Inyo

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_id e client_secret para 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.mode tem webhook como padrão. Se você não tiver uma webhook_url configurada, esta chamada retorna 422; 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

CasoPor que importaOnde ler
status é in_reviewNã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ãoUma 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 detalhepassed é 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áginaO que aborda
Sessões de VerificaçãoPré-preenchimento, travamento de tipo de documento, verificações de dados, limites de captura
Entrega do WidgetIncorporação em webview, personalização de marca, localização
Verificação Servidor-a-ServidorUso da sua própria interface de captura em vez do widget
Configuração do TenantLimiares, documentos aceitos e jurisdições
Sandbox e Dados de TesteSimulando resultados approved, declined e in_review