Pular para o conteúdo
No ar em produção, em modo shadow: o FingerTrackID recomenda, o seu sistema decide.Status →

Catálogo de erros (Problems)

Todo erro chega como application/problem+json (RFC 9457), com type, title, status, retryable e, quando presente, correlation_id.

Baixe, para validação, o schema do Problem e o contrato OpenAPI v1 exatos.

O type é um URI completo sob https://fingertrackid.dev/problems/, por exemplo https://fingertrackid.dev/problems/rate-limited.

  • É um identificador estável. Não o busque em tempo de execução e não trate como problema uma consulta a ele que falhe. Compare a string type completa.
  • Esta página é a documentação de todos os tipos. Cada um tem sua própria seção abaixo, em https://docs.fingertrackid.com/api/errors/#<suffix> (por exemplo #rate-limited), e abrir um URI type no navegador redireciona para essa seção.
  • Baseie seu código em type e status. O title é texto legível por humanos; ele só é fixo para authentication-failed (Autenticação falhou, em português, como o contrato define) e assessment-result-expired (Assessment result expired). Não crie condicionais com base em title.
  • O contrato permite errors[] (com pointer e code) apenas em validation-failed, como campo opcional. Não conte com ele para encontrar o campo errado.
Sufixo do type HTTP retryable Rotas
validation-failed 400 false Avaliação, feedback
event-context-invalid 400 false Avaliação
occurred-at-out-of-window 400 false Avaliação
authentication-failed 401 false Avaliação, feedback
timestamp-out-of-window 401 true Avaliação, feedback
request-replayed 401 true Avaliação, feedback
forbidden 403 false Avaliação, feedback
not-found 404 false Feedback
idempotency-conflict 409 false Avaliação, feedback
binding-conflict 409 false Avaliação, feedback
assessment-result-expired 410 false Avaliação
payload-too-large 413 false Avaliação, feedback
unsupported-media-type 415 false Avaliação, feedback
rate-limited 429 true Avaliação, feedback
internal 500 false Avaliação, feedback
assessment-unavailable 503 true Avaliação, feedback

As rotas de feedback têm seu próprio catálogo fechado de Problems no OpenAPI de feedback, com títulos em inglês. O endpoint de coleta do Web SDK usa mais alguns tipos, listados em vistos no navegador, e os tipos que a API não envia vêm listados depois deles.

400, não admite nova tentativa. A requisição não corresponde ao schema, ou a rota é uma variação de /v1/assessments (query string, barra final, método diferente de POST), ou a requisição traz Expect/Trailer ou um cabeçalho de framing duplicado. Corrija a requisição conforme o schema.

Em uma requisição v1.1, isso inclui uma etiqueta (tag) fora da gramática (maiúscula, hífen, espaço, mais de 64 caracteres, 11 ou mais dígitos no total) e um campo exclusivo da v1 (journey, action, journey_context). Não existe um tipo de Problem separado para a etiqueta.

400 · application/problem+json
{
"type": "https://fingertrackid.dev/problems/validation-failed",
"title": "Request inválido",
"status": 400,
"correlation_id": "corr-problem-validation-0001",
"retryable": false,
"errors": [
{
"pointer": "/journey",
"code": "INVALID_ENUM"
}
]
}

400, não admite nova tentativa. O event_context_token está presente, mas é inválido, expirou, já foi usado ou é de outro escopo. Nada é armazenado. No perfil gerenciado de produção, um token expira no máximo ao fim da janela de evidência da sua aplicação (60 ou 300 segundos), contada a partir de quando a coleta dele chegou ao FingerTrackID (a janela de evidência). Não faça nova tentativa: o mesmo corpo recebe a mesma resposta, e um corpo diferente com os mesmos IDs de operação é um idempotency-conflict. Para ainda avaliar o evento, envie-o uma vez como uma nova operação (novos external_event_id e idempotency_key) com event_context_token: null. Quando o navegador não tiver token, envie null desde o início (orientações de integração).

400 · application/problem+json
{
"type": "https://fingertrackid.dev/problems/event-context-invalid",
"title": "Contexto do evento inválido",
"status": 400,
"correlation_id": "corr-problem-context-invalid-0001",
"retryable": false
}

400, não admite nova tentativa. O occurred_at de uma nova operação está fora de ±300 s do relógio do servidor. Confira o relógio e a origem do timestamp; esta rota não serve para backfill.

400 · application/problem+json
{
"type": "https://fingertrackid.dev/problems/occurred-at-out-of-window",
"title": "Evento fora da janela online",
"status": 400,
"correlation_id": "corr-problem-occurred-at-0001",
"retryable": false
}

401, não admite nova tentativa. A falha de autenticação uniforme (veja autenticação): erro nos bytes, nos cabeçalhos, no key_id ou na decodificação do segredo, ou credencial revogada, suspensa ou bloqueada. Trate-a como erro de configuração e emita um alerta.

