Sua primeira requisição

Passo a passo completo — crie uma requisição, envie os documentos pelo servidor, submeta-a e trate o webhook.

O Início rápido usou uma sessão hospedada porque é o caminho mais simples. Esta página mostra a alternativa: coletar os documentos na sua própria interface e enviá-los de servidor para servidor. Escolha essa abordagem quando quiser controle total sobre a experiência do solicitante ou quando já tiver as imagens dos documentos armazenadas.

O ciclo de vida

stateDiagram-v2
  [*] --> PENDING_UPLOAD: POST /requests
  PENDING_UPLOAD --> PENDING_UPLOAD: POST /documents (each upload)
  PENDING_UPLOAD --> PROCESSING: POST /submit
  PROCESSING --> APPROVED: auto-decision: approve
  PROCESSING --> REJECTED: auto-decision: reject
  PROCESSING --> ESCALATED: auto-decision: escalate
  ESCALATED --> APPROVED: POST /decision (human)
  ESCALATED --> REJECTED: POST /decision (human)
  REJECTED --> PENDING_UPLOAD: POST /resubmit
  APPROVED --> [*]

Cada transição de estado emite um webhook. Na maioria das integrações, você só precisa agir nos estados PROCESSING, APPROVED, REJECTED e ESCALATED.

Etapa 1 — Criar a requisição

curl -X POST https://app.certivant.com/api/v1/kyc/requests \
  -H "Authorization: Bearer ck_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "type": "INDIVIDUAL",
    "externalRef": "user-9281",
    "applicant": {
      "fullName": "Alex Singh",
      "dateOfBirth": "1988-11-03",
      "nationality": "GB",
      "email": "alex@example.com",
      "phone": "+447700900100",
      "emailVerified": true,
      "phoneVerified": false
    }
  }'

Resposta (201):

{
  "id": "req_01J0...",
  "status": "PENDING_UPLOAD",
  "pendingDocTypes": ["GOVERNMENT_ID", "SELFIE"],
  "applicant": { "fullName": "Alex Singh", ... },
  "createdAt": "..."
}

pendingDocTypes indica quais documentos esta verificação ainda precisa. A lista é atualizada a cada envio — quando ficar vazia, a requisição está pronta para ser submetida.

Etapa 2 — Enviar os documentos

Cada envio de documento é um POST separado em multipart/form-data. Passe documentType (e side para documentos de dois lados, como a carteira de motorista) como parâmetros de consulta, e o arquivo em um campo chamado file.

# Front of an ID card
curl -X POST "https://app.certivant.com/api/v1/kyc/requests/req_01J0.../documents?documentType=GOVERNMENT_ID&side=front" \
  -H "Authorization: Bearer ck_live_..." \
  -F "file=@/path/to/id-front.jpg"

# Back of the same ID card
curl -X POST "https://app.certivant.com/api/v1/kyc/requests/req_01J0.../documents?documentType=GOVERNMENT_ID&side=back" \
  -H "Authorization: Bearer ck_live_..." \
  -F "file=@/path/to/id-back.jpg"

# Selfie
curl -X POST "https://app.certivant.com/api/v1/kyc/requests/req_01J0.../documents?documentType=SELFIE" \
  -H "Authorization: Bearer ck_live_..." \
  -F "file=@/path/to/selfie.jpg"

Restrições:

  • Tamanho do arquivo: 10 MB no máximo por arquivo.
  • Tipos MIME: image/jpeg, image/png, image/webp, application/pdf.
  • side é obrigatório para GOVERNMENT_ID e aceito para qualquer documento que tenha dois lados; omita-o para SELFIE, PROOF_OF_ADDRESS etc.

Cada envio retorna o status atualizado da requisição:

{
  "id": "doc_01J1...",
  "documentType": "GOVERNMENT_ID",
  "side": "front",
  "status": "pending",
  "requestStatus": "PENDING_UPLOAD",
  "pendingDocTypes": ["SELFIE"],
  "fileSize": 412938,
  "mimeType": "image/jpeg"
}

Quando pendingDocTypes estiver vazio, você está pronto para submeter.

Etapa 3 — Enviar para processamento

