Fluxo de KYC
Verifique a identidade do usuário com a Sumsub antes que ele transacione — geração de link, callbacks de status e o que cada resultado de KYC significa.
Fluxo de KYC
Todo usuário final BlendFi precisa completar a verificação de identidade antes de movimentar dinheiro. Isso é uma exigência regulatória — sem um KYC approved, tentativas de criar uma cotação ou transação retornam 403 missing_capability para o usuário. A BlendFi cuida do KYC pela Sumsub; você não fala diretamente com a Sumsub.
Como tudo se encaixa
Seu app BlendFi Sumsub
│ │ │
├─ POST /v1/users ─────►│ │
│◄──── usuário criado ──┤ │
│ (kyc: not_started) │ │
│ │ │
├─ POST /v1/users/{id}/kyc ─► │
│ ├── cria applicant ──────►│
│ │◄──── id do applicant ───┤
│ ├── gera link websdk ────►│
│ │◄──── url assinada ──────┤
│◄── submissão de kyc ──┤ │
│ (kyc: pending, │ │
│ websdk_url) │ │
│ │ │
├─ redireciona usuário final para websdk_url ─────►
│ │ (usuário envia docs) │
│ │◄────── webhook ─────────┤
│ │ (resultado da revisão) │
│◄── webhook pra você ──┤ │
│ (kyc: approved) │ │Você só chama a BlendFi. A BlendFi chama a Sumsub por você e reflete os resultados de volta.
Cinco resultados
`not_started`
Usuário existe. A submissão de KYC ainda não foi iniciada. Não pode transacionar.
`pending`
Link WebSDK entregue. A Sumsub está revisando os documentos e a selfie. Não pode transacionar.
`approved`
Usuário passou no KYC. Pode transacionar. Validade padrão é 12 meses; renovamos no vencimento.
`rejected`
A Sumsub rejeitou os documentos. Usuário não pode transacionar. Tem que reenviar (uma submissão nova volta para `pending`).
`expired`
Um KYC `approved` ultrapassou a janela de validade. Usuário precisa verificar de novo antes de transacionar.
O caminho completo
1. Crie o usuário
curl -X POST $BLENDFI_BASE/v1/users \
-H "Authorization: Bearer $BLENDFI_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "content-type: application/json" \
-d '{
"external_id": "seu-usuario-001",
"name": "Ada Lovelace",
"cpf": "52998224725"
}'O usuário é criado com kyc_status: not_started. O CPF é armazenado criptografado; nunca devolvemos em texto puro.
2. Inicie a submissão de KYC
Essa chamada gera uma URL assinada do WebSDK da Sumsub. É seguro expor para seu usuário final (uso único, TTL curto — geralmente 30 minutos).
curl -X POST $BLENDFI_BASE/v1/users/01J.../kyc \
-H "Authorization: Bearer $BLENDFI_KEY" \
-H "Idempotency-Key: $(uuidgen)"Resposta:
{
"user_id": "01J...",
"status": "pending",
"websdk_url": "https://websdk.sumsub.com/start/eyJ...",
"websdk_url_expires_at": "2026-04-29T13:30:00Z"
}O kyc_status do usuário muda para pending imediatamente, antes mesmo dos documentos serem enviados. Esse é o estado de "tem uma submissão em andamento".
Tempo de vida do link WebSDK
O websdk_url é válido até websdk_url_expires_at. Se o usuário final não abrir a tempo, chame POST /v1/users/{id}/kyc de novo para pegar um link novo. O estado da submissão de KYC continua em pending mesmo gerando link novo — você não perde progresso.
3. Redirecione o usuário final para o WebSDK
Abra websdk_url numa aba do navegador, num iframe ou numa webview mobile. A Sumsub guia o usuário pela captura de documentos (CPF + documento de identidade + selfie) e fecha o fluxo.
O usuário não volta pra você com um status — a Sumsub não conhece suas URLs. Você descobre o resultado por webhook (próximo passo) ou fazendo polling em GET /v1/users/{id}/kyc.
4. Receba o resultado por webhook
Quando a Sumsub termina a revisão, ela avisa a BlendFi. A BlendFi atualiza o kyc_status do usuário e encaminha um webhook para sua URL registrada.
{
"type": "user.kyc.approved",
"user_id": "01J...",
"external_id": "seu-usuario-001",
"kyc_status": "approved",
"approved_at": "2026-04-29T13:08:00Z",
"expires_at": "2027-04-29T13:08:00Z"
}Tipos de evento possíveis: user.kyc.approved, user.kyc.rejected, user.kyc.expired. Não tem evento para pending — esse é o estado quando a submissão começa.
Se você ainda não tem webhooks ligados, faça polling como fallback:
curl $BLENDFI_BASE/v1/users/01J.../kyc \
-H "Authorization: Bearer $BLENDFI_KEY"{
"user_id": "01J...",
"status": "approved",
"approved_at": "2026-04-29T13:08:00Z",
"expires_at": "2027-04-29T13:08:00Z"
}5. Transacione
Com kyc_status: approved, o usuário pode ser sujeito de uma cotação, transação ou qualquer outro endpoint que movimenta dinheiro. Antes disso, esses endpoints respondem com um erro claro apontando de volta para o passo do KYC.
Forçando resultados de KYC no sandbox
O sandbox usa um espelho da Sumsub. Para evitar esperar uma revisão de documento real, use o test helper para forçar qualquer resultado:
curl -X POST $BLENDFI_BASE/v1/test_helpers/users/01J.../kyc \
-H "Authorization: Bearer $BLENDFI_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "content-type: application/json" \
-d '{"status": "approved"}'Valores aceitáveis: "approved", "rejected", "expired". O webhook é disparado exatamente como seria em produção, então sua lógica de handler é exercitada de ponta a ponta.
Apenas no sandbox
/v1/test_helpers/* não existe em produção — chamadas retornam 404. Garanta que seus caminhos de código que forçam resultados de KYC estejam marcados como test-only e nunca rodem contra api.blendfi.com.
Renovação e expiração
KYCs aprovados valem por 12 meses por padrão. A gente monitora a expiração e move o usuário para kyc_status: expired no dia do limite. Você recebe um webhook user.kyc.expired 7 dias antes da expiração para conseguir avisar o usuário a verificar de novo com antecedência.
Uma reverificação é uma chamada POST /v1/users/{id}/kyc nova — o usuário passa pelo mesmo fluxo do WebSDK de novo. Não tem endpoint separado de "renovação".
Rejeições
Um resultado rejected inclui um rejection_reason:
{
"user_id": "01J...",
"status": "rejected",
"rejected_at": "2026-04-29T13:08:00Z",
"rejection_reason": "document_unreadable"
}Razões comuns:
rejection_reason | O que aconteceu | O que dizer ao usuário |
|---|---|---|
document_unreadable | Fotos muito borradas, com reflexo ou cortadas | Refazer com luz melhor, documento inteiro no enquadramento |
document_expired | O documento enviado está fora da validade | Enviar um documento atual |
liveness_failed | A selfie não bateu com o documento ou era foto de foto | Tentar de novo com o rosto real do usuário na câmera |
pep_match | O usuário bateu numa lista de pessoas politicamente expostas | A gente escala; você ouve da gente |
sanctions_match | O usuário bateu numa lista de sanções | O usuário não pode ser onboardado |
data_mismatch | Os dados do documento não batem com o CPF / nome no nosso sistema | Verifique seus inputs de external_id, name, cpf |
Um usuário rejected pode reenviar (POST /v1/users/{id}/kyc de novo). A submissão nova substitui a rejeição; o status volta para pending.
pep_match e sanctions_match são terminais no nosso fluxo — reenvio não resolve. A gente trata caso a caso com você.
O que ler em seguida
Primeiros passos
Crie seu primeiro usuário. O KYC começa logo depois disso.
Ciclo de vida da transação
Um KYC aprovado é pré-requisito de cada passo do ciclo de vida. Veja como uma falha `kyc_blocked` se propaga.
Erros e retentativas
Como aparece o `403 missing_capability` quando um usuário com `kyc_status: pending` tenta transacionar.
FAQ
O mesmo usuário final pode reenviar se for rejeitado?
Pode — para a maioria das razões de rejeição. Chame POST /v1/users/{id}/kyc de novo para pegar um link novo do WebSDK; o usuário passa pelo fluxo de novo. Os dois casos terminais são pep_match e sanctions_match — esses exigem revisão humana do nosso lado.
O que acontece se o usuário fechar o WebSDK no meio?
O kyc_status dele continua pending. O WebSDK guarda o estado parcial por uns 24 horas; se ele reabrir o mesmo link nessa janela, retoma de onde parou. Após a expiração, gere um link novo.
Eu preciso verificar a assinatura do webhook?
Precisa. Webhooks de produção da BlendFi carregam um cabeçalho X-BlendFi-Signature (HMAC-SHA-256 sobre o corpo, com um segredo por organização). Rejeite qualquer webhook cuja assinatura não bata. A gente fornece snippets de verificação na referência de webhooks.
Por que o estado not_started existe se eu sempre inicio o KYC logo após criar o usuário?
Algumas integrações criam usuários cedo (cadastro de waitlist, por exemplo) e só disparam o KYC quando o usuário faz uma ação relevante de dinheiro. O formato em dois passos suporta esse padrão. Se você sempre inicia o KYC na hora, trate not_started como um estado transiente que sua UI nunca exibe.
Posso ver as imagens dos documentos rejeitados? Não. A Sumsub guarda os documentos; a BlendFi só vê o veredicto e a razão da rejeição. Isso é uma fronteira de privacidade por design.
O usuário passou no KYC em outro produto que eu opero — posso pular o KYC da BlendFi para ele? Não. A gente reverifica por organização BlendFi, independente de o mesmo usuário final ter sido verificado em outro lugar. Isso é uma exigência regulatória.
Idempotência
Torne seus POSTs e PATCHes seguros para retentativas — sem usuários duplicados, sem cobrança em dobro, mesmo quando a rede cai no meio da chamada.
Ciclo de vida da transação
Da cotação até a liquidação — todo estado que uma transação BlendFi pode estar, as transições legais entre eles e como reagir a cada um.
