Skip to main content

Formato de erro

Todos os erros retornam um objeto JSON no seguinte formato:
{
  "error": {
    "type": "validation_error",
    "message": "Campo 'name' é obrigatório.",
    "code": "MISSING_REQUIRED_FIELD",
    "details": [
      {
        "field": "name",
        "message": "Campo obrigatório"
      }
    ]
  },
  "meta": {
    "request_id": "req_01jx8kz3m4n5p6q7r8s9t0u1v"
  }
}
CampoTipoDescrição
error.typestringCategoria do erro (ex: validation_error)
error.messagestringMensagem legível para humanos
error.codestringCódigo de máquina para tratamento programático
error.detailsarray?Detalhes adicionais (ex: campos inválidos)
meta.request_idstringID único da requisição para suporte

Códigos HTTP

StatusTipoQuando ocorre
200SucessoLeitura bem-sucedida
201CriadoRecurso criado com sucesso
204Sem conteúdoExclusão bem-sucedida
400validation_errorCorpo ou parâmetros inválidos
401unauthorizedAPI Key ausente ou inválida
403forbiddenEscopo insuficiente ou restrição de plano
404not_foundRecurso não encontrado
409conflictConflito de dados (ex: duplicata)
422unprocessable_entityDados válidos mas impossíveis de processar
429rate_limit_exceededLimite de requisições atingido
500internal_errorErro interno do servidor

Referência de códigos de erro

Autenticação

CódigoStatusDescrição
MISSING_API_KEY401Header Authorization ausente
INVALID_API_KEY_FORMAT401Chave não começa com sk_live_
INVALID_API_KEY401Chave inválida, expirada ou revogada
INSUFFICIENT_SCOPE403Escopo necessário não concedido à chave
PLAN_RESTRICTION403Recurso não disponível no plano atual

Validação

CódigoStatusDescrição
INVALID_ID400ID de recurso com formato inválido
MISSING_REQUIRED_FIELD400Campo obrigatório ausente
INVALID_TYPE400Valor de enum inválido
INVALID_PRIORITY400Prioridade inválida
INVALID_CHANNEL400Canal não suportado
CHANNEL_NOT_SUPPORTED400Canal não disponível na API pública
MISSING_CONTENT400Conteúdo da mensagem ausente
MISSING_MEDIA_URL400URL de mídia ausente para mensagens não-texto
MISSING_TAG400Campo tag ausente

Recursos

CódigoStatusDescrição
NOT_FOUND404Recurso não encontrado na organização
PIPELINE_NOT_FOUND404Funil de venda não encontrado
STAGE_NOT_FOUND404Etapa não encontrada no funil de venda
CONTACT_NOT_FOUND404Contato não encontrado
DUPLICATE_CONTACT409Já existe contato com esse telefone/email
DUPLICATE409Registro duplicado

Processamento

CódigoStatusDescrição
NO_WHATSAPP_JID422Contato sem WhatsApp configurado
NO_WHATSAPP_INSTANCE422Nenhuma instância WhatsApp conectada
NO_MESSENGER_PSID422Contato sem PSID do Messenger
NO_MESSENGER_PAGE422Nenhuma página Messenger conectada
NO_STAGES422Funil de venda sem etapas
ALREADY_OPEN422Negócio já está aberto
MESSENGER_SEND_ERROR500Erro ao enviar via Messenger API

Rate Limiting

CódigoStatusDescrição
RATE_LIMIT_EXCEEDED429Limite por minuto atingido
RATE_LIMIT_BURST_EXCEEDED429Limite de burst (10s) atingido
RATE_LIMIT_DAILY_EXCEEDED429Limite diário atingido
WHATSAPP_INSTANCE_RATE_LIMIT42930 msg/min por instância WhatsApp
MESSENGER_PAGE_RATE_LIMIT42930 msg/min por página Messenger

Tratando erros em código

async function apiRequest(url, options = {}) {
  const response = await fetch(`https://api.socialsell.ai/v1${url}`, {
    ...options,
    headers: {
      'Authorization': 'Bearer sk_live_...',
      'Content-Type': 'application/json',
      ...options.headers
    }
  });

  const data = await response.json();

  if (!response.ok) {
    const { error } = data;
    
    switch (error.code) {
      case 'RATE_LIMIT_EXCEEDED':
        const retryAfter = parseInt(response.headers.get('Retry-After') || '60');
        // aguardar e tentar novamente
        await new Promise(r => setTimeout(r, retryAfter * 1000));
        return apiRequest(url, options);
        
      case 'DUPLICATE_CONTACT':
        // contato já existe — usar o ID retornado
        return { existing: error.existing_contact };
        
      default:
        throw new Error(`[${error.code}] ${error.message}`);
    }
  }

  return data;
}

Header de Rate Limiting

Quando bem-sucedida, cada resposta inclui headers informativos:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-RateLimit-Reset: 2026-06-10T15:30:00.000Z
X-Request-Id: req_01jx8kz3m4n5p6q7r8s9t0u1v
Quando o limite é atingido, a resposta inclui:
Retry-After: 15
Aguarde o número de segundos indicado antes de tentar novamente.