Skip to main content

Onboarding KYC 100% via API

O link de onboarding é o caminho mais curto: você cria o onboarding e o seu cliente preenche tudo numa página hospedada pela Woovi. Quando você já tem o seu próprio funil — coleta os documentos, a selfie e os dados dos sócios dentro do seu produto — dá para fazer o onboarding inteiro pela API, sem que o cliente final veja nenhuma tela da Woovi.

Esta página descreve esse fluxo de ponta a ponta. Todos os endpoints endereçam o cadastro pelo mesmo correlationID que você enviou ao criar o onboarding.

Pré-requisitos
Link hospedado100% via API
Quem coleta documentos e selfieA Woovi, na página do linkVocê, no seu produto
Esforço de integraçãoUma chamada + webhooksUm endpoint por passo + upload de arquivos
Pix de autenticação e BC Protege+O link conduz o clienteVocê mostra o QR Code e orienta o cliente
Envio para análiseO cliente clica em enviarVocê chama POST /api/v1/kyc/onboarding/submit
RFI (pedido de documentos)O cliente responde no linkVocê responde pela API ou envia o link da RFI

Os dois caminhos gravam no mesmo cadastro e passam pelas mesmas validações, então dá para misturar: criar pela API, enviar os documentos que você já tem e mandar o link só para o que faltar. Na dúvida, comece pelo link; migre para a API quando a experiência dentro do seu produto justificar.

Visão geral

Escopos

EndpointEscopo
POST /api/v1/kyc/onboardingKYC_ONBOARDING_POST
POST /api/v1/filesFILE_POST
GET /api/v1/kyc/documentsKYC_DOCUMENTS_GET
POST /api/v1/kyc/documentsKYC_DOCUMENTS_POST
GET /api/v1/kyc/representativesKYC_REPRESENTATIVES_GET
POST /api/v1/kyc/representatives e /representatives/documentsKYC_REPRESENTATIVES_POST
POST /api/v1/kyc/pix-authenticationKYC_PIX_AUTHENTICATION_POST
GET /api/v1/kyc/pix-authentication/{id}KYC_PIX_AUTHENTICATION_GET
GET /api/v1/kyc/bc-protectionKYC_BC_PROTECTION_GET
POST /api/v1/kyc/bc-protection/resendKYC_BC_PROTECTION_POST
POST /api/v1/kyc/onboarding/submitKYC_ONBOARDING_SUBMIT_POST
GET /api/v1/kyc/rfiKYC_RFI_GET
POST /api/v1/kyc/rfiKYC_RFI_POST

Sem o escopo, a chamada responde 403.

Status do cadastro

StatusO que significaO que a API aceita
DRAFT / PENDINGAguardando você (ou o cliente)Tudo: documentos, sócios, Pix, BC Protege+, submit
IN_REVIEWEm análise na WooviSó leitura, exceto enquanto houver RFI aberta
APPROVEDConta aprovada e provisionadaSó leitura
REJECTEDReprovadoSó leitura

IN_REVIEW não é final: a análise pode abrir uma RFI ou devolver o cadastro para PENDING. Veja Como acompanhar o onboarding em tempo real por webhooks.

1. Criar o onboarding

curl -X POST https://api.woovi.com/api/v1/kyc/onboarding \
-H "Authorization: <APP_ID>" \
-H "Content-Type: application/json" \
-d '{
"taxID": "11.222.333/0001-81",
"correlationID": "merchant-4417",
"businessDescription": "Venda de roupas e acessorios pela internet",
"website": "https://loja-do-merchant.com.br"
}'

O cadastro nasce em PENDING, já com os sócios encontrados no CNPJ (source: ENRICHMENT). A chamada é idempotente por correlationID: repetir devolve o mesmo cadastro (200). Os campos estão em Como criar um onboarding KYC via API?.

A partir daqui, todo endpoint recebe correlationID (no body ou na query). O CNPJ do cadastro também é aceito no lugar dele.