401 · application/problem+json
{
"type": "https://fingertrackid.dev/problems/authentication-failed",
"title": "Autenticação falhou",
"status": 401,
"correlation_id": "corr-problem-authentication-0001",
"retryable": false
}

401, admite nova tentativa. Seu relógio está fora de ±300 s do relógio do servidor. Sincronize e envie uma nova tentativa.

401 · application/problem+json
{
"type": "https://fingertrackid.dev/problems/timestamp-out-of-window",
"title": "Timestamp da assinatura fora da janela",
"status": 401,
"correlation_id": "corr-problem-timestamp-0001",
"retryable": true
}

401, admite nova tentativa. Um request_id foi reutilizado. Envie uma nova tentativa e corrija o gerador de IDs.

401 · application/problem+json
{
"type": "https://fingertrackid.dev/problems/request-replayed",
"title": "Identificador da tentativa já consumido",
"status": 401,
"correlation_id": "corr-problem-replay-0001",
"retryable": true
}

403, não admite nova tentativa. A credencial é válida, mas não tem a capacidade da rota. Crie no console uma credencial de servidor com essa permissão.

403 · application/problem+json
{
"type": "https://fingertrackid.dev/problems/forbidden",
"title": "Capability de assessment ausente",
"status": 403,
"correlation_id": "corr-problem-forbidden-0001",
"retryable": false
}

404, não admite nova tentativa, apenas nas rotas de feedback. A avaliação de destino não existe ou está fora do escopo autenticado; os dois casos recebem esta mesma resposta. Confira o assessment_id no caminho.

409, não admite nova tentativa. A chave de idempotência ou o ID externo foi reutilizado com conteúdo diferente. Reconcilie; não invente novos IDs automaticamente.

A etiqueta (tag) é conteúdo: uma nova tentativa com os mesmos IDs e outra etiqueta é um conflito. Também é conflito um ID de uma operação v1 enviado de novo em um corpo v1.1, ou o inverso: operações v1 e v1.1 nunca compartilham IDs.

409 · application/problem+json
{
"type": "https://fingertrackid.dev/problems/idempotency-conflict",
"title": "Chave de idempotência já usada com outro conteúdo",
"status": 409,
"correlation_id": "corr-problem-idempotency-0001",
"retryable": false
}

409, não admite nova tentativa. Referências de pessoa, conta ou sessão são incompatíveis com vínculos já armazenados. Na rota de avaliação, a causa habitual é um account_ref que já está vinculado a outro subject_ref: uma conta nunca muda de pessoa. Nenhum evento ou avaliação é armazenado, e o mesmo corpo recebe a mesma resposta, então não faça nova tentativa com ele. Corrija o mapeamento no seu backend (mantenha a chave e o prefixo de cada referência inalterados ao longo do tempo; veja referências de pessoa e conta) e siga seu fluxo normal: em um login, o login prossegue.

409 · application/problem+json
{
"type": "https://fingertrackid.dev/problems/binding-conflict",
"title": "Vínculo de identidade ou sessão incompatível",
"status": 409,
"correlation_id": "corr-problem-binding-conflict-0001",
"retryable": false
}

410, não admite nova tentativa, apenas na rota de avaliação. A operação lógica autenticada existe, mas o resultado dela está fora da janela de histórico aprovada. Pare as novas tentativas; não crie novos IDs para regerar a operação antiga.

410 · application/problem+json
{
"type": "https://fingertrackid.dev/problems/assessment-result-expired",
"title": "Assessment result expired",
"status": 410,
"retryable": false
}

413, não admite nova tentativa. O corpo tem mais de 16384 bytes. Reduza-o e assine de novo.

413 · application/problem+json
{
"type": "https://fingertrackid.dev/problems/payload-too-large",
"title": "Payload excede o limite",
"status": 413,
"correlation_id": "corr-problem-payload-0001",
"retryable": false
}

415, não admite nova tentativa. O Content-Type não é exatamente application/json, ou Content-Encoding está presente.

415 · application/problem+json
{
"type": "https://fingertrackid.dev/problems/unsupported-media-type",
"title": "Representação do request não suportada",
"status": 415,
"correlation_id": "corr-problem-media-type-0001",
"retryable": false
}

429, admite nova tentativa. Acima da taxa do seu cliente de servidor. Aguarde o Retry-After e então envie uma nova tentativa com o mesmo corpo (limites).

429 · application/problem+json
{
"type": "https://fingertrackid.dev/problems/rate-limited",
"title": "Limite de assessments atingido",
"status": 429,
"correlation_id": "corr-problem-rate-limit-0001",
"retryable": true
}

500, não admite nova tentativa. Uma falha interna conhecida, antes de qualquer coisa ser armazenada. Não faça nova tentativa automática; abra um chamado de suporte com o correlation_id.

