{
"error": {
"code": "ERR_API_FORBIDDEN_SCOPE",
"message": "O token não tem permissão de POST no módulo \"contacts\"."
}
}
string
obrigatório
Identificador fixo do erro. Use este código para decidir o que a sua integração faz. O texto da
mensagem pode mudar com o tempo, então não dependa dele.
string
obrigatório
Descrição em português, pensada para aparecer em log e em tela de suporte.
any
Informações extras, quando existem, como a lista de campos inválidos. A maioria dos erros não
traz este campo.
Trate qualquer resposta fora da faixa
2xx como erro antes de ler data. Quando a chamada
falha, data não existe, e ler resposta.data.id gera um TypeError que esconde a causa real.Códigos de autenticação e permissão
| Código | Status | O que fazer |
|---|---|---|
ERR_API_UNAUTHORIZED | 401 | Token ausente, inválido, revogado ou expirado, ou IP não autorizado. A resposta é a mesma em todos esses casos. Confira o token no painel. |
ERR_API_FORBIDDEN_SCOPE | 403 | O token não tem permissão para esse método nesse módulo. A mensagem diz qual é. Ajuste as permissões do token. |
ERR_API_NOT_ENABLED | 403 | O plano da empresa não inclui a API pública. |
ERR_NO_PERMISSION | 403 | A operação exige um nível de acesso que o token não tem. |
ERR_SELF_SERVICE_DISABLED | 403 | Recurso disponível apenas em instalações self-service, como o convite de usuários. |
Quando um
401 começa a aparecer de repente, a causa mais comum é o token ter expirado ou o IP
de saída do seu servidor ter mudado. Confira a data de validade do token antes de investigar a
rede.Códigos de requisição
| Código | Status | O que fazer |
|---|---|---|
ERR_API_VALIDATION | 400 ou 422 | Falta um campo obrigatório ou algum valor não é aceito. A mensagem diz qual é o problema. |
ERR_API_INVALID_JSON | 400 | O corpo não é um JSON válido. Confira aspas, vírgulas e o cabeçalho Content-Type: application/json. |
ERR_API_INVALID_PARAMETER | 400 | Algum parâmetro tem formato inválido, como texto onde se espera número ou uma data que não existe. |
ERR_API_NOT_FOUND | 404 | O registro não existe, ou o id informado não é um número. |
ERR_API_ROUTE_NOT_FOUND | 404 | O método ou o caminho não existe. Confira o verbo e se a URL base inclui /api/v1. |
ERR_API_CONFLICT | 409 | Já existe um registro com esses dados. |
ERR_API_INVALID_REFERENCE | 422 | Um dos ids enviados no corpo não existe. |
ERR_API_PAYLOAD_TOO_LARGE | 413 | O corpo passou do tamanho permitido. |
ERR_API_UPLOAD | 413 ou 422 | O arquivo passou do tamanho permitido ou o envio não foi aceito. |
ERR_API_RATE_LIMIT | 429 | A empresa atingiu o limite de requisições por minuto. Espere o tempo indicado em Retry-After. |
ERR_API_IDEMPOTENCY_KEY_INVALID | 400 | Idempotency-Key com mais de 200 caracteres. |
ERR_API_IDEMPOTENCY_KEY_REUSED | 409 | A mesma chave já foi usada com outro corpo. |
ERR_API_IDEMPOTENCY_IN_PROGRESS | 409 | Outra tentativa com essa chave ainda está em andamento. |
ERR_API_INTERNAL | 500 | Falha do nosso lado. Vale repetir depois de alguns segundos. Se continuar, fale com o suporte informando o método e o caminho. |
Um id de outra empresa responde
404, exatamente como um id que não existe. É proposital: a API
não confirma que um registro existe fora da sua conta.Códigos de regra de negócio
Estes códigos aparecem quando a requisição está correta, mas a situação atual do recurso não permite a operação.Mensagens
Mensagens
| Código | Status | Significado |
|---|---|---|
ERR_API_BODY_REQUIRED | 400 | Mensagem do tipo text sem o campo body. |
ERR_API_TEMPLATE_REQUIRED | 400 | Mensagem do tipo template sem o campo template. Também aparece ao agendar envio em canal de WhatsApp oficial sem template. |
ERR_API_INTERACTIVE_REQUIRED | 400 | Mensagem do tipo interactive sem o campo interactive. |
ERR_API_MEDIA_REQUIRED | 400 | Mensagem do tipo media sem arquivo. |
ERR_API_CHANNEL_NOT_FOUND | 404 | O canal não existe nesta empresa. |
ERR_API_TICKET_NOT_FOUND | 404 | O atendimento informado em ticketId não existe nesta empresa. |
ERR_API_JOB_NOT_FOUND | 404 | O jobId não existe ou pertence a outra empresa. |
ERR_API_TEMPLATE_MEDIA_NOT_ALLOWED | 400 | O template informado não aceita mídia no cabeçalho. |
ERR_API_CONTACT_NOT_IDENTIFIED | 400 | Nenhum de ticketId, contactId ou number, ou só number num canal sem telefone. |
ERR_API_CONTACT_NOT_FOUND | 404 | O contactId não existe nesta empresa. |
ERR_API_CONTACT_UNREACHABLE | 422 | O contato não pode receber por este canal: sem conversa anterior nele (canais sem telefone; no Webchat, sem sessão do visitante neste webchat) ou sem telefone (canais de telefone). |
ERR_API_INTERACTIVE_INVALID | 422 | Webchat: o interactive está fora do formato ou dos limites do WhatsApp, ou é de um tipo que não existe no webchat. A message traz o campo e o motivo. |
ERR_API_NO_WHATSAPP_CREDITS | 402 | Canal WhatsApp Business com cobrança ativada e a empresa sem crédito. A mensagem não entra na fila. |
ERR_API_ACTIVE_CONTACTS_LIMIT_REACHED | 402 | A empresa atingiu o limite de contatos ativos do mês e o destinatário ainda não trocou mensagem com ela neste mês. Contatos que já contaram no mês seguem recebendo; a contagem zera no dia 1º. Não vale para canais web_whatsapp. A mensagem não entra na fila. |
Canais
Canais
| Código | Status | Significado |
|---|---|---|
ERR_API_CHANNEL_NOT_FOUND | 404 | O canal não existe nesta empresa. |
Webchat
Webchat
| Código | Status | Significado |
|---|---|---|
ERR_WEBCHAT_NOT_FOUND | 404 | O slug não é de um webchat ativo desta empresa. |
ERR_WEBCHAT_SESSION_NOT_FOUND | 404 | A sessão não existe neste webchat. |
ERR_WEBCHAT_SESSION_CLOSED | 410 | A sessão foi encerrada. Abra outra (com externalId, a mesma é reaberta). |
ERR_WEBCHAT_SESSION_BLOCKED | 403 | A sessão está bloqueada por excesso de mensagens (1 hora). |
ERR_WEBCHAT_VISITOR_DATA_REQUIRED | 422 | Faltam dados iniciais obrigatórios do visitante. A message traz os campos (ex.: name,phone). |
ERR_WEBCHAT_MESSAGE_EMPTY | 422 | Mensagem sem texto e sem arquivo. |
ERR_WEBCHAT_MESSAGE_TOO_LONG | 422 | Texto acima de 4.096 caracteres. |
ERR_WEBCHAT_MEDIA_TOO_LARGE | 413 | Arquivo acima de 10 MB. |
ERR_WEBCHAT_MEDIA_INVALID_TYPE | 422 | Tipo de arquivo não aceito (o tipo é lido do conteúdo, não do nome). |
ERR_WEBCHAT_UPLOAD_LIMIT | 429 | Volume de arquivos do webchat na última hora esgotado. |
ERR_WEBCHAT_INTERACTIVE_REPLY_INVALID | 422 | interactiveReply com opção que não está na mensagem, ou mensagem que o visitante não vê. |
ERR_WEBCHAT_LOCATION_INVALID | 422 | location fora da faixa (latitude de -90 a 90, longitude de -180 a 180). |
Atendimentos
Atendimentos
| Código | Status | Significado |
|---|---|---|
ERR_NO_TICKET_FOUND | 404 | O atendimento não existe nesta empresa. |
ERR_API_TRANSFER_TARGET_REQUIRED | 400 | Para transferir, informe a fila ou o usuário de destino. |
ERR_API_TICKET_CLOSED | 409 | automation: true em conversa encerrada que não tem mais o protocolo em aberto. |
ERR_API_TICKET_IN_NPS | 409 | automation em conversa que está na pesquisa de satisfação. |
ERR_API_TICKET_IN_SERVICE | 409 | automation: true em conversa com atendente responsável. Tire o atendente antes, com POST /tickets/{id}/transfer e userId: null. |
Tags
Tags
| Código | Status | Significado |
|---|---|---|
ERR_NO_TAG_FOUND | 404 | A tag não existe ou foi apagada. |
Qualificações
Qualificações
| Código | Status | Significado |
|---|---|---|
ERR_API_QUEUE_NOT_FOUND | 422 | Alguma fila de queues não existe nesta empresa. |
Campanhas
Campanhas
| Código | Status | Significado |
|---|---|---|
ERR_NO_CAMPAIGN_FOUND | 404 | A campanha não existe nesta empresa. |
CRM
CRM
| Código | Status | Significado |
|---|---|---|
ERR_NO_BOARD_FOUND | 404 | O painel não existe nesta empresa. |
ERR_NO_BOARD_LIST_FOUND | 404 | A etapa não existe no painel, ou a etapa de destino é de outro painel. |
ERR_NO_CARD_FOUND | 404 | O card não existe nesta empresa. |
ERR_NO_CONTACT_FOUND | 404 | O contato não existe nesta empresa. |
Relatórios
Relatórios
| Código | Status | Significado |
|---|---|---|
ERR_COMPANY_OR_DATE_NOT_DEFINED | 400 | Faltou date_start ou date_finish. |
ERR_API_VALIDATION | 422 | A data não está no formato AAAA-MM-DD ou AAAA-MM-DD HH:mm:ss. |
Agendamentos
Agendamentos
| Código | Status | Significado |
|---|---|---|
ERR_API_SCHEDULE_ALREADY_SENT | 409 | O agendamento já foi enviado e não pode ser alterado. |
ERR_API_SCHEDULE_CANCELED | 409 | O agendamento foi cancelado. |
ERR_API_SCHEDULE_NOT_EDITABLE | 409 | A situação atual do agendamento não permite edição. |
Usuários
Usuários
| Código | Status | Significado |
|---|---|---|
ERR_API_USER_ID_REQUIRED | 400 | A operação exige o id do usuário. |
ERR_API_USER_NO_WRITABLE_FIELDS | 400 | Nenhum campo alterável foi enviado. E-mail e senha pertencem à conta global do usuário e não podem ser editados pela API. |
ERR_API_INVITE_ALREADY_ACCEPTED | 409 | O convite já foi aceito e a pessoa já é membro da empresa. Para tirar o acesso dela, use PUT /users/{id}/active. |
ERR_API_PROFILE_NOT_FOUND | 422 | O profileId não é de um perfil desta empresa. Consulte os perfis em GET /profiles. |
Como tratar cada tipo de erro
Cada faixa de status pede uma reação diferente. Um400 volta igual se você repetir a chamada sem
mudar nada. Já um 429 deve ser repetido depois da espera indicada, senão a operação se perde.
async function tratar(res) {
if (res.ok) return res.status === 204 ? null : (await res.json()).data;
const { error } = await res.json().catch(() => ({ error: {} }));
switch (res.status) {
case 401:
// Não repita: o token não vai melhorar sozinho. Alerte quem opera.
throw new ErroDeCredencial(error.code, error.message);
case 403:
case 404:
case 409:
case 422:
// Definitivos: repetir dá o mesmo resultado. Corrija a chamada.
throw new ErroDeRequisicao(error.code, error.message, error.details);
case 429:
throw new ErroTemporario(Number(res.headers.get('Retry-After') ?? 60));
default:
// 5xx: falha do servidor. Vale retry com espera crescente.
throw new ErroTemporario(5);
}
}
def tratar(res):
if res.ok:
return None if res.status_code == 204 else res.json().get("data")
erro = res.json().get("error", {}) if res.content else {}
if res.status_code == 401:
raise ErroDeCredencial(erro.get("code"), erro.get("message"))
if res.status_code in (403, 404, 409, 422):
raise ErroDeRequisicao(erro.get("code"), erro.get("message"), erro.get("details"))
if res.status_code == 429:
raise ErroTemporario(int(res.headers.get("Retry-After", 60)))
raise ErroTemporario(5)
Registre sempre o
error.code no seu log, junto com o método e o caminho chamados. Com essas
informações, o suporte consegue localizar a requisição, e tudo cabe em uma linha.