2. Subir os arquivos e obter o fileId

Nenhum endpoint de KYC recebe o arquivo em si. Primeiro você sobe cada arquivo no endpoint de arquivos com purpose=ACCOUNT_REGISTER_DOCUMENT; depois envia o id devolvido como fileId.

curl -X POST https://api.woovi.com/api/v1/files \
-H "Authorization: <APP_ID>" \
-F "purpose=ACCOUNT_REGISTER_DOCUMENT" \
-F "correlationID=merchant-4417-contrato-social"
{
"file": {
"id": "6712c2ac7c2f1e0012a4b8d1",
"purpose": "ACCOUNT_REGISTER_DOCUMENT",
"fileName": "contrato-social.pdf",
"contentType": "application/pdf"
}
}
Regras do fileId
  • O arquivo precisa ter sido enviado pela mesma empresa do AppID e com purpose ACCOUNT_REGISTER_DOCUMENT. Arquivo de outra empresa ou de outro purpose responde como não encontrado (400).
  • Formatos aceitos: PDF, PNG, JPEG e WEBP, até 10 MiB. HEIC não é aceito.
  • Um mesmo fileId não pode aparecer duas vezes na mesma requisição.
  • Todos os fileId são resolvidos antes de gravar: se um falhar, nada da requisição é gravado.

3. Documentos da empresa

curl -X POST https://api.woovi.com/api/v1/kyc/documents \
-H "Authorization: <APP_ID>" \
-H "Content-Type: application/json" \
-d '{
"correlationID": "merchant-4417",
"documents": [
{ "type": "SOCIAL_CONTRACT", "fileId": "6712c2ac7c2f1e0012a4b8d1" }
]
}'

Tipos aceitos: SOCIAL_CONTRACT, CCMEI, ATA, BYLAWS, BETS_LICENSE, BANK_STATEMENT, FINANCIAL_CAPACITY_PROOF, BILLING_PROOF, COMPANY_ADDRESS_PROOF. De 1 a 10 por chamada.

A resposta 201 lista todos os documentos da empresa (com url de download válida por 5 minutos) e requestDocuments, os tipos que a análise ainda espera. GET /api/v1/kyc/documents?correlationID=merchant-4417 devolve o mesmo formato.

4. Sócios e representantes

Liste os sócios que já vieram do CNPJ e guarde o id de cada um — é por ele, nunca pelo CPF, que os outros endpoints endereçam um sócio (um CPF pode aparecer duas vezes quando um sócio foi desativado e substituído).

curl "https://api.woovi.com/api/v1/kyc/representatives?correlationID=merchant-4417" \
-H "Authorization: <APP_ID>"

Para adicionar um sócio (só enquanto o cadastro estiver DRAFT/PENDING), já com os documentos:

curl -X POST https://api.woovi.com/api/v1/kyc/representatives \
-H "Authorization: <APP_ID>" \
-H "Content-Type: application/json" \
-d '{
"correlationID": "merchant-4417",
"name": "MARIA DE SOUZA",
"taxID": "529.982.247-25",
"type": "ADMIN",
"birthDate": "1985-03-14",
"email": "[email protected]",
"phone": "+5511999999999",
"documents": [
{ "type": "CNH", "fileId": "6712c2ac7c2f1e0012a4b8d2" },
{ "type": "PICTURE", "fileId": "6712c2ac7c2f1e0012a4b8d3" }
]
}'
  • type: ADMIN (padrão) é o administrador: deve a autenticação Pix, a liberação do BC Protege+, a selfie e um documento de identidade. REPRESENTATIVE não.
  • CPF já ativo no cadastro → 409 REPRESENTATIVE_ALREADY_REGISTERED. CPF de um sócio desativado → a linha é reativada (200, reactivated: true). MEI tem um único titular (409 MEI_SINGLE_OWNER).
  • Um arquivo reprovado pela checagem de qualidade (ilegível, cortado) volta em rejectedDocuments e pode ser reenviado.