500 · application/problem+json
{
"type": "https://fingertrackid.dev/problems/internal",
"title": "Falha interna não retentável",
"status": 500,
"correlation_id": "corr-problem-internal-0001",
"retryable": false
}

503, admite nova tentativa. Indisponibilidade ou estado desconhecido. Aguarde o Retry-After (hoje sempre 1 segundo; aguarde pelo menos 1 segundo se o cabeçalho algum dia faltar) e então envie uma nova tentativa com o mesmo corpo: um request_id novo, timestamp atual e nova assinatura, porque o request_id da tentativa respondida pode já ter sido consumido. Uma avaliação retida retorna 200; um resultado expirado retorna 410 definitivo. Faça novas tentativas um número limitado de vezes, dentro do seu prazo de negócio, nunca em loop.

503 · application/problem+json
{
"type": "https://fingertrackid.dev/problems/assessment-unavailable",
"title": "Assessment temporariamente indisponível",
"status": 503,
"detail": "Repita a mesma operação lógica com novo request_id; o commit pode ter ocorrido.",
"correlation_id": "corr-assessment-timeout-0001",
"retryable": true
}

O Web SDK se comunica com o seu domínio de coleta e trata essas respostas sozinho, devolvendo ao seu código um status como UNAVAILABLE. Você nunca as interpreta, mas elas podem aparecer no painel de rede do navegador.

Sufixo do type HTTP Significado
origin-not-allowed 403 A origem da página não é uma das origens permitidas da aplicação neste domínio de coleta. A resposta não traz aprovação de CORS, então o navegador a oculta e o SDK informa TRANSPORT_ERROR
sdk-session-conflict 409 Um conflito com o estado atual da sessão do SDK; o SDK trata
event-context-conflict 409 Uma requisição de contexto do evento conflitante para o mesmo evento do SDK; o SDK trata
sdk-unavailable 503 A coleta está temporariamente indisponível; siga com um contexto null

O endpoint de coleta também usa validation-failed, authentication-failed, not-found, idempotency-conflict, payload-too-large, unsupported-media-type, rate-limited e internal com o mesmo significado acima; ali, o SDK pode fazer nova tentativa em internal.

O catálogo do FingerTrackID reserva mais alguns tipos. Um URI type com um desses sufixos ainda leva a esta página, mas as rotas de avaliação, feedback e coleta nunca os retornam: um código que trata os tipos acima trata todas as respostas.

Sufixo do type O que você recebe no lugar
signature-invalid, unknown-client, client-suspended authentication-failed. As falhas de autenticação são uniformes, então uma recusa nunca diz a quem chamou se o erro estava na assinatura, na chave ou no estado da credencial
nonce-replayed request-replayed
external-event-conflict idempotency-conflict
assessment-timeout, assessment-state-unknown assessment-unavailable: um prazo esgotado ou um estado que não pôde ser confirmado recebe nova tentativa com o mesmo corpo
journey-key-cardinality-exceeded, assessment-profile-not-activated Nada: eles são reservados para um perfil de requisição futuro, que hoje não é aceito. As requisições v1 e v1.1 nunca os retornam
  • 401 — a autenticação da tentativa falhou. authentication-failed é uniforme e não recebe nova tentativa; timestamp-out-of-window e request-replayed recebem uma nova tentativa.
  • 403 — você está autenticado, mas a credencial não tem a capacidade da rota.
  • 429 — acima da taxa do cliente de servidor. Aguarde o Retry-After e então faça nova tentativa com novos request_id, timestamp e assinatura; tentar de novo sem aguardar pode bloquear a credencial por 10 minutos (limites).
  • 503 — indisponibilidade ou estado desconhecido. Aguarde o Retry-After e então faça nova tentativa com o mesmo corpo e novos request_id, timestamp e assinatura, um número limitado de vezes; uma avaliação retida retorna 200; um resultado expirado retorna 410 definitivo.
  • Na API servidor a servidor (avaliação e feedback), 429 e 503 trazem Retry-After em segundos inteiros, no mínimo 1; hoje sempre enviam 1. Leia o cabeçalho em vez de fixar um valor no código, e aguarde pelo menos 1 segundo se ele algum dia faltar. O 429 do endpoint de coleta calcula o valor: pela taxa de novas sessões, o tempo até que a próxima abertura de sessão caiba nela; pelo limite de sessões simultâneas da aplicação, até 1800 segundos. O Web SDK respeita esse valor por você.
  • Toda resposta traz X-Correlation-Id, opaco e sem dados pessoais. Guarde-o para o suporte.
  • Um POST para um caminho que não começa com /v1/assessments recebe 404. Variações de /v1/assessments (query, barra final) e qualquer método diferente de POST recebem 400 validation-failed.