Verifique primeiro o e-mail e o telefone. A verificação de e-mail e telefone faz parte das checagens. Se a sua organização exigir isso (em Configurações de KYC/B), confirme que cada canal exigido está verificado antes de submeter — seja definindo emailVerified / phoneVerified: true na criação (como na etapa 1, quando você mesmo já os validou), seja fazendo com que o solicitante conclua o código de e-mail/telefone em uma sessão hospedada. Um canal exigido não verificado reprova a checagem de contato durante o processamento.

curl -X POST https://app.certivant.com/api/v1/kyc/requests/req_01J0.../submit \
  -H "Authorization: Bearer ck_live_..."

Resposta:

{ "id": "req_01J0...", "status": "PROCESSING", "message": "..." }

A requisição passa para PROCESSING. O mecanismo de risco da Certivant executa verificações de autenticidade do documento, OCR, comparação facial (se você tiver enviado uma selfie), prova de vida, triagem de sanções e quaisquer regras personalizadas configuradas pela sua organização. Isso normalmente termina em poucos segundos.

Não faça polling para obter o resultado. Configure um webhook (veja a etapa 4) — é assim que a Certivant informa que a requisição foi concluída. O polling consome o limite de requisições e aumenta a latência.

Etapa 4 — Receber o webhook

Configure um endpoint de webhook em KYC → Configurações → Webhooks no painel. Sempre que a requisição mudar de estado, a Certivant enviará um POST para a sua URL:

{
  "event": "kyc.request.approved",
  "requestId": "req_01J0...",
  "organizationId": "org_01H...",
  "externalRef": "user-9281",
  "status": "APPROVED",
  "timestamp": "2026-05-27T10:04:21.000Z",
  "data": {
    "score": 94,
    "decision": "approve",
    "extracted": {
      "fullName": "Alex Singh",
      "dateOfBirth": "1988-11-03",
      "documentNumber": "GBR-1234567"
    },
    "liveness": { "isLive": true, "confidence": 0.98 },
    "faceMatch": { "isMatch": true, "confidence": 0.91 }
  }
}

Valide o cabeçalho X-Certivant-Signature-V2 (veja Verificação de assinatura), localize o registro no seu banco de dados pelo externalRef e prossiga.

Etapa 5 — Tratar encaminhamento para revisão e rejeição

Nem toda requisição é aprovada de forma limpa. Os dois resultados para os quais você precisa se preparar são:

kyc.request.escalated

O mecanismo automatizado não teve confiança suficiente — geralmente porque o documento tinha baixa qualidade, a comparação facial ficou no limite ou um resultado de sanções precisa de uma análise humana. Um revisor da sua organização abre a requisição no painel e decide. Você não precisa fazer nada; a decisão final dispara outro webhook (kyc.request.approved ou kyc.request.rejected).

Você pode emitir a decisão de forma programática com o escopo kyc:manage:

curl -X POST https://app.certivant.com/api/v1/kyc/requests/req_01J0.../decision \
  -H "Authorization: Bearer ck_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "decision": "APPROVED", "note": "Confirmed against internal CRM record" }'

kyc.request.rejected

O solicitante não passou nas checagens — documento vencido, resultado de sanções, falha na prova de vida etc. Veja data.factors e data.disqualifiers no payload do webhook para entender o motivo. Você pode permitir que o solicitante tente novamente, reenviando a requisição:

curl -X POST https://app.certivant.com/api/v1/kyc/requests/req_01J0.../resubmit \
  -H "Authorization: Bearer ck_live_..."

Isso redefine a requisição para PENDING_UPLOAD e limpa os documentos anteriores. Em seguida, o solicitante pode enviar os documentos novamente (ou usar uma nova URL de sessão hospedada), e você pode submeter outra vez.

O que construir em seguida

  • Conecte o manipulador de webhook à sua fila de tarefas em segundo plano, para que você possa repetir o seu próprio trabalho posterior caso ele falhe.
  • Armazene os campos data.extracted no registro do seu usuário — nome, data de nascimento, número do documento — e evite pedir essas informações novamente.
  • Adicione, no seu próprio produto, uma visão administrativa que leve ao painel da Certivant para qualquer requisição que a sua equipe precise inspecionar.

Para a referência completa dos endpoints e os casos extremos, veja Requisições de KYC.