Para enviar documentos de um sócio que já existe (por exemplo, os que vieram do CNPJ):

curl -X POST https://api.woovi.com/api/v1/kyc/representatives/documents \
-H "Authorization: <APP_ID>" \
-H "Content-Type: application/json" \
-d '{
"correlationID": "merchant-4417",
"representativeId": "6721f0b3c1d4e80012a4f9aa",
"documents": [
{ "type": "IDENTITY_FRONT", "fileId": "6712c2ac7c2f1e0012a4b8d4" },
{ "type": "IDENTITY_BACK", "fileId": "6712c2ac7c2f1e0012a4b8d5" },
{ "type": "PICTURE", "fileId": "6712c2ac7c2f1e0012a4b8d6" }
]
}'

Todo ADMIN ativo precisa de PICTURE (selfie) e de uma identidade válida: CNH, ou CNH_FRONT + CNH_BACK, ou IDENTITY_FRONT + IDENTITY_BACK, ou PASSPORT. Se todos os arquivos forem reprovados, a resposta é 422.

5. Autenticação Pix dos administradores

Quando a sua empresa tem a feature PIX_AUTHENTICATION_KYC, cada ADMIN ativo precisa provar que tem conta no próprio CPF pagando um Pix de valor simbólico. A cobrança é criada com ensureSameTaxID: o próprio arranjo Pix recusa pagador com outro CPF. O valor é devolvido.

curl -X POST https://api.woovi.com/api/v1/kyc/pix-authentication \
-H "Authorization: <APP_ID>" \
-H "Content-Type: application/json" \
-d '{
"correlationID": "merchant-4417",
"representativeId": "6721f0b3c1d4e80012a4f9aa"
}'
{
"pixAuthentication": {
"id": "6722a1d0e4b1f30012c0ffee",
"status": "CREATED",
"result": "UNVERIFIED",
"amount": 1,
"dueDate": "2026-09-24T18:30:00.000Z"
},
"brCode": "00020101021226900014br.gov.bcb.pix..."
}

Mostre o brCode como QR Code ou "copia e cola" para o sócio. Chamar de novo com uma cerimônia aberta devolve o mesmo brCode; se o sócio já estiver verificado, a resposta é 200 com result: MATCHED e sem brCode. Não fixe o amount no seu código: ele muda por ambiente.

Depois, consulte o resultado:

curl https://api.woovi.com/api/v1/kyc/pix-authentication/6722a1d0e4b1f30012c0ffee \
-H "Authorization: <APP_ID>"
resultSignificadoPróximo passo
UNVERIFIEDNenhum pagamento aindaContinue consultando até dueDate
MATCHEDPagador = CPF do sócioPronto para esse sócio
MISMATCHPagou, mas outro CPF / instituição reprovadaCrie uma nova cerimônia

Decida por result, não por status. Cadência sugerida: a cada 5 s, recuando para 10, 20 e 40 s em erros seguidos. Quando allRepresentativesVerified for true, todos os ADMIN estão verificados.

Sandbox

No sandbox a cerimônia não pode ser concluída (exige um Pix real), então essa exigência não se aplica lá.

6. BC Protege+

O BC Protege+ é um cadastro do Banco Central em que o titular bloqueia a abertura de contas no próprio nome. Enquanto estiver ativo para o CNPJ ou para algum ADMIN ativo, a Woovi não pode abrir a conta.

curl "https://api.woovi.com/api/v1/kyc/bc-protection?correlationID=merchant-4417" \
-H "Authorization: <APP_ID>"
{
"applicable": true,
"authorized": false,
"blocking": [
{ "scope": "REPRESENTATIVE", "taxID": "52998224725", "situation": "UNAUTHORIZED" }
]
}
  • applicable: false → a regra não se aplica à sua empresa; nunca bloqueia.
  • blocking lista todos os bloqueios de uma vez; mostre todos ao cliente.
  • Só o titular resolve: ele desativa o BC Protege+ no Banco Central e você pede uma nova consulta:
