# Erros da API

<https://unifokal.com/docs/erros>

## Erros da API

Toda resposta de erro tem o mesmo envelope, em toda rota: `{ "error": "<código>", "message": "<texto>" }`. Trate pelo `error`, que é estável dentro de `/v1`. O `message` é para gente e pode mudar. Nenhum dos códigos abaixo cria sessão nem é cobrado.

Cada código tem a própria âncora: cole o código no fim do endereço desta página, depois de um `#`, e você cai direto nele. São 91 códigos em 4 grupos.

- [Criação de sessão: os erros do primeiro dia](https://unifokal.com/docs/erros#criacao-de-sessao)
- [Criação de sessão: códigos de um módulo do flow](https://unifokal.com/docs/erros#criacao-por-modulo)
- [Emissão de link hospedado](https://unifokal.com/docs/erros#link-hospedado)
- [Cifra da carga do webhook, no painel](https://unifokal.com/docs/erros#cifra-do-webhook)

### Criação de sessão: os erros do primeiro dia

Respostas de POST /v1/verification-sessions que qualquer flow pode receber. O mesmo vocabulário vale nas outras rotas da chave secreta: credencial, conta e teto por minuto respondem igual em todas.

#### `validation_error` HTTP 400

**O que aconteceu.** Um campo obrigatório faltou ou veio fora do formato. A mensagem nomeia o campo, o valor aceito e o limite, e nunca repete o valor que você mandou.

**O que fazer.** Leia o campo nomeado na mensagem, corrija o corpo e mande de novo. Confira também o cabeçalho Content-Type: application/json, sem ele a requisição chega sem corpo.

**O que não fazer.** Não repita a mesma chamada esperando outra resposta: o corpo igual devolve o mesmo erro.

Veja também: [POST /v1/verification-sessions](https://unifokal.com/docs/api-rest#post-sessions)

#### `unknown_policy_key` HTTP 400

**O que aconteceu.** O bloco policy trouxe uma chave que não existe. O bloco é uma lista fechada, e a chave recusada vem nomeada na mensagem.

**O que fazer.** Tire a chave ou corrija o nome dela conforme a referência da criação de sessão e mande de novo.

**O que não fazer.** Não trate como aviso: nada foi criado, e a política que você achou que ligou não vale para sessão nenhuma.

Veja também: [POST /v1/verification-sessions](https://unifokal.com/docs/api-rest#post-sessions)

#### `unknown_monitoring_key` HTTP 400

**O que aconteceu.** O bloco monitoring trouxe uma chave que não existe. O bloco é uma lista fechada, e a chave recusada vem nomeada na mensagem.

**O que fazer.** Tire a chave ou corrija o nome dela e mande de novo. Sem o bloco, a sessão herda o que o flow define.

**O que não fazer.** Não conte com o monitoramento dessa sessão: a chamada foi recusada inteira.

Veja também: [POST /v1/verification-sessions](https://unifokal.com/docs/api-rest#post-sessions)

#### `invalid_api_key` HTTP 401

**O que aconteceu.** A chave secreta não veio, veio sem o prefixo Bearer, não existe ou foi revogada. A mensagem diz qual dos casos.

**O que fazer.** Mande o cabeçalho Authorization: Bearer seguido da chave sk_test\_ ou sk_live\_ do ambiente certo. Se a chave foi revogada, gere outra no painel e troque no seu cofre de segredos.

**O que não fazer.** Não mande a chave secreta pelo navegador nem pelo aplicativo: ela vive só no seu servidor.

Veja também: [Autenticação](https://unifokal.com/docs/autenticacao#auth)

#### `organization_suspended` HTTP 403

**O que aconteceu.** A organização está suspensa, e toda chamada com a chave secreta para de uma vez.

**O que fazer.** Entre no painel para ver o motivo da suspensão, ou fale com o suporte.

**O que não fazer.** Não gire chave nem crie conta nova para contornar: a suspensão é da organização, e a chave nova cai no mesmo erro.

Veja também: [Autenticação](https://unifokal.com/docs/autenticacao#auth)

#### `test_key_used_in_production` HTTP 403

**O que aconteceu.** O prefixo da chave diz um ambiente e o registro dela diz outro. O caso clássico é a chave guardada na variável errada do deploy.

**O que fazer.** Use a chave do ambiente que você quer chamar: sk_test\_ para sandbox, sk_live\_ para produção.

**O que não fazer.** Não edite o prefixo da chave à mão: o prefixo faz parte dela.

Veja também: [Sandbox e produção: o que muda](https://unifokal.com/docs/ambientes#ambientes)

#### `email_not_verified` HTTP 403

**O que aconteceu.** A conta ainda não confirmou o e-mail. A chave é válida e o flow existe, mas nenhuma sessão é criada antes da confirmação.

**O que fazer.** Confirme o e-mail da conta pelo link que enviamos e conclua o onboarding no painel.

**O que não fazer.** Não troque de chave: o bloqueio é da conta, não da credencial.

Veja também: [Autenticação](https://unifokal.com/docs/autenticacao#auth)

#### `credential_type_not_allowed` HTTP 403

**O que aconteceu.** Você mandou uma credencial do painel (dsk\_) numa rota que só aceita a chave secreta.

**O que fazer.** Chame esta rota com a chave secreta sk_test\_ ou sk_live\_, do seu servidor.

**O que não fazer.** Não reaproveite o token da sessão do painel na integração.

Veja também: [Autenticação](https://unifokal.com/docs/autenticacao#auth)

#### `flow_not_found` HTTP 404

**O que aconteceu.** O flow_id não existe neste ambiente. Um flow vive num ambiente só, e o ambiente é a chave que você usou: o mesmo id não existe do outro lado.

**O que fazer.** Confira o flow_id e a chave. Flow de produção se chama com sk_live\_, flow de sandbox com sk_test\_.

**O que não fazer.** Não tente o mesmo id com a chave do outro ambiente esperando achar o flow: crie o flow no ambiente em que vai usá-lo.

Veja também: [Sandbox e produção: o que muda](https://unifokal.com/docs/ambientes#ambientes)

#### `flow_not_live` HTTP 422

**O que aconteceu.** O flow existe, mas não está ativo: ainda é rascunho ou foi arquivado.

**O que fazer.** Ative o flow no painel, ou use o flow_id de um flow ativo, e mande de novo.

**O que não fazer.** Não repita a chamada em laço: enquanto o flow não estiver ativo, a resposta é a mesma.

Veja também: [Integração ponta a ponta](https://unifokal.com/docs/integracao#integracao)

#### `email_not_accepted` HTTP 422

**O que aconteceu.** O corpo trouxe email. O contato do titular nunca entra na criação de sessão: quem pergunta a pessoa e dispara o código é o widget.

**O que fazer.** Tire email do corpo. O titular digita o e-mail na verificação.

**O que não fazer.** Não mande o e-mail por outro campo para contornar: o widget é quem prova a posse do canal.

Veja também: [Validação de canal: e-mail e telefone](https://unifokal.com/docs/modulos/canal#modulos-canal)

#### `phone_not_accepted` HTTP 422

**O que aconteceu.** O corpo trouxe phone. O telefone do titular nunca entra na criação de sessão: quem pergunta a pessoa e dispara o código é o widget.

**O que fazer.** Tire phone do corpo. O titular digita o telefone na verificação.

**O que não fazer.** Não mande o telefone por outro campo para contornar: o widget é quem prova a posse do canal.

Veja também: [Validação de canal: e-mail e telefone](https://unifokal.com/docs/modulos/canal#modulos-canal)

#### `insufficient_credit` HTTP 402

**O que aconteceu.** O saldo de produção não cobre o máximo que esta verificação pode custar. A mensagem diz quanto falta.

**O que fazer.** Recarregue o saldo no painel (Cobrança) ou ligue a recarga automática, e mande de novo.

**O que não fazer.** Não troque para a chave de sandbox em produção: o sandbox não verifica ninguém de verdade.

Veja também: [Sandbox e produção: o que muda](https://unifokal.com/docs/ambientes#ambientes)

#### `sandbox_limit_reached` HTTP 429

**O que aconteceu.** O sandbox chegou ao teto mensal de 500 sessões.

**O que fazer.** Espere a virada do mês para seguir testando, ou passe a integração para produção.

**O que não fazer.** Não trate como o limite por minuto: esperar alguns segundos não resolve este 429.

Veja também: [Sandbox](https://unifokal.com/docs/ambientes#sandbox)

#### `rate_limited` HTTP 429

**O que aconteceu.** A conta passou do teto de chamadas por minuto. Na criação de sessão ele é de 60 em produção e 240 em sandbox.

**O que fazer.** Espere o prazo do cabeçalho Retry-After e tente de novo, com recuo exponencial se o volume for alto.

**O que não fazer.** Não repita na hora nem em paralelo: cada tentativa imediata conta no mesmo teto.

Veja também: [Sandbox e produção: o que muda](https://unifokal.com/docs/ambientes#ambientes)

#### `idempotency_conflict` HTTP 409

**O que aconteceu.** Uma chamada com o mesmo reference_id ainda está em andamento. O reference_id é a chave de idempotência da criação.

**O que fazer.** Espere a primeira terminar e repita: a repetição recebe a mesma sessão, com o cabeçalho Idempotent-Replay: true.

**O que não fazer.** Não gere um reference_id novo para escapar do conflito: ele identifica o seu usuário, não a tentativa.

Veja também: [POST /v1/verification-sessions](https://unifokal.com/docs/api-rest#post-sessions)

#### `idempotency_key_reuse` HTTP 422

**O que aconteceu.** O mesmo reference_id voltou com um corpo diferente dentro da janela em que a sessão anterior vale (15 minutos).

**O que fazer.** Repita com o mesmo corpo da primeira chamada, ou espere a sessão anterior vencer para mandar o corpo novo.

**O que não fazer.** Não reaproveite o reference_id de um usuário para outro usuário.

Veja também: [POST /v1/verification-sessions](https://unifokal.com/docs/api-rest#post-sessions)

#### `policy_module_not_in_flow` HTTP 422

**O que aconteceu.** O bloco policy ajusta um módulo que este flow não tem. A política é recusada com nome para você não achar que desligou algo que segue ligado.

**O que fazer.** Tire a chave de política do módulo ausente, ou adicione o módulo ao flow no painel.

**O que não fazer.** Não mantenha a chave esperando que ela valha quando o módulo entrar: a chamada inteira é recusada.

Veja também: [POST /v1/verification-sessions](https://unifokal.com/docs/api-rest#post-sessions)

#### `policy_ubo_cap_above_flow` HTTP 422

**O que aconteceu.** policy.ubo_max_paid_nodes veio acima do teto do próprio flow. O teto da sessão só aperta o do flow, nunca o afrouxa.

**O que fazer.** Mande um valor menor ou igual ao do flow, ou suba o teto no flow pelo painel.

**O que não fazer.** Não tente subir o gasto de uma sessão por este campo: o gasto só sobe por decisão registrada no flow.

Veja também: [Cadeia societária até o beneficiário final](https://unifokal.com/docs/modulos/ubo-profundo#modulo-ubo-profundo)

#### `session_not_supported` HTTP 422

**O que aconteceu.** O flow informado só recebe alertas do monitoramento transacional e não aceita sessão de verificação. Vale igual na emissão do link hospedado.

**O que fazer.** Mande os eventos com o bloco transaction, ou crie a sessão no seu flow de verificação.

**O que não fazer.** Não abra o widget para este flow: ele não tem jornada de titular.

Veja também: [Monitoramento transacional](https://unifokal.com/docs/modulos/transacao-monitor#modulo-transacao-monitor)

### Criação de sessão: códigos de um módulo do flow

Estes só existem quando o flow tem o módulo correspondente, ou quando a conta ligou um teto no painel. Sem o módulo, a porta não existe.

#### `counterparty_country_invalid` HTTP 422

**O que aconteceu.** Um evento de transação trouxe em counterparty_country um código de duas letras que não está na lista fechada de países (ISO 3166-1 alfa-2). A mensagem aponta o índice do evento, nunca o valor.

**O que fazer.** Mande o código ISO 3166-1 alfa-2 do país da contraparte (por exemplo PA ou BR), ou deixe o campo de fora quando não souber.

**O que não fazer.** Não reenvie o lote igual: a validação vem antes de qualquer gravação, e o lote inteiro é recusado de novo.

Veja também: [PLD/FT pela regra da norma](https://unifokal.com/docs/pld-ft#pld-ft)

#### `pld_profile_invalid` HTTP 422

**O que aconteceu.** O corpo trouxe o bloco opcional pld_profile com um campo fora do formato. A mensagem traz o nome do campo, nunca o valor.

**O que fazer.** Corrija o campo apontado conforme o perfil descrito na página de PLD/FT, ou mande a chamada sem o bloco.

**O que não fazer.** Não repita a chamada igual: o bloco é validado antes de qualquer gravação, e a recusa se repete.

Veja também: [PLD/FT pela regra da norma](https://unifokal.com/docs/pld-ft#pld-ft)

#### `pld_profile_not_supported` HTTP 422

**O que aconteceu.** O corpo trouxe pld_profile num flow sem o módulo que o lê: pld_risco na criação de sessão, ou pld_monitor na ingestão de transação.

**O que fazer.** Ligue o módulo no flow, ou mande a chamada sem o bloco.

**O que não fazer.** Não conte com o bloco aceito e ignorado: sem o módulo, a chamada é recusada, para você não achar que informou o perfil do seu cliente.

Veja também: [PLD/FT pela regra da norma](https://unifokal.com/docs/pld-ft#pld-ft)

#### `transaction_conflict` HTTP 422

**O que aconteceu.** O corpo trouxe transaction e transactions juntos. Os dois são exclusivos.

**O que fazer.** Mande um evento no singular (transaction) ou o lote (transactions), nunca os dois.

**O que não fazer.** Não duplique o evento nos dois campos para garantir: a chamada é recusada inteira.

Veja também: [Gate transacional](https://unifokal.com/docs/modulos/transacao#modulo-transacao)

#### `transaction_not_supported` HTTP 422

**O que aconteceu.** O bloco de transação foi para um flow sem módulo que consome transação.

**O que fazer.** Mande a transação para o flow que tem o módulo transacional, ou adicione o módulo ao flow.

**O que não fazer.** Não conte com o evento gravado: nada foi aceito.

Veja também: [Gate transacional](https://unifokal.com/docs/modulos/transacao#modulo-transacao)

#### `batch_too_large` HTTP 422

**O que aconteceu.** O lote transactions passou do teto de eventos por chamada. O teto vem no corpo do erro.

**O que fazer.** Divida o lote em partes dentro do teto informado e mande cada parte. O external_id evita duplicar.

**O que não fazer.** Não descubra o teto por tentativa: ele já vem na resposta.

Veja também: [Gate transacional](https://unifokal.com/docs/modulos/transacao#modulo-transacao)

#### `batch_not_supported_for_gate` HTTP 422

**O que aconteceu.** O lote foi para um flow com o gate transacional síncrono, que decide um pagamento por vez.

**O que fazer.** Mande cada evento no singular, pelo campo transaction.

**O que não fazer.** Não espere veredito por item de um lote neste flow.

Veja também: [Gate transacional](https://unifokal.com/docs/modulos/transacao#modulo-transacao)

#### `transaction_required` HTTP 422

**O que aconteceu.** O flow contém o gate transacional e a chamada veio sem o bloco transaction. Vale na criação de sessão e na emissão de link hospedado.

**O que fazer.** Mande o evento no bloco transaction. Esse flow só recebe transação.

**O que não fazer.** Não abra o widget nem emita link para este flow: uma sessão de titular não teria o que perguntar a ele.

Veja também: [Gate transacional](https://unifokal.com/docs/modulos/transacao#modulo-transacao)

#### `external_id_required` HTTP 422

**O que aconteceu.** O evento de transação veio sem external_id, que é o token de idempotência do evento.

**O que fazer.** Mande um external_id estável por evento, o mesmo em toda reentrega daquele evento.

**O que não fazer.** Não gere um external_id novo a cada tentativa: é ele que impede evento duplicado e segunda cobrança.

Veja também: [Gate transacional](https://unifokal.com/docs/modulos/transacao#modulo-transacao)

#### `amount_too_large` HTTP 422

**O que aconteceu.** amount_cents veio acima do teto de valor aceito por evento.

**O que fazer.** Confira a unidade: o valor vai em centavos, como inteiro. Corrija e mande de novo.

**O que não fazer.** Não divida um movimento real em vários eventos para caber no teto.

Veja também: [Gate transacional](https://unifokal.com/docs/modulos/transacao#modulo-transacao)

#### `currency_not_supported` HTTP 422

**O que aconteceu.** A moeda do evento não é BRL, a única aceita.

**O que fazer.** Mande o valor em reais, com currency BRL.

**O que não fazer.** Não converta sem registrar: o evento precisa descrever o movimento como ele aconteceu em reais.

Veja também: [Gate transacional](https://unifokal.com/docs/modulos/transacao#modulo-transacao)

#### `event_too_old` HTTP 422

**O que aconteceu.** occurred_at está além da janela de importação de eventos antigos.

**O que fazer.** Mande só eventos dentro da janela. Dentro dela, o evento antigo entra normalmente.

**O que não fazer.** Não altere occurred_at para caber na janela: a data precisa ser a do movimento.

Veja também: [Gate transacional](https://unifokal.com/docs/modulos/transacao#modulo-transacao)

#### `reference_id_charset` HTTP 422

**O que aconteceu.** Um id opaco do evento, ou o act.external_id, trouxe caractere fora do conjunto aceito. A mensagem nomeia o campo recusado.

**O que fazer.** Use só os caracteres aceitos no campo nomeado, de preferência o id interno que você já usa.

**O que não fazer.** Não ponha dado pessoal no id para torná-lo legível.

Veja também: [Gate transacional](https://unifokal.com/docs/modulos/transacao#modulo-transacao)

#### `pii_shaped_value` HTTP 422

**O que aconteceu.** Um id opaco do evento, ou o act.external_id, tem forma de dado pessoal (CPF, CNPJ, e-mail, telefone, chave Pix ou número de cartão). O corpo do erro nunca devolve o valor.

**O que fazer.** Troque pelo seu identificador interno, sem dado pessoal dentro.

**O que não fazer.** Não mascare o dado pessoal para passar: o id é opaco por contrato.

Veja também: [Gate transacional](https://unifokal.com/docs/modulos/transacao#modulo-transacao)

#### `pending_lifecycle_not_enabled` HTTP 422

**O que aconteceu.** O evento veio com status pending num flow cujo módulo não aceita o ciclo pendente.

**O que fazer.** Mande o evento já confirmado. Se ele for desfeito depois, mande a reversão.

**O que não fazer.** Não mande o mesmo evento duas vezes, uma pendente e outra confirmada.

Veja também: [Gate transacional](https://unifokal.com/docs/modulos/transacao#modulo-transacao)

#### `settlement_status_invalid` HTTP 422

**O que aconteceu.** Uma liquidação ou reversão veio com status pending. Liquidação e reversão nunca chegam pendentes.

**O que fazer.** Mande a liquidação ou a reversão quando ela já tiver acontecido.

**O que não fazer.** Não antecipe a liquidação como pendente.

Veja também: [Gate transacional](https://unifokal.com/docs/modulos/transacao#modulo-transacao)

#### `unknown_settles_reference` HTTP 422

**O que aconteceu.** settles não aponta um evento seu no mesmo ambiente.

**O que fazer.** Mande antes o evento original, no mesmo ambiente, e depois a liquidação apontando o external_id dele.

**O que não fazer.** Não aponte evento de outro ambiente: sandbox e produção não se enxergam.

Veja também: [Gate transacional](https://unifokal.com/docs/modulos/transacao#modulo-transacao)

#### `already_settled` HTTP 409

**O que aconteceu.** O alvo já tem liquidação ou reversão. A segunda do mesmo alvo é recusada.

**O que fazer.** Trate como já registrado. Para desfazer um movimento, mande uma reversão do evento original.

**O que não fazer.** Não repita a liquidação com outro external_id.

Veja também: [Gate transacional](https://unifokal.com/docs/modulos/transacao#modulo-transacao)

#### `daily_ingest_cap_reached` HTTP 429

**O que aconteceu.** A organização chegou ao teto diário de eventos de transação. O lote recusado não gravou nada, e a resposta não traz Retry-After porque o balde é o dia.

**O que fazer.** Pause o envio e retome no dia seguinte, a partir do lote recusado.

**O que não fazer.** Não repita em laço durante o dia: a resposta é a mesma até a virada.

Veja também: [Gate transacional](https://unifokal.com/docs/modulos/transacao#modulo-transacao)

#### `assinatura_document_required` HTTP 422

**O que aconteceu.** O flow contém o módulo de assinatura e a chamada veio sem document_sha256. A emissão de link para esse flow cai no mesmo código.

**O que fazer.** Mande o bloco assinatura com o hash do documento. A sessão desse flow nasce pela API, não por link.

**O que não fazer.** Não emita link hospedado para este flow: o link não leva o documento.

Veja também: [Assinatura eletrônica](https://unifokal.com/docs/modulos/assinatura#modulo-assinatura)

#### `assinatura_not_supported` HTTP 422

**O que aconteceu.** O bloco assinatura foi para um flow sem o módulo de assinatura.

**O que fazer.** Tire o bloco, ou use o flow que tem o módulo.

**O que não fazer.** Não conte com o documento assinado: nada foi criado.

Veja também: [Assinatura eletrônica](https://unifokal.com/docs/modulos/assinatura#modulo-assinatura)

#### `document_blocklisted` HTTP 422

**O que aconteceu.** Na reautenticação facial, o documento da matrícula está na sua lista de bloqueio.

**O que fazer.** Revise a entrada na lista de bloqueio. Se ela não vale mais, solte o bloqueio pela verificação ou por Sessões no painel.

**O que não fazer.** Não matricule o mesmo titular de novo para contornar o bloqueio.

Veja também: [Reautenticação facial](https://unifokal.com/docs/modulos/face-reauth#modulo-face-reauth)

#### `reauth_rate_limited` HTTP 429

**O que aconteceu.** A conta passou do teto de tentativas de reautenticação facial.

**O que fazer.** Espere o prazo do cabeçalho Retry-After, em segundos, e tente de novo.

**O que não fazer.** Não repita antes do prazo: cada tentativa imediata recebe o mesmo 429.

Veja também: [Reautenticação facial](https://unifokal.com/docs/modulos/face-reauth#modulo-face-reauth)

#### `expected_address_not_supported` HTTP 422

**O que aconteceu.** expected_address foi para um flow sem o módulo de comprovante de endereço.

**O que fazer.** Tire o campo, ou use o flow que tem o módulo endereco_ocr.

**O que não fazer.** Não conte com o cruzamento de endereço: nada foi criado.

Veja também: [Comprovante de endereço](https://unifokal.com/docs/modulos/endereco-ocr#modulo-endereco-ocr)

#### `consultation_authorization_required` HTTP 422

**O que aconteceu.** O flow contém o módulo de custódia da autorização e a chamada veio sem o bloco consultation_authorization. A emissão de link para esse flow cai no mesmo código.

**O que fazer.** Mande o bloco com o hash do texto que o titular autorizou. A sessão desse flow nasce pela API.

**O que não fazer.** Não emita link hospedado para este flow: o link não leva a autorização.

Veja também: [Custódia da autorização de consulta](https://unifokal.com/docs/modulos/custodia-autorizacao#modulo-custodia-autorizacao)

#### `consultation_authorization_not_supported` HTTP 422

**O que aconteceu.** O bloco consultation_authorization foi para um flow sem o módulo de custódia.

**O que fazer.** Tire o bloco, ou use o flow que tem o módulo.

**O que não fazer.** Não conte com a autorização guardada: nada foi criado.

Veja também: [Custódia da autorização de consulta](https://unifokal.com/docs/modulos/custodia-autorizacao#modulo-custodia-autorizacao)

#### `unknown_consultation_authorization_key` HTTP 400

**O que aconteceu.** O bloco consultation_authorization trouxe uma chave que não existe. A chave recusada vem nomeada na mensagem.

**O que fazer.** Tire a chave ou corrija o nome dela e mande de novo.

**O que não fazer.** Não trate como aviso: a chamada foi recusada inteira.

Veja também: [Custódia da autorização de consulta](https://unifokal.com/docs/modulos/custodia-autorizacao#modulo-custodia-autorizacao)

#### `foreign_entity_required` HTTP 422

**O que aconteceu.** O flow verifica uma empresa estrangeira e a chamada não trouxe o bloco foreign_entity.

**O que fazer.** Mande o bloco com o LEI da empresa, ou com o nome e o país dela.

**O que não fazer.** Não tente pelo link hospedado: ele não leva a empresa.

Veja também: [Empresa estrangeira](https://unifokal.com/docs/modulos/kyb-estrangeira#modulo-kyb-estrangeira)

#### `foreign_entity_not_supported` HTTP 422

**O que aconteceu.** O bloco foreign_entity foi para um flow sem o módulo de empresa estrangeira.

**O que fazer.** Tire o bloco, ou use o flow que tem o módulo.

**O que não fazer.** Não conte com a empresa verificada: nada foi criado.

Veja também: [Empresa estrangeira](https://unifokal.com/docs/modulos/kyb-estrangeira#modulo-kyb-estrangeira)

#### `foreign_entity_lei_invalid` HTTP 422

**O que aconteceu.** O LEI informado não confere o dígito de controle da norma. Quase sempre é erro de digitação.

**O que fazer.** Confira o identificador com o cliente e mande de novo, ou mande o nome e o país.

**O que não fazer.** Não leia como empresa inexistente: o identificador é que está errado.

Veja também: [Empresa estrangeira](https://unifokal.com/docs/modulos/kyb-estrangeira#modulo-kyb-estrangeira)

#### `foreign_entity_too_many_owners` HTTP 422

**O que aconteceu.** O bloco declarou mais beneficiários finais do que o teto por sessão.

**O que fazer.** Declare só as pessoas naturais que controlam a empresa e mande de novo.

**O que não fazer.** Não divida em várias sessões da mesma empresa para passar do teto.

Veja também: [Empresa estrangeira](https://unifokal.com/docs/modulos/kyb-estrangeira#modulo-kyb-estrangeira)

#### `unknown_foreign_entity_key` HTTP 400

**O que aconteceu.** O bloco foreign_entity trouxe uma chave que não existe. A chave recusada vem nomeada na mensagem.

**O que fazer.** Tire a chave ou corrija o nome dela e mande de novo.

**O que não fazer.** Não trate como aviso: a chamada foi recusada inteira.

Veja também: [Empresa estrangeira](https://unifokal.com/docs/modulos/kyb-estrangeira#modulo-kyb-estrangeira)

#### `unknown_beneficial_owner_key` HTTP 400

**O que aconteceu.** Um beneficiário declarado trouxe uma chave que não existe. Hoje só o nome é aceito.

**O que fazer.** Mande cada beneficiário só com o campo name.

**O que não fazer.** Não trate como aviso: a chamada foi recusada inteira.

Veja também: [Empresa estrangeira](https://unifokal.com/docs/modulos/kyb-estrangeira#modulo-kyb-estrangeira)

#### `origin_tag_not_supported` HTTP 422

**O que aconteceu.** origin_tag veio junto do bloco de transação. A ingestão de transação não tem jornada a rotular.

**O que fazer.** Tire origin_tag das chamadas de transação e mantenha só nas de sessão.

**O que não fazer.** Não use origin_tag para marcar lote de transação: use o external_id.

Veja também: [POST /v1/verification-sessions](https://unifokal.com/docs/api-rest#post-sessions)

#### `spend_cap_reached` HTTP 429

**O que aconteceu.** A conta configurou um orçamento diário de gasto no painel e ele acabou hoje. Nada é cobrado nesta recusa.

**O que fazer.** Espere o Retry-After, que vai até 00:00 UTC, ou suba o teto no painel. Subir passa a valer na virada do dia.

**O que não fazer.** Não trate como retentativa curta: é uma pausa até a virada do dia.

Veja também: [Painel de operação](https://unifokal.com/docs/painel-de-operacao#painel-de-operacao)

#### `volume_cap_reached` HTTP 429

**O que aconteceu.** A conta configurou um teto diário de operações no painel e ele foi alcançado hoje.

**O que fazer.** Espere o Retry-After, que vai até 00:00 UTC, ou suba o teto no painel. Subir passa a valer na virada do dia.

**O que não fazer.** Não trate como retentativa curta: é uma pausa até a virada do dia.

Veja também: [Painel de operação](https://unifokal.com/docs/painel-de-operacao#painel-de-operacao)

#### `attempt_limit_reached` HTTP 429

**O que aconteceu.** A mesma referência (reference_id) já tentou vezes demais num período recente. A sessão não foi criada e nada foi cobrado.

**O que fazer.** Encerre a tentativa daquela pessoa e siga pelo seu atendimento. Se o caso for legítimo, fale com o suporte.

**O que não fazer.** Não repita automaticamente nem troque o reference_id para contornar: ele identifica o seu usuário, e a recusa não traz prazo de nova tentativa.

Veja também: [POST /v1/verification-sessions](https://unifokal.com/docs/api-rest#post-sessions)

#### `module_quota_reached` HTTP 429

**O que aconteceu.** A organização alcançou hoje a cota diária de sessões novas com o módulo de PEP e sanções. A sessão não foi criada e nada foi cobrado.

**O que fazer.** Espere o Retry-After, que vai até 00:00 UTC. Se o seu volume pede mais, fale com o suporte: a cota é ajustada por organização.

**O que não fazer.** Não repita em laço curto nem crie sessão sem o módulo para contornar: a renovação de uma sessão já criada não conta de novo.

Veja também: [POST /v1/verification-sessions](https://unifokal.com/docs/api-rest#post-sessions)

#### `account_event_required` HTTP 422

**O que aconteceu.** O flow contém o módulo de proteção de conta e a chamada veio sem o bloco account_event.

**O que fazer.** Mande o evento de conta (login, troca de senha, recuperação de acesso) no bloco account_event.

**O que não fazer.** Não abra o widget para este flow: ele avalia eventos de conta, não uma jornada de verificação.

Veja também: [Proteção de conta](https://unifokal.com/docs/modulos/conta#modulo-conta)

#### `account_event_not_supported` HTTP 422

**O que aconteceu.** O bloco account_event foi para um flow sem o módulo de proteção de conta.

**O que fazer.** Mande o evento para o flow que tem o módulo conta, ou adicione o módulo ao flow.

**O que não fazer.** Não conte com o evento avaliado: nada foi aceito.

Veja também: [Proteção de conta](https://unifokal.com/docs/modulos/conta#modulo-conta)

#### `account_event_ip_not_public` HTTP 422

**O que aconteceu.** account_event.device.ip veio com um endereço privado, de loopback ou de link-local. O campo precisa ser o IP público do usuário final.

**O que fazer.** Mande o IP público de quem fez a ação, lido na borda da sua infraestrutura (o primeiro IP confiável do cabeçalho do seu proxy).

**O que não fazer.** Não mande o IP do seu servidor, do balanceador ou da rede interna.

Veja também: [Proteção de conta](https://unifokal.com/docs/modulos/conta#modulo-conta)

#### `session_monitoring_not_supported` HTTP 422

**O que aconteceu.** O bloco session_monitoring foi para um flow sem o módulo de monitoramento de sessão.

**O que fazer.** Tire o bloco, ou use o flow que tem o módulo sessao_monitor.

**O que não fazer.** Não conte com a sessão monitorada: nada foi criado, e nenhum alerta sairia dela.

Veja também: [Monitoramento de sessão](https://unifokal.com/docs/modulos/sessao-monitor#modulo-sessao-monitor)

#### `reference_id_required` HTTP 422

**O que aconteceu.** O flow tem um módulo que amarra o resultado a um titular (proteção de conta, reautenticação facial, monitoramento de sessão ou dispositivo Pix) e a chamada veio sem reference_id utilizável.

**O que fazer.** Mande o reference_id do titular, o mesmo identificador que você usa para ele no seu sistema.

**O que não fazer.** Não mande um valor aleatório por chamada: sem o titular certo, o resultado não tem a quem se referir.

Veja também: [POST /v1/verification-sessions](https://unifokal.com/docs/api-rest#post-sessions)

#### `window_too_long` HTTP 422

**O que aconteceu.** session_monitoring.window_hours veio acima do teto da janela de monitoramento. A mensagem traz o teto. O valor é recusado com nome, nunca cortado em silêncio.

**O que fazer.** Mande uma janela dentro do teto informado, ou omita o campo para usar a janela padrão.

**O que não fazer.** Não programe o seu atendimento contando com uma cobertura maior que a janela aceita.

Veja também: [Monitoramento de sessão](https://unifokal.com/docs/modulos/sessao-monitor#modulo-sessao-monitor)

#### `enrollment_not_found` HTTP 422

**O que aconteceu.** Na reautenticação facial, não há matrícula biométrica utilizável para aquele reference_id. A matrícula nasce num onboarding aprovado com face e prova de vida.

**O que fazer.** Rode o onboarding do titular uma vez, num flow marcado para matricular, e depois peça a reautenticação.

**O que não fazer.** Não tente matricular pela aprovação manual da fila de revisão: matrícula nasce de prova, não de decisão de operador.

Veja também: [Reautenticação facial](https://unifokal.com/docs/modulos/face-reauth#modulo-face-reauth)

#### `enrollment_locked` HTTP 422

**O que aconteceu.** A matrícula do titular travou depois de reautenticações seguidas que não bateram.

**O que fazer.** Peça ao titular um novo onboarding aprovado: é ele que destrava a matrícula.

**O que não fazer.** Não insista na reautenticação: enquanto a matrícula estiver travada, a resposta é a mesma.

Veja também: [Reautenticação facial](https://unifokal.com/docs/modulos/face-reauth#modulo-face-reauth)

#### `pix_device_required` HTTP 422

**O que aconteceu.** O flow contém o módulo de dispositivo Pix e a chamada veio sem o bloco pix_device.

**O que fazer.** Mande o bloco pix_device com o fingerprint do aparelho que está sendo cadastrado.

**O que não fazer.** Não abra este flow sem o aparelho: o vínculo é aparelho e titular.

Veja também: [Cadastro de dispositivo Pix](https://unifokal.com/docs/modulos/pix-device#modulo-pix-device)

#### `pix_device_module_not_in_flow` HTTP 422

**O que aconteceu.** O bloco pix_device foi para um flow sem o módulo de dispositivo Pix.

**O que fazer.** Tire o bloco, ou use o flow que tem o módulo pix_device.

**O que não fazer.** Não conte com o aparelho cadastrado: nada foi criado.

Veja também: [Cadastro de dispositivo Pix](https://unifokal.com/docs/modulos/pix-device#modulo-pix-device)

#### `pix_device_reference_required` HTTP 422

**O que aconteceu.** O flow contém o módulo de dispositivo Pix e a chamada veio sem reference_id.

**O que fazer.** Mande o reference_id do titular dono do aparelho.

**O que não fazer.** Não reaproveite o reference_id de outro titular: o vínculo é aparelho e titular.

Veja também: [Cadastro de dispositivo Pix](https://unifokal.com/docs/modulos/pix-device#modulo-pix-device)

#### `credit_relationship_required` HTTP 422

**O que aconteceu.** O flow tem módulo de consulta de crédito e a chamada veio sem credit_relationship. A Lei 12.414, art. 15, exige que o consulente declare a relação com o cadastrado.

**O que fazer.** Mande credit_relationship com mantem ou pretende_manter, conforme a relação comercial ou de crédito com o titular.

**O que não fazer.** Não declare uma relação que não existe: a declaração é sua, e fica registrada na sessão.

Veja também: [Análise de crédito](https://unifokal.com/docs/modulos/credito#modulos-credito)

#### `credit_relationship_not_supported` HTTP 422

**O que aconteceu.** credit_relationship foi para um flow sem módulo de consulta de crédito.

**O que fazer.** Tire o campo, ou use o flow que tem o módulo de crédito.

**O que não fazer.** Não mande o campo em todo flow por padrão: ele só vale onde há consulta de crédito.

Veja também: [Análise de crédito](https://unifokal.com/docs/modulos/credito#modulos-credito)

#### `credit_purpose_required` HTTP 422

**O que aconteceu.** O flow tem módulo de consulta de crédito e não declara a finalidade da consulta, que a Lei 12.414, art. 7, exige.

**O que fazer.** Edite o flow no painel e declare a finalidade da consulta de crédito.

**O que não fazer.** Não troque o flow por outro sem módulo de crédito esperando o mesmo resultado.

Veja também: [Análise de crédito](https://unifokal.com/docs/modulos/credito#modulos-credito)

#### `credit_consulente_unverified` HTTP 422

**O que aconteceu.** A consulta de crédito exige a conta com CNPJ cadastrado e verificado, e a sua conta ainda não está assim.

**O que fazer.** Cadastre e verifique o CNPJ da conta no painel e mande de novo.

**O que não fazer.** Não use a conta de outra empresa: o consulente é quem responde pela consulta.

Veja também: [Análise de crédito](https://unifokal.com/docs/modulos/credito#modulos-credito)

#### `act_requires_passkey` HTTP 422

**O que aconteceu.** O corpo trouxe o bloco act, e o flow não tem o módulo passkey. O ato só é aprovado com o fator do titular.

**O que fazer.** Use um flow com o módulo passkey para a sessão com ato, ou tire o bloco act da chamada.

**O que não fazer.** Não tire o act e trate a sessão comum como aprovação do ato: ela não prova que a pessoa aprovou aquele ato.

Veja também: [Aprovação de ato com passkey](https://unifokal.com/docs/modulos/passkey#modulo-passkey)

#### `passkey_not_enrolled` HTTP 422

**O que aconteceu.** O flow aprova com a passkey, e a conta deste reference_id não tem passkey ativa que sirva para o pedido.

**O que fazer.** Vincule a passkey antes, com um flow de cadastro que a vincula, ou use outro fator para esta pessoa.

**O que não fazer.** Não repita a mesma chamada: sem a passkey vinculada, a resposta é a mesma.

Veja também: [Aprovação de ato com passkey](https://unifokal.com/docs/modulos/passkey#modulo-passkey)

#### `passkey_bind_needs_authentication` HTTP 422

**O que aconteceu.** A conta já tem passkey ativa, e vincular outra exige que o flow também peça a passkey atual.

**O que fazer.** Use um flow que vincula a passkey e tem o módulo passkey, para a pessoa entrar com a atual antes.

**O que não fazer.** Não revogue a passkey atual só para vincular outra sem a pessoa pedir.

Veja também: [Aprovação de ato com passkey](https://unifokal.com/docs/modulos/passkey#modulo-passkey)

#### `passkey_bind_needs_reproof` HTTP 422

**O que aconteceu.** A conta já teve passkey, e vincular de novo exige refazer a prova de identidade da pessoa.

**O que fazer.** Use um flow que vincula a passkey com documento, Face Match e Liveness, ou com a reautenticação facial.

**O que não fazer.** Não vincule de novo só com a prova de vida: a nova passkey precisa nascer de uma identidade provada.

Veja também: [Aprovação de ato com passkey](https://unifokal.com/docs/modulos/passkey#modulo-passkey)

#### `unknown_act_key` HTTP 400

**O que aconteceu.** O bloco act trouxe uma chave que não existe. A chave recusada vem nomeada na mensagem.

**O que fazer.** Tire a chave ou corrija o nome dela e mande de novo.

**O que não fazer.** Não trate como aviso: a chamada foi recusada inteira.

Veja também: [Aprovação de ato com passkey](https://unifokal.com/docs/modulos/passkey#modulo-passkey)

#### `act_hostile_char` HTTP 422

**O que aconteceu.** Um texto do bloco act (kind, summary ou counterparty) tem caractere invisível ou de controle, como quebra de linha ou marca de direção do texto.

**O que fazer.** Mande o texto em uma linha só, sem caractere invisível, e mande de novo.

**O que não fazer.** Não troque o caractere por outro parecido: o texto que a pessoa lê precisa ser o que o ato diz.

Veja também: [Aprovação de ato com passkey](https://unifokal.com/docs/modulos/passkey#modulo-passkey)

#### `act_kind_invalid` HTTP 422

**O que aconteceu.** O act.kind veio vazio, acima de 40 caracteres ou com um tipo reservado.

**O que fazer.** Mande um tipo curto do seu próprio vocabulário, como pix_transfer ou change_email.

**O que não fazer.** Não ponha dado pessoal no tipo: ele volta no webhook.

Veja também: [Aprovação de ato com passkey](https://unifokal.com/docs/modulos/passkey#modulo-passkey)

#### `act_summary_invalid` HTTP 422

**O que aconteceu.** O act.summary veio vazio ou acima de 140 caracteres.

**O que fazer.** Escreva o resumo do que a pessoa aprova em uma frase curta e mande de novo.

**O que não fazer.** Não corte o resumo no meio de uma palavra ou de um valor: a pessoa aprova o que lê.

Veja também: [Aprovação de ato com passkey](https://unifokal.com/docs/modulos/passkey#modulo-passkey)

#### `act_counterparty_invalid` HTTP 422

**O que aconteceu.** O act.counterparty veio vazio ou acima de 80 caracteres.

**O que fazer.** Mande o nome do favorecido abreviado, ou tire o campo, que é opcional.

**O que não fazer.** Não mande documento do favorecido no lugar do nome.

Veja também: [Aprovação de ato com passkey](https://unifokal.com/docs/modulos/passkey#modulo-passkey)

#### `act_amount_invalid` HTTP 422

**O que aconteceu.** O act.amount_cents não é um número inteiro de centavos, zero ou maior.

**O que fazer.** Mande o valor em centavos, como número inteiro, junto de currency BRL.

**O que não fazer.** Não mande o valor em reais com casas decimais: o campo é em centavos.

Veja também: [Aprovação de ato com passkey](https://unifokal.com/docs/modulos/passkey#modulo-passkey)

#### `act_currency_invalid` HTTP 422

**O que aconteceu.** A act.currency não é BRL, ou veio sem valor, ou o valor veio sem moeda.

**O que fazer.** Mande amount_cents e currency BRL juntos, ou tire os dois.

**O que não fazer.** Não mande a moeda sozinha: moeda só vale com valor.

Veja também: [Aprovação de ato com passkey](https://unifokal.com/docs/modulos/passkey#modulo-passkey)

### Emissão de link hospedado

Códigos próprios de POST /v1/verification-links. Todo o resto do vocabulário da emissão é o mesmo da criação de sessão.

#### `expires_in_too_long` HTTP 422

**O que aconteceu.** expires_in veio acima do teto de validade do link. O valor é recusado com nome, nunca cortado em silêncio.

**O que fazer.** Mande uma validade dentro do teto e emita um link novo quando ele vencer.

**O que não fazer.** Não prometa ao titular um prazo maior que a validade aceita.

Veja também: [Link de verificação hospedado](https://unifokal.com/docs/api-rest#link-hospedado)

#### `environment_mismatch` HTTP 422

**O que aconteceu.** environment veio diferente do ambiente da chave. O ambiente é a chave.

**O que fazer.** Tire o campo, ou use a chave do ambiente que você quer: sk_test\_ para sandbox, sk_live\_ para produção.

**O que não fazer.** Não tente emitir link de produção com a chave de sandbox.

Veja também: [Link de verificação hospedado](https://unifokal.com/docs/api-rest#link-hospedado)

### Cifra da carga do webhook, no painel

Respostas das telas de chave pública e de cifra por destino, no painel. Não aparecem nas rotas da chave secreta.

#### `encryption_key_missing` HTTP 409

**O que aconteceu.** Você tentou ligar a cifra de um destino sem chave pública ativa no ambiente dele.

**O que fazer.** Registre a chave pública do ambiente no painel e depois ligue a cifra no destino.

**O que não fazer.** Não desligue a cifra para receber em claro sem decidir isso de propósito: um destino com cifra obrigatória nunca recebe em claro.

Veja também: [Webhooks e eventos](https://unifokal.com/docs/webhooks#webhooks)

#### `encryption_key_in_use` HTTP 409

**O que aconteceu.** Você tentou aposentar a única chave ativa enquanto algum destino do ambiente exige a cifra.

**O que fazer.** Registre a chave nova primeiro, confirme que ela abre as entregas, e só então aposente a antiga.

**O que não fazer.** Não desligue a cifra do destino só para conseguir apagar a chave.

Veja também: [Webhooks e eventos](https://unifokal.com/docs/webhooks#webhooks)

#### `invalid_public_key_encoding` HTTP 400

**O que aconteceu.** A chave pública não está em base64 padrão, ou não está na forma canônica.

**O que fazer.** Exporte a chave pública em SPKI DER e codifique em base64 padrão, sem quebras de linha.

**O que não fazer.** Não cole a chave privada: o painel só recebe a pública.

Veja também: [Webhooks e eventos](https://unifokal.com/docs/webhooks#webhooks)

#### `invalid_public_key_format` HTTP 400

**O que aconteceu.** A chave enviada não é o SPKI DER de uma chave X25519 (44 bytes).

**O que fazer.** Gere um par X25519 e envie a parte pública em SPKI DER, em base64.

**O que não fazer.** Não envie chave RSA nem de curva P-256: o envelope usa X25519.

Veja também: [Webhooks e eventos](https://unifokal.com/docs/webhooks#webhooks)

#### `invalid_public_key_small_order` HTTP 400

**O que aconteceu.** A chave pública é um ponto de ordem pequena do X25519, que não serve para cifrar.

**O que fazer.** Gere um par novo com uma biblioteca de criptografia padrão e envie a parte pública.

**O que não fazer.** Não monte a chave à mão nem reaproveite chave de exemplo.

Veja também: [Webhooks e eventos](https://unifokal.com/docs/webhooks#webhooks)
