Pular para o conteúdo
BetaDocumentação em validação contínua. Comportamento descrito pode divergir do servidor — abra um chamado no app se algo não bater.

Erros

Códigos HTTP, formato JSON consistente, lista de códigos comuns e como tratar com retry, fallback e logging.


A API retorna erros em um formato JSON consistente, com um código estável que você pode usar em código de retry e fallback — independente da mensagem (que pode mudar entre versões).

Formato

Todo erro vem assim:

Text
{
  "code": "validation_error",
  "message": "Campo 'fullName' é obrigatório.",
  "details": {
    "field": "fullName"
  }
}
  • code — string estável. Nunca muda dentro de uma versão major.
  • message — humano-legível, em PT-BR. Pode mudar.
  • details — campos extras específicos do erro (opcional).
Informação
Sem wrapper

O payload de erro é flat — não há um campo error ao redor. Sempre faça body.code, não body.error.code.

Códigos HTTP por categoria

StatusSignificado
200Sucesso (GET, PATCH).
201Criado com sucesso (POST).
204Sucesso sem conteúdo (DELETE).
400Requisição mal formada (JSON inválido, idempotency key).
401Não autenticado (token ausente, inválido, revogado).
403Autenticado mas sem permissão (scope insuficiente, plano).
404Recurso não existe ou não pertence ao seu workspace.
409Conflito (ex.: e-mail duplicado em cadastro de pessoa).
422Validação semântica (regra de negócio violada).
429Rate limit excedido. Veja o guia.
500Erro interno. Reportável.

Códigos de erro

A v1 expõe os seguintes códigos estáveis:

CodeStatusQuando acontece
unauthorized401Token ausente, malformado ou revogado.
forbidden403Token válido mas sem permissão pra essa operação.
plan_limit403Quota do plano atual atingida (ex.: número de pessoas).
not_found404Recurso não existe ou está em outro workspace.
conflict409Conflito de unicidade (ex.: e-mail já cadastrado).
invalid_idempotency_key400Idempotency-key reutilizada com payload diferente.
validation_error422Payload mal formado ou regra de negócio violada.
request_error4xxErro genérico de requisição (4xx sem código mais específico).
internal_error500Algo deu errado no servidor. Tente de novo.

Padrão de retry recomendado

Text
async function callApi(path: string, init: RequestInit, attempt = 1) {
  const res = await fetch(`https://api.mixycrm.com.br/api/v1${path}`, init);

  // Sucesso: retorna direto.
  if (res.ok) return res.json();

  // 429: respeita Retry-After.
  if (res.status === 429) {
    const retryAfter = Number(res.headers.get("retry-after") ?? 5);
    await new Promise((r) => setTimeout(r, retryAfter * 1000));
    return callApi(path, init, attempt + 1);
  }

  // 5xx: backoff exponencial até 5 tentativas.
  if (res.status >= 500 && attempt < 5) {
    const delay = Math.min(2 ** attempt * 1000, 30_000);
    await new Promise((r) => setTimeout(r, delay));
    return callApi(path, init, attempt + 1);
  }

  // 4xx (não 429): erro do cliente, não retentar.
  const body = await res.json();
  throw new ApiError(body); // body = { code, message, details? }
}
Atenção
Não retentar 4xx

Erros 400, 401, 403, 404, 409, 422 são deterministicamente do cliente. Retentar não muda o resultado e ainda gasta seu rate limit. Logue e investigue.

Logging recomendado

Em produção, logue estes campos pra facilitar debug:

  • code (chave de busca rápida).
  • message.
  • Endpoint chamado, método, status code.
  • Body da request (sem PII se possível) e do erro.
  • Headers de rate limit (x-ratelimit-*) — útil pra entender se você estava perto do limite.

Reportar um bug

Pra reportar comportamento inesperado da API, abra um chamado no app (ícone de suporte no canto inferior direito) com:

  1. Endpoint chamado e método.
  2. Body enviado (anonimize PII).
  3. Resposta recebida (code + message).
  4. Timestamp aproximado da chamada — facilita correlacionar com logs internos.
  5. O que você esperava acontecer.

A gente usa cookies pra entender o que funciona e o que não funciona aqui. Sem terceiros — dado fica conosco. Política.