Verificação de Documentos
Para avançar um remetente para níveis de conformidade mais altos (Nível 2 e acima), seus documentos de identidade precisam ser verificados. Há duas formas de fazer isso:
- Sessão de Verificação KYC (recomendado) — crie uma sessão e entregue ao seu usuário a URL de um widget hospedado. O widget captura as fotos do documento e uma selfie, verifica tudo, e o resultado flui automaticamente para o registro do remetente.
- Envio direto de documentos (obsoleto) — envie você mesmo os arquivos de imagem do documento e aguarde a revisão por OCR/manual.
⚠️ Os endpoints de envio direto estão obsoletos. Novas integrações devem usar Sessões de Verificação KYC. As integrações de envio existentes continuam funcionando, mas o fluxo de sessão adiciona prova de vida com selfie, comparação facial com o retrato do documento e defesa contra ataques de apresentação, algo que o simples envio de arquivos não oferece.
Sessões de Verificação KYC (Recomendado)
Endpoint: POST /organizations/{tenant}/v2/senders/{personId}/kycSession
Autenticação: Nível de tenant (x-api-key)
O caminho legado
POST /v2/people/{personId}/kycSessioncontinua funcionando para integrações em migração, mas novas integrações devem usar/v2/senders.
Cria uma sessão de Verificação de Identidade Inyo360 para a pessoa. Você fornece apenas parâmetros de apresentação do widget — o documento a verificar é resolvido automaticamente a partir dos documentos declarados da pessoa, e a sessão é pré-preenchida com os dados do registro (nome, data de nascimento, número do documento, estado emissor, país emissor), de modo que o usuário só precisa capturar o documento e a selfie.
Declare o documento primeiro. A pessoa precisa ter no registro um documento verificável por KYC e não vencido (adicionado via
POST /v2/sendersdocuments[]) antes de abrir uma sessão — caso contrário a requisição retorna422 NO_VERIFIABLE_DOCUMENT.
Corpo da Requisição
Ambos os campos são obrigatórios:
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
language | string | Sim | Idioma do widget, xx ou xx-XX (ex.: en, es, pt-BR) |
redirectUrl | string (URL) | Sim | Para onde enviar o usuário ao concluir o fluxo do widget |
curl --request POST \
--url https://{FQDN}/organizations/$TENANT/v2/senders/$PERSON_ID/kycSession \
--header 'Content-Type: application/json' \
--header "x-api-key: $API_KEY" \
--data '{
"language": "pt-BR",
"redirectUrl": "https://your-app.example/kyc/done"
}'
Como o Documento É Selecionado
A Inyo percorre os documentos declarados da pessoa em ordem de prioridade e verifica o primeiro elegível:
drivers_licensepassport- A família de documentos de identidade, do mais específico ao mais genérico:
dni,cc,cpf,consular_id,voter_id,id
Documentos com data de validade no passado são ignorados (uma pessoa com carteira de motorista vencida e passaporte válido usa o passaporte); documentos sem data de validade registrada são aceitos. ssn, itin e other nunca são selecionados — não correspondem ao vocabulário de documentos do KYC.
A checagem cruzada de dados está sempre ativa: a camada KYC compara os dados extraídos do documento capturado com o registro pré-preenchido da pessoa.
Resposta (201):
{
"sessionId": "9f1c8e42-7c3e-4f2b-9d7a-2b1e5c8f4a10",
"status": "pending",
"widgetUrl": "https://{FQDN}/verify/8Kd2mQ..."
}
O Fluxo
- Crie a sessão e abra a
widgetUrlpara o seu usuário (link, redirecionamento ou webview — veja Entrega do widget). - O usuário fotografa o documento e tira uma selfie no widget.
- A Inyo recebe diretamente o resultado de verificação assinado — você não manipula nenhuma imagem de documento.
- Com um resultado verificado, os registros de documentos da pessoa são criados/atualizados automaticamente com o veredito de verificação, e o webhook
DocumentUpdatedEvents(webhooks) é disparado. - Leia o resultado nesse webhook.
verificationStatuséVERIFIEDquando a sessão foi aprovada,REJECTEDquando foi recusada ePENDINGquando ficou retida para revisão — nesse caso um segundo evento chega depois com a decisão do revisor. Oiddo evento é o id da sessão em ambos, então os dois se correlacionam.
O webhook é o canal mais rápido, e consultar a sessão é o recurso quando uma entrega é perdida. Assinar DocumentUpdatedEvents continua sendo o que torna o fluxo orientado a eventos em vez de baseado em polling. O veredito também é gravado no documento da pessoa como kycVerdict (legível via GET /people/{personId}): VERIFIED para uma sessão aprovada, REJECTED para uma recusada. Uma sessão ainda em revisão deixa o documento exibindo o que a verificação do documento declarado registrou na criação da pessoa — o que não é uma afirmação sobre esta sessão. Leia o webhook para o resultado da própria sessão.
As sessões passam por estes estados no lado da Inyo: PENDING → VERIFIED, REJECTED, PENDING_REVIEW, SUPERSEDED, FAILED ou EXPIRED.
PENDING_REVIEW significa que o resultado não alcançou um veredito automático frente aos limiares de aprovação e recusa configurados para o seu tenant, então fica retido para um revisor da Inyo. É um relato de progresso, não um resultado: um segundo evento chega quando a revisão conclui. Em sandbox toda sessão que alcança um veredito chega aqui, porque lá não há limiares configurados, e ninguém revisa os seus remetentes de teste — então você mesmo resolve cada uma com Resolver uma sessão KYC retida. SUPERSEDED, FAILED e EXPIRED são terminais e não concluem nada sobre o documento — veja Quando uma sessão termina sem veredito. Uma sessão que o remetente não terminou termina em EXPIRED 49 horas após a criação por padrão; o link dela deixa de abrir após 48.
Erros
| HTTP | Erro | Causa |
|---|---|---|
404 | NOT_FOUND | Pessoa não encontrada no seu tenant |
422 | NO_VERIFIABLE_DOCUMENT | A pessoa não tem no registro um documento verificável por KYC e não vencido — declare um via POST /v2/senders (documents[]) primeiro |
422 | VALIDATION_ERROR | language ou redirectUrl ausente ou malformado |
422 | KYC_UNAVAILABLE | A verificação KYC não pôde ser concluída — o serviço estava indisponível, ou o KYC não está configurado para o seu tenant. Repita com backoff; se persistir, contate o suporte da Inyo. |
Consultar uma Sessão de Verificação
Endpoint: GET /organizations/{tenant}/v2/senders/{personId}/kycSession/{sessionId}
Autenticação: Nível de tenant
Consulte uma sessão — o recurso para quando você perde uma entrega de webhook. Você sempre tem o id: ele volta na criação da sessão e acompanha todo DocumentUpdatedEvents como id.
curl --request GET \
--url https://{FQDN}/organizations/$TENANT/v2/senders/$PERSON_ID/kycSession/$SESSION_ID \
--header "x-api-key: $API_KEY"
| Campo | Notas |
|---|---|
sessionId | O mesmo valor que o id de DocumentUpdatedEvents carrega |
status | PENDING, VERIFIED, REJECTED, PENDING_REVIEW, SUPERSEDED, FAILED, EXPIRED ou ORPHANED |
result | O resultado normalizado completo, incluindo checks[]. Nulo até o primeiro resultado chegar, então uma sessão PENDING retorna um status e nenhum resultado. |
completedAt | Nulo enquanto indefinida, e para PENDING_REVIEW — que reporta progresso, não um resultado. Definido para todo estado terminal, inclusive os que não concluíram nada. Este marca quando a verificação chegou ao seu resultado; o completedAt dentro de result, quando presente, é o da sessão KYC, definido quando a avaliação terminou — mesmo enquanto este ainda está nulo durante PENDING_REVIEW. |
createdAt | Quando a sessão foi criada |
widgetUrl | Apenas enquanto a sessão está indefinida. O token está no caminho da URL, então um já gasto não é retornado. |
404 quando o id da sessão é desconhecido, pertence a outra pessoa ou pertence a outra organização.
Legado: Envio Direto de Documentos (Obsoleto)
⚠️ Obsoleto. Use as Sessões de Verificação KYC no lugar. Estes endpoints permanecem disponíveis para integrações existentes. Os documentos enviados são verificados por OCR com IA (quando habilitado para o seu tenant) ou pela equipe de conformidade da Inyo.
Documentos de Identidade
Endpoint: POST /organizations/{tenant}/people/{personId}/documents/documentId/{subtype}/upload
Autenticação: Nível de tenant (x-api-key)
Content-Type: multipart/form-data
O segmento de caminho {subtype} é o tipo do documento. Tanto o formato wire (passport, driversLicense, ...) quanto o formato canônico em maiúsculas (PASSPORT, DRIVERS_LICENSE, ...) são aceitos. O conjunto completo:
| Valor wire | Valor(es) canônico(s) | Descrição |
|---|---|---|
passport | PASSPORT | Passaporte |
driversLicense | DRIVERS_LICENSE | Carteira de motorista |
nationalId | DNI, CC, ID | Documento nacional — DNI (Espanha/Argentina/Peru), CC (cédula da Colômbia) ou documento de identidade genérico |
cpf | CPF | CPF (Brasil) |
consularId | CONSULAR_ID | Identidade consular (matrícula consular) |
voterId | VOTER_ID | Título de eleitor |
ssn | SSN | Cartão de Seguro Social dos EUA |
itin | ITIN | ITIN dos EUA (IRS) |
other | OTHER | Outro documento emitido pelo governo |
As três variantes de documento nacional (
DNI,CC,ID) são agrupadas no único valor wirenationalId, para que os clientes não precisem lidar com nomes específicos por país.
Um subtype desconhecido retorna 422 INVALID_SUBTYPE com a lista allowed na resposta. PROOF_OF_FUNDS deliberadamente não é aceito aqui — use o endpoint dedicado de origem de fundos.
Campos do Formulário
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
file | file | Sim | A imagem do documento — pdf, jpg, jpeg ou png, máx. 10 MB |
idNumber | string | Não | O número impresso no documento |
issuer | string | Não | Autoridade emissora ou estado |
expirationDate | string | Não | Formato YYYY-MM-DD |
curl --request POST \
--url https://{FQDN}/organizations/$TENANT/people/$PERSON_ID/documents/documentId/PASSPORT/upload \
--header "x-api-key: $API_KEY" \
--form "file=@/path/to/passport.jpg" \
--form "idNumber=AB1234567" \
--form "expirationDate=2030-12-31"
Resposta (201):
{
"id": "4ec66735-216b-4ab4-b1d7-00558baa6d85",
"subtype": "PASSPORT",
"fileName": "passport.jpg",
"verificationStatus": "PENDING",
"createdAt": "2026-08-04T12:00:00+00:00",
"idNumber": "AB1234567",
"issuer": null,
"expirationDate": "2030-12-31"
}
Origem dos Fundos
Comprovante da origem dos fundos do remetente (extrato bancário, contracheque), exigido para tiers de conformidade mais altos.
Endpoint: POST /organizations/{tenant}/people/{personId}/documents/sourceOfFunds/upload
Autenticação: Nível de tenant (x-api-key)
Content-Type: multipart/form-data
curl --request POST \
--url https://{FQDN}/organizations/$TENANT/people/$PERSON_ID/documents/sourceOfFunds/upload \
--header "x-api-key: $API_KEY" \
--form "file=@/path/to/bank-statement.pdf"
Mesmas regras de arquivo dos documentos de identidade (pdf/jpg/jpeg/png, máx. 10 MB). O envio é armazenado sob o tipo PROOF_OF_FUNDS.
O envio chega como PENDING e é verificado pelo OCR com IA onde estiver habilitado, ou pela equipe de conformidade da Inyo. Até ser verificado não conta para nenhum nível de conformidade. Em sandbox nenhuma das duas coisas acontece sozinha — resolva você mesmo com Resolver uma revisão de documento pendente.
Status de Verificação de Documentos
Após o envio, os documentos são verificados de forma assíncrona — por OCR com IA (se habilitado para o seu tenant) em minutos, ou então pela equipe de conformidade.
Estes endpoints cobrem apenas documentos enviados por upload. Eles resolvem
{documentId}como um upload, então um documento verificado por uma sessão de verificação KYC não tem registro aqui e as duas rotas retornam404. Leia o resultado de uma sessão no webhookDocumentUpdatedEvents, e o veredito resultante emkycVerdictno documento da pessoa.
Consultar o Status de Verificação Atual
Endpoint: GET /organizations/{tenant}/documents/{documentId}/verificationStatus/current
Autenticação: Nível de tenant
curl --request GET \
--url https://{FQDN}/organizations/$TENANT/documents/$DOCUMENT_ID/verificationStatus/current \
--header "x-api-key: $API_KEY"
Consultar o Histórico de Status de Verificação
Endpoint: GET /organizations/{tenant}/documents/{documentId}/verificationStatus
Autenticação: Nível de tenant
curl --request GET \
--url https://{FQDN}/organizations/$TENANT/documents/$DOCUMENT_ID/verificationStatus \
--header "x-api-key: $API_KEY"
Retorna entradas com status, reason, verifiedBy e createdAt — o campo reason explica as rejeições, para que você possa orientar o usuário a reenviar.
Listar os Documentos de uma Pessoa
Lista uploads, então uma pessoa cujos documentos foram todos verificados por sessões KYC retorna um array vazio. Os documentos declarados e seus vereditos estão no registro da pessoa.
Endpoint: GET /organizations/{tenant}/people/{personId}/documents
Autenticação: Nível de tenant
curl --request GET \
--url https://{FQDN}/organizations/$TENANT/people/$PERSON_ID/documents \
--header "x-api-key: $API_KEY"
Status de Verificação
| Status | Descrição |
|---|---|
PENDING | Documento enviado, aguardando verificação |
VERIFIED | Documento aceito — o nível de conformidade pode ser elevado |
REJECTED | Documento rejeitado — verifique o reason e reenvie |
Notificações por Webhook
Registre-se no webhook DocumentUpdatedEvents para ser notificado quando o status de verificação de um documento mudar — um evento no envio (PENDING) e outro quando a verificação for concluída (VERIFIED/REJECTED). Veja Webhooks para a referência do payload.
Boas Práticas
- Envie imagens de alta qualidade — imagens borradas ou cortadas serão rejeitadas.
- Passe
idNumbereexpirationDatequando os tiver — eles enriquecem o registro de conformidade e aceleram a análise. - Verifique o nível de conformidade após a verificação — quando um documento estiver
VERIFIED, chameGET /participants/{id}/complianceLevelspara ver se o remetente foi elevado de nível. - Trate rejeições com cuidado — exiba o
reasonda rejeição e solicite ao usuário que reenvie. - Use webhooks em vez de polling — registre-se em
DocumentUpdatedEventspara ser notificado imediatamente.
Dados de Teste
Para testes em sandbox, veja Testes em Sandbox — números de documento reservados que ditam um resultado de verificação, um endpoint para resolver uma sessão retida, e os valores do remetente sobre os quais a rede de payout age.
