Pular para o conteúdo principal

Erros

Todos os erros da API Veridia seguem um shape consistente. Esta pagina e a referencia canonica para cada codigo de erro que voce pode ver.

Shape de resposta de erro

Cada resposta de erro inclui:

{
"error": "invalid_body",
"message": "Request body failed validation",
"requestId": "9f511d92ac11236d-SJC",
"detail": {
"fieldErrors": {
"country": ["expected 2 characters"]
}
}
}
CampoTipoDescricao
errorstringCodigo machine-readable — switch neste no seu codigo
messagestringResumo human-readable, principalmente para logs
requestIdstringID unico desta request — inclua em tickets de suporte
detailobjectOpcional. Contexto extra (erros de campo, motivo de mismatch de keys, etc.)

O mesmo requestId tambem e retornado no response header X-Request-Id — util quando o parsing JSON falha.

Catalogo de erros

invalid_body400 Bad Request

O body da request falhou validacao do schema Zod. Verifique detail.fieldErrors para especificos.

Causas comuns:

  • Campo obrigatorio faltando
  • Tipo errado (ex: string onde se esperava number)
  • String muito longa (ex: userRef > 128 chars)
  • Valor enum invalido (ex: documentType: "id" em vez de "dni")
  • verificationId nao bate ^vf_[A-Za-z0-9]{16,24}$

Em /submit especificamente, detail.reason pode ser:

ReasonSignificado
doc_front_key_mismatchO keys.docFront nao bate com o que /init retornou
selfie_key_mismatchO keys.selfie nao bate com o que /init retornou
doc_back_key_mismatchO keys.docBack nao bate com o que /init retornou
doc_front_not_uploadedO objeto R2 da frente nao existe — o cliente nunca fez upload
selfie_not_uploadedO objeto R2 da selfie nao existe
doc_front_disappearedO objeto R2 existia durante o HEAD mas sumiu antes do OCR (extremamente raro)

Recovery: Conserte a request e tente de novo. Estes sao erros do cliente.

unauthorized401 Unauthorized

O header Authorization esta faltando, malformado, ou nao usa o scheme Bearer.

Recovery: Adicione um header Authorization: Bearer <key> valido.

invalid_key401 Unauthorized

O bearer token nao corresponde a uma key valida. Nunca existiu, foi revogada, ou expirou.

Recovery: Gere uma nova key no dashboard. Verifique que voce esta usando a key correta para o environment correto.

origin_not_allowed403 Forbidden

A publishable key foi usada de um dominio que nao esta na lista de allowed origins.

Recovery: Adicione seu dominio a lista de allowed origins no dashboard. Para desenvolvimento local, adicione http://localhost:PORT.

wrong_environment403 Forbidden

Uma test key (qv_pub_test_* / qv_sec_test_*) foi usada com um endpoint live, ou vice-versa.

Recovery: Use o environment correspondente. Test keys para teste, live keys para producao.

insufficient_credits403 Forbidden

O tenant tem 0 creditos. Novas verificacoes nao podem iniciar.

Recovery: Top up creditos no dashboard, ou contate o suporte se voce esta num plano custom.

verification_not_found404 Not Found

O verificationId nao existe, nao pertence a este tenant, ou o intent expirou (>1 hora apos /init).

Recovery:

  • Verifique que o ID nao tenha typos
  • Garanta que voce esta usando a mesma API key (ou outra do mesmo tenant)
  • Se passou mais de 1 hora desde /init, reinicie o fluxo

not_found404 Not Found

A rota nao existe.

Recovery: Verifique a URL. Typos comuns: /v1/verifications em vez de /v1/verify/:id.

rate_limited429 Too Many Requests

Atingiu o rate limit por tenant. O response header Retry-After diz quanto esperar (em segundos).

EndpointLimite padrao
/v1/verify/init60 / minuto
/v1/verify/submit30 / minuto
/v1/verify/:id600 / minuto

Recovery:

  • Espere a duracao em Retry-After, depois tente de novo
  • Adicione throttling do seu lado
  • Contate o suporte para elevar limites por-tenant

internal500 Internal Server Error

Algo quebrou do lado da Veridia. Raro.

Recovery:

  • Tente de novo com backoff exponencial (o issue pode ser transitorio)
  • Se persistir, abra um ticket de suporte com o requestId da resposta

Gerenciando erros bem

JavaScript / Node.js

async function callVeridia(url, options) {
const response = await fetch(url, options);

if (response.ok) {
return response.json();
}

const error = await response.json();

// Switch no error code, nao no HTTP status
switch (error.error) {
case 'invalid_body':
console.error('Validation falhou:', error.detail?.fieldErrors);
throw new ValidationError(error);

case 'rate_limited':
const retryAfter = response.headers.get('Retry-After') || 1;
await new Promise(r => setTimeout(r, retryAfter * 1000));
return callVeridia(url, options); // tenta de novo uma vez

case 'insufficient_credits':
// Notifica ops, fallback para revisao manual
await notifyCreditsExhausted();
throw new BusinessError(error);

case 'verification_not_found':
// Erro logico — reinicia o fluxo
throw new NotFoundError(error);

case 'internal':
// Issue da Veridia — logue e alerte
logger.error('Veridia internal error', {
requestId: error.requestId,
url,
});
throw new ExternalServiceError(error);

default:
throw new Error(`Veridia erro nao gerenciado: ${error.error}`);
}
}

Python

import time
import requests

def call_veridia(url, **kwargs):
response = requests.request(**kwargs, url=url)

if response.ok:
return response.json()

error = response.json()

if error["error"] == "invalid_body":
raise ValidationError(error)

if error["error"] == "rate_limited":
retry_after = int(response.headers.get("Retry-After", 1))
time.sleep(retry_after)
return call_veridia(url, **kwargs)

if error["error"] == "insufficient_credits":
notify_credits_exhausted()
raise BusinessError(error)

if error["error"] == "verification_not_found":
raise NotFoundError(error)

if error["error"] == "internal":
logger.error(
"Veridia internal error",
extra={"request_id": error["requestId"], "url": url},
)
raise ExternalServiceError(error)

raise Exception(f"Veridia erro nao gerenciado: {error['error']}")

Best practices

  • Switch em error.error, nao em HTTP status. Os codigos HTTP podem mudar por motivos nao-breaking; o codigo error string e parte do nosso contrato publico de API
  • Sempre logue o requestId. E o caminho mais rapido para diagnostico se voce abrir um ticket de suporte
  • Tente de novo com backoff para internal e rate_limited. Nao tente de novo invalid_body, unauthorized, verification_not_found, ou insufficient_credits
  • Surface erros de validation aos seus developers, nao aos usuarios finais. Usuarios finais devem ver "Algo deu errado, por favor tente de novo"
  • Monitore insufficient_credits como business alert — significa que voce esta perdendo faturamento

Proximos passos