Primeiros Passos
Este guia conduz você por uma verificação de identidade completa no sandbox da Inyo. Ao final, você terá criado uma sessão, verificado um documento e uma selfie por meio do widget hospedado e recebido um resultado assinado no seu próprio endpoint.
Pré-requisitos
- Credenciais de sandbox emitidas pela Inyo durante o onboarding:
client_ideclient_secretpara o grant client-credentials- Sua URL base de sandbox e a confirmação de que suas faixas de IP de saída estão na lista de permissões
- Um
webhook_secret— usado para verificar a assinatura dos resultados entregues
- Um endpoint de webhook, acessível publicamente via HTTPS, registrado na Inyo como sua
webhook_url. Durante o desenvolvimento, um túnel (ngrok, Cloudflare Tunnel) funciona; alternativamente, use a entrega por redirecionamento e dispense o webhook por completo. - Um celular com câmera para o widget. O acesso à câmera exige um contexto seguro, então abra o widget via HTTPS — navegadores desktop também funcionam.
- Um cliente REST (cURL, Postman ou similar).
Ainda não tem credenciais? Entre em contato com nossa equipe de vendas para solicitar acesso ao sandbox.
Etapa 1: Obtenha um Token de Acesso
curl --request POST \
--url https://{FQDN}/oauth/token \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data grant_type=client_credentials \
--data client_id=$KYC_CLIENT_ID \
--data client_secret=$KYC_CLIENT_SECRET
{
"access_token": "eyJhbGciOiJSUzI1NiIs…",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "sessions verifications"
}
Armazene o access_token e reutilize-o até expirar — consulte Autenticação para o tratamento de renovação.
Etapa 2: Crie uma Sessão de Verificação
user_ref é o seu próprio identificador para a pessoa que está sendo verificada. Ele é devolvido em todos os resultados, então use o identificador pelo qual seu sistema já referencia os usuários.
curl --request POST \
--url https://{FQDN}/v1/sessions \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header 'Content-Type: application/json' \
--data '{
"user_ref": "user-123",
"language": "en",
"delivery": { "mode": "webhook" }
}'
{
"session_id": "9f1c8e42-7c3e-4f2b-9d7a-2b1e5c8f4a10",
"status": "pending",
"widget_url": "https://{FQDN}/verify/8Kd2mQ…"
}
Persista o session_id associado ao seu usuário agora — é assim que você correlacionará o resultado recebido.
delivery.modetemwebhookcomo padrão. Se você não tiver umawebhook_urlconfigurada, esta chamada retorna422; use{"mode": "redirect", "redirect_url": "https://you.example/kyc-done"}no lugar.
Etapa 3: Envie o Cliente para o Widget
Abra a widget_url no navegador do cliente ou em uma webview nativa, ou entregue-a por SMS ou e-mail. O link contém um código de uso único e é válido por 48 horas.
O cliente seleciona um tipo de documento, fotografa o documento, tira uma selfie e vê o resultado. Você não escreve nenhum código de câmera — consulte Entrega do Widget para detalhes de webview e personalização de marca.
Etapa 4: Receba o Resultado Assinado
Quando a verificação termina, a Inyo faz um POST do resultado para sua webhook_url com um cabeçalho X-Inyo-Signature:
POST /kyc-result HTTP/1.1 Content-Type: application/json X-Inyo-Signature: 4c1f9a…
{
"session_id": "9f1c8e42-7c3e-4f2b-9d7a-2b1e5c8f4a10",
"user_ref": "user-123",
"status": "approved",
"auto_status": "approved",
"document": {
"type": "Passport",
"number": "A12345678",
"issuing_state": "USA",
"issuing_country": "USA",
"expiration_date": "2033-09-30"
},
"person": {
"first_name": "ALEX",
"last_name": "MORGAN",
"date_of_birth": "1988-03-04",
"nationality": "USA"
},
"checks": [
{ "name": "document_readable", "passed": true, "score": null, "detail": "all core fields extracted" },
{ "name": "mrz_valid", "passed": true, "score": null, "detail": "all check digits valid" },
{ "name": "document_not_expired", "passed": true, "score": null, "detail": "expiration_date 2033-09-30" },
{ "name": "face_match", "passed": true, "score": 98.7, "detail": "CompareFaces similarity vs threshold 90.0" }
],
"prefill_mismatches": [],
"provider": "inyo"
}
Verifique a assinatura antes de confiar no payload. Ela é um HMAC-SHA256 dos bytes brutos do corpo da requisição, com sua webhook_secret como chave:
import crypto from "node:crypto";
const expected = crypto
.createHmac("sha256", process.env.KYC_WEBHOOK_SECRET)
.update(rawBody) // bytes brutos, antes do JSON.parse
.digest("hex");
const signature = req.headers["x-inyo-signature"];
const valid =
signature &&
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
Fazer o parse do corpo e serializá-lo novamente altera espaços em branco e a ordem das chaves e vai quebrar a assinatura. Detalhes completos, incluindo o modo de redirecionamento, estão em Recebendo Resultados.
Responda com 2xx para confirmar o recebimento. A Inyo tenta novamente até três vezes com backoff e então para.
Etapa 5: Confirme no Lado do Servidor
GET /v1/sessions/{session_id} é o registro autoritativo. Use-o para reconciliar, para recuperar um webhook perdido ou sempre que precisar de certeza em vez de um push:
curl --request GET \
--url https://{FQDN}/v1/sessions/$SESSION_ID \
--header "Authorization: Bearer $ACCESS_TOKEN"
{
"session_id": "9f1c8e42-7c3e-4f2b-9d7a-2b1e5c8f4a10",
"user_ref": "user-123",
"status": "approved",
"step": "done",
"delivery_mode": "webhook",
"result": { "…": "the same normalized result" },
"created_at": "2026-07-31T14:02:11.481Z",
"updated_at": "2026-07-31T14:04:57.902Z"
}
Trate Estes Três Casos Antes de Entrar em Produção
| Caso | Por que importa | Onde ler |
|---|---|---|
status é in_review | Não é uma resposta final — um humano decide e você é notificado depois. Pode chegar por webhook e em um redirecionamento. | Revisão Manual |
| Dois resultados para uma sessão | Uma decisão de analista ou uma reversão de controle de qualidade reenvia o resultado. Aplique o maior notified_at, não a chegada mais recente. | Recebendo Resultados |
| Uma verificação falhou, mas você quer o detalhe | passed é o resultado; os limiares por tenant são citados no detail de cada verificação. Nunca condicione decisões ao score de ai_authenticity. | Verificações e Decisões |
Próximos Passos
| Página | O que aborda |
|---|---|
| Sessões de Verificação | Pré-preenchimento, travamento de tipo de documento, verificações de dados, limites de captura |
| Entrega do Widget | Incorporação em webview, personalização de marca, localização |
| Verificação Servidor-a-Servidor | Uso da sua própria interface de captura em vez do widget |
| Configuração do Tenant | Limiares, documentos aceitos e jurisdições |
| Sandbox e Dados de Teste | Simulando resultados approved, declined e in_review |
