Todos os erros seguem RFC 7807 (Problem Details). Content-Type: application/problem+json.
Estrutura padrao
"title": "Chip nao encontrado",
"code": "chip-not-found",
"detail": "Chip 01HZTQ... nao existe.",
| Campo | Notas |
|---|
type | URI do tipo do erro. Hoje sempre about:blank (campo mantido pra compat futura) |
title | resumo legivel em PT-BR |
status | HTTP status code |
code | identificador unico estavel (use isso pra logica do consumer) |
detail | mensagem mais especifica |
extra | objeto com campos contextuais (chip_id, app_id, etc) |
Use code pra branching no seu codigo, nao title ou detail — sao mensagens humanas e podem mudar.
Codigos por dominio
Chips
| Code | HTTP | Quando |
|---|
chip-not-found | 404 | ID nao existe |
chip-not-connected | 409 | tentou enviar mensagem por chip nao-connected |
chip-qr-unavailable | 409 | tentou pegar QR de chip nao-pairing (ou ainda nao gerou) |
Apps
| Code | HTTP | Quando |
|---|
app-not-found | 404 | ID nao existe |
app-chip-access-forbidden | 403 | app nao tem can_send/can_receive no chip |
unauthorized | 401 | api_key invalida/expirada |
Mensagens
| Code | HTTP | Quando |
|---|
message-not-found | 404 | ID nao existe ou app nao tem acesso |
idempotency-conflict | 409 | idempotency_key reutilizada com payload diferente |
unsupported-message-type | 422 | type nao reconhecido |
daily-limit-exceeded | 429 | chip atingiu daily_message_limit |
Midia
| Code | HTTP | Quando |
|---|
media-not-found | 404 | id nao existe OU app sem acesso |
Transcricao
| Code | HTTP | Quando |
|---|
transcription-disabled | 422 | TRANSCRIPTION_PROVIDER=disabled no hub |
Push devices
| Code | HTTP | Quando |
|---|
push-device-not-found | 404 | ID nao existe |
Contatos
| Code | HTTP | Quando |
|---|
contact-not-found | 404 | JID nao existe pra esse chip |
chip-offline | 503 | foto requisitada mas chip nao esta connected |
Webhook deliveries
| Code | HTTP | Quando |
|---|
webhook-delivery-not-found | 404 | ID nao existe |
Validacao
| Code | HTTP | Quando |
|---|
validation | 400 | body/query falhou validacao Zod. extra.issues traz array de problemas |
Exemplo:
"title": "Validacao falhou",
"detail": "campos invalidos no body",
{ "path": ["to"], "message": "Required" },
{ "path": ["content", "text"], "message": "String must contain at least 1 character(s)" }
Erros do servidor (5xx)
Hub raramente retorna 5xx — quando retorna, indica bug ou infra fora. Recomendado retry com backoff do seu lado.
| Code | HTTP | Tipo |
|---|
internal-error | 500 | erro nao tratado |
service-unavailable | 503 | dependencia (Postgres/Redis/MinIO) caiu |
/health/ready falha junto. Monitore.
Padrao de tratamento
async function callHub(method, path, body) {
const res = await fetch(`${HUB}${path}`, {
headers: { 'Authorization': `Bearer ${KEY}`, 'Content-Type': 'application/json' },
body: body ? JSON.stringify(body) : undefined,
const problem = await res.json().catch(() => ({}))
const err = new Error(problem.detail || problem.title || `HTTP ${res.status}`)
err.extra = problem.extra
if (res.status === 204) return null
const msg = await callHub('POST', '/v1/messages', { ... })
if (e.code === 'idempotency-conflict') {
// mesma key foi usada antes — pega a mensagem original
const original = await callHub('GET', `/v1/messages/${e.extra.existing_message_id}`)
} else if (e.code === 'chip-not-connected') {
// re-tenta apos reconnect ou avisa o operador