curl -X POST https://api.woovi.com/api/v1/kyc/bc-protection/resend \
-H "Authorization: <APP_ID>" \
-H "Content-Type: application/json" \
-d '{ "correlationID": "merchant-4417", "taxID": "52998224725" }'

A resposta 202 significa que a consulta foi aceita, não que a situação mudou: leia o GET de novo depois (ou espere o webhook ACCOUNT_REGISTER_STEP_UPDATED). Há um limite de um reenvio por hora por CPF/CNPJ: dentro da janela a resposta é 429 com nextResendAt.

7. Enviar para análise

curl -X POST https://api.woovi.com/api/v1/kyc/onboarding/submit \
-H "Authorization: <APP_ID>" \
-H "Content-Type: application/json" \
-d '{ "correlationID": "merchant-4417" }'
{
"correlationID": "merchant-4417",
"status": "IN_REVIEW",
"inReviewAt": "2026-09-24T16:10:00.000Z"
}
  • Só é aceito para cadastros em DRAFT ou PENDING. Cadastros em qualquer outro status (APPROVED, REJECTED, CREATING, FAILED) são recusados com 409 STATUS_NOT_SUBMITTABLE — um cadastro já decidido nunca volta para análise.
  • É idempotente: um cadastro que já está IN_REVIEW responde 200 com o inReviewAt original, sem refazer nada. Pode repetir uma chamada que deu timeout.
  • Todas as validações rodam no servidor. Enquanto alguma estiver pendente, a resposta é 409 com code:
codeCausaComo resolver
MISSING_PIX_AUTHENTICATIONUm ADMIN ativo sem cerimônia MATCHED (só com PIX_AUTHENTICATION_KYC)Passo 5
BC_PROTECTION_NOT_AUTHORIZEDCNPJ ou ADMIN com BC Protege+ ativoPasso 6
MISSING_REPRESENTATIVE_DOCUMENTSADMIN sem selfie ou sem identidade válidaPasso 4
PENDING_REQUESTED_DOCUMENTSA análise pediu documentos que não foram enviadosPasso 3 / RFI
PENDING_BC_PROTEGEA única pendência é o BC Protege+Passo 6
STATUS_NOT_SUBMITTABLEO cadastro não está em DRAFT/PENDINGConsulte o status; não há o que reenviar
Diferença para o link

No link hospedado a autenticação Pix não impede o envio (ela é cobrada depois, na análise). Pela API ela bloqueia o submit, porque a sua integração não tem uma "próxima tela" para mandar o cliente de volta.

8. Acompanhar por webhook

Não faça polling do status. Cadastre os webhooks com a sua API Master:

EventoQuando
ACCOUNT_REGISTER_STEP_UPDATEDUm passo foi concluído ou bloqueado (ex.: BC Protege+)
ACCOUNT_REGISTER_IN_REVIEWO cadastro entrou em análise
ACCOUNT_REGISTER_DOCUMENTS_REQUESTEDA análise abriu uma RFI
ACCOUNT_REGISTER_RFI_RESOLVEDTodos os itens da RFI foram respondidos
ACCOUNT_REGISTER_PENDINGO cadastro voltou para o cliente
ACCOUNT_REGISTER_APPROVED / _REJECTEDDecisão final

Payloads, assinatura e deduplicação estão em Como acompanhar o onboarding em tempo real por webhooks?.

9. RFI (pedido de informações)

Quando a análise precisa de algo a mais, ela abre uma RFI e envia ACCOUNT_REGISTER_DOCUMENTS_REQUESTED. Leia o que foi pedido:

