Códigos de erro

Erros das chamadas a /v1/* (proxy Tokia → modelos IA) seguem o formato OpenAI-compatible:

json
{
  "error": {
    "type": "rate_limit_exceeded",
    "message": "Muitas requisições simultâneas. Aguarde alguns segundos e tente novamente.",
    "code": "rate_limit_exceeded"
  }
}

Erros das chamadas REST (/api-keys, /topups, /payment-methods, /me/profile etc.) usam { "error": "<código>", "details"?: string }. Códigos HTTP seguem convenção REST.

Erros do proxy /v1/*

Tokia normaliza todos os erros dos modelos IA upstream em 6 categorias. A mensagem é em pt-BR e sempre acionável — nunca vaza nome do provedor ou detalhe interno.

HTTPtype / codeQuando aconteceO que fazer
400invalid_requestParâmetro inválido (model inexistente, max_tokens absurdo, messages malformado).Verificar payload contra /docs/api/chat.
401authentication_failedAPI key Tokia inválida, revogada, expirada, ou sem acesso ao modelo solicitado.Recriar key em /dashboard/keys incluindo o modelo desejado.
404model_not_foundID do modelo não existe no catálogo Tokia.Ver lista atual em /docs/models.
429rate_limit_exceededThrottling Tokia (default 100 req/min/IP) ou limite do modelo.Backoff exponencial — esperar 1-2s e retentar. Lê header retry-after.
429api_key_rate_limitedSprint 177 — limite por API key (default 120 req/min) atingido.Crie 2ª API key em /dashboard/keys pra paralelizar carga, ou backoff lendo x-ratelimit-reset.
403ip_blocked_by_allowlistSprint 111 — IP do cliente não está na allowlist desta key.Adicionar IP em /dashboard/keys → editar key → IP allowlist.
502upstream_errorFalha temporária na infraestrutura Tokia/upstream.Retentar em alguns segundos. Se persistir, contatar suporte.
503service_unavailableModelo temporariamente indisponível (manutenção, recarga em curso).Retentar em alguns minutos. Tokia já foi notificada automaticamente.

Erros REST (dashboard / billing / keys)

400 Bad Request

CódigoSignificado
cpf_requiredProfile sem CPF/CNPJ. Cliente precisa preencher em PUT /me/profile antes de fazer top-up ou cadastrar cartão.
invalid_cpf_cnpj_formatFormato inválido (não tem 11 ou 14 dígitos).
invalid_cpf_cnpj_checksumDígitos verificadores não batem.
amount must be number between 10 and 5000Valor de top-up fora do intervalo.
name must be 3-50 charsNome de API key inválido.
no_valid_modelsLista model_ids[] passada não tem nenhum ID válido do catálogo.
card_rejectedAsaas rejeitou o cartão (recusado, expirado, dados incorretos).
missing_card_or_holder_infoPOST /payment-methods sem campos obrigatórios.

401 Unauthorized

CódigoSignificado
(sem corpo)Token Bearer ausente ou inválido. Verifique header Authorization.
invalid_tokenWebhook Asaas com token errado (não afeta clientes).
invalid_signatureWebhook Logto com HMAC inválido (não afeta clientes).

403 Forbidden

CódigoSignificado
forbiddenEndpoint admin sem permissão. Cliente normal vê 403; admins precisam estar na allowlist.
key_model_access_deniedAPI key não tem o modelo solicitado em sua lista permitida. Crie nova key incluindo o modelo.

404 Not Found

CódigoSignificado
key_not_foundDELETE /api-keys/:id com id que não pertence ao user.
payment_method_not_foundDELETE /payment-methods/:id com id inválido.
profile_not_foundGET /me/profile antes do webhook Logto criar o profile.

500 Internal Server Error

Erro inesperado Tokia. Reporte pra contato@usetokia.com com timestamp + request_id (do header x-request-id da response).

Headers úteis

Toda resposta de /v1/* retorna headers extras pra debug e controle de fluxo:

HeaderQuando aparecePra que serve
x-tokia-request-idToda respostaSprint 164 — UUID único da chamada. Inclua em suporte. Cliente pode enviar o próprio header pra correlação ponta-a-ponta.
x-ratelimit-limitToda resposta (Sprint 177)Quantos requests por minuto a key pode fazer.
x-ratelimit-remainingToda resposta (Sprint 177)Quantos requests ainda cabem na janela atual.
x-ratelimit-resetToda resposta (Sprint 177)Unix timestamp (segundos) quando o contador zera.
retry-afterSó em 429Segundos até poder retentar.

Padrão de retry recomendado

ts
// SDK Node oficial já faz isso (sdks/node v0.3+).
// Implementação manual em qualquer cliente HTTP:
async function retryableFetch(url: string, opts: RequestInit, max = 5) {
  for (let attempt = 0; attempt < max; attempt++) {
    const r = await fetch(url, opts);
    // Retentar em 429 e 5xx
    if (r.status === 429 || r.status >= 500) {
      const retryAfter = Number(r.headers.get("retry-after")) || 1;
      const wait = retryAfter * 1000 * Math.pow(2, attempt);
      await new Promise((ok) => setTimeout(ok, Math.min(wait, 30_000)));
      continue;
    }
    return r;
  }
  throw new Error("Tokia: max retries exceeded");
}