curl "https://api.woovi.com/api/v1/kyc/rfi?correlationID=merchant-4417" \
-H "Authorization: <APP_ID>"
{
"rfi": {
"status": "OPEN",
"kind": "DOCUMENTS",
"reason": "Enviar contrato social atualizado e documento do sócio",
"requestedAt": "2026-09-24T17:00:00.000Z",
"deadlineAt": "2026-10-01T17:00:00.000Z"
},
"company": {
"pending": [
{ "type": "SOCIAL_CONTRACT", "answeredBy": "FILE" },
{ "type": "WEBSITE", "answeredBy": "LINK" }
]
},
"representatives": [
{
"id": "6721f0b3c1d4e80012a4f9aa",
"name": "MARIA DE SOUZA",
"pending": [
{ "type": "CNH", "answeredBy": "FILE" },
{ "type": "PIX_AUTHENTICATION", "answeredBy": "PIX_AUTHENTICATION" }
]
}
],
"link": "https://kyc.woovi.com/rfi/QWNjb3VudFJlZ2lzdGVyOjY5..."
}

answeredBy diz como responder cada item:

answeredByComo responder
FILEPOST /api/v1/kyc/rfi (ou os endpoints de documentos)
PIX_AUTHENTICATIONPasso 5
BC_PROTECTIONPasso 6, depois que o cliente desativar
LINKSó pelo link (site, descrição do negócio, regularização do CNPJ)

Responda os arquivos numa única chamada:

curl -X POST https://api.woovi.com/api/v1/kyc/rfi \
-H "Authorization: <APP_ID>" \
-H "Content-Type: application/json" \
-d '{
"correlationID": "merchant-4417",
"documents": [
{ "type": "SOCIAL_CONTRACT", "fileId": "6712c2ac7c2f1e0012a4b8d7" }
],
"representatives": [
{
"representativeId": "6721f0b3c1d4e80012a4f9aa",
"documents": [{ "type": "CNH", "fileId": "6712c2ac7c2f1e0012a4b8d8" }]
}
]
}'

Cada arquivo precisa responder a um item que foi pedido — senão 400 NOT_REQUESTED e nada é gravado. Um pedido de identidade de sócio aceita qualquer família (CNH, CNH_FRONT/CNH_BACK, IDENTITY_FRONT/IDENTITY_BACK, PASSPORT). Sem RFI aberta, a resposta é 409 RFI_NOT_OPEN. Quando nada mais estiver pendente, a RFI fecha (status: RESOLVED) e chega o webhook ACCOUNT_REGISTER_RFI_RESOLVED.

Você pode misturar: responder os arquivos pela API e mandar o link ao cliente só para os itens LINK.

Erros comuns

Todas as respostas de erro têm error (mensagem já traduzida) e, quando existe, code (estável, use no seu código).

HTTPcodeCausa
400Body inválido (lista de erros de validação), CPF inválido, ou fileId não encontrado para a sua empresa/purpose
400NOT_REQUESTEDArquivo de RFI que não responde a nada pedido
401AppID ausente ou inválido
403Empresa sem BAAS/PARTNER, sem PIX_AUTHENTICATION_KYC (Pix), ou AppID sem o escopo
404Nenhum cadastro com esse correlationID na sua empresa, ou sócio desconhecido
409ACCOUNT_REGISTER_NOT_OPENO cadastro não aceita mais alterações no status atual
409REPRESENTATIVE_ALREADY_REGISTERED / MEI_SINGLE_OWNERSócio duplicado / MEI com mais de um titular
409REPRESENTATIVE_NOT_ACTIVEDocumento para um sócio desativado
409REGISTER_CLOSED_FOR_NEW_CEREMONIESCadastro fora de PENDING sem RFI de Pix aberta
409códigos do submitAlguma validação do envio pendente
409RFI_NOT_OPENNão há RFI aberta
422Todos os documentos do sócio foram reprovados na checagem de qualidade
429Reenvio do BC Protege+ dentro da janela de 1 hora (nextResendAt)
502UPSTREAM_ERRORServiço de autenticação Pix indisponível; tente de novo
Referência completa

Schemas, parâmetros e exemplos interativos de cada endpoint estão na API Reference.