Identity Verification
Create a verification link, send it to the person and get the decision. The verification page, hosted by CPFHub.io, runs the liveness check, reads the document (CNH, RG or passport), compares the face with the document photo and checks the CPF against the Receita Federal. It costs 5 credits per completed verification.
Using Cursor, Lovable, v0 or another AI? Copy the Identity Verification prompt and paste it into your assistant.
POST /kyc/linkscreates the link and returns theurl.- You send the
urlto the person or redirect them to it in your sign-up flow. - The decision arrives at your webhook, or through the
GET /kyc/links/{id}lookup.
The verification does not validate the document against a government database, does not perform forensic document analysis and does not accept the digital CNH (CNH Digital).
Create link
https:/ / api.cpfhub.io/ kyc/ links| Where | Name | Required | Description |
|---|---|---|---|
| Header | x-api-key | Yes | Your API key, the same one used for lookups |
| Body | externalId | No | Your identifier for the sign-up (up to 200 characters). It comes back in the webhook. |
| Body | cpf | No | A CPF you already know. If it differs from the document, the verification goes to review. It is never returned in responses. |
| Body | redirectUrl | No | Where the person returns when they finish. https only. |
| Body | language | No | pt-BR, en or es. Default: browser language. |
| Body | expiresInMinutes | No | Validity, from 5 to 10080. Default: 1440 (24 h). |
| Body | maxAttempts | No | Attempts, from 1 to 10. Default: 3. |
curl -X POST "https://api.cpfhub.io/kyc/links" \
-H "x-api-key: $CPFHUB_API_KEY" \
-H "content-type: application/json" \
-d '{
"externalId": "cliente-4821",
"redirectUrl": "https://seusite.com.br/cadastro/concluido"
}'HTTP 201 Created
{
"success": true,
"data": {
"id": "5b1d7c2e-8a4f-4e7b-9c3d-2f6a1e0b9d47",
"url": "https://verificar.cpfhub.io/AbC123xYz",
"externalId": "cliente-4821",
"expiresAt": "2026-10-28T14:00:00.000Z",
"maxAttempts": 3,
"language": null
}
}Store the id: it comes back in the webhook as linkId. When they finish, the person returns to redirectUrl with kyc_link_id and external_id in the URL, but without the decision: confirm it through the webhook or the lookup.
Get link
https:/ / api.cpfhub.io/ kyc/ links/ {id}{
"success": true,
"data": {
"id": "5b1d7c2e-8a4f-4e7b-9c3d-2f6a1e0b9d47",
"url": null,
"externalId": "cliente-4821",
"status": "completed",
"attempts": 1,
"maxAttempts": 3,
"expiresAt": "2026-10-28T14:00:00.000Z",
"createdAt": "2026-10-27T14:00:00.000Z",
"completedAt": "2026-10-27T14:06:12.000Z",
"verification": {
"id": "8f3c2a1e-77b0-4d3c-9a1f-0e5b6c7d8e9f",
"status": "approved",
"reasons": [],
"completedAt": "2026-10-27T14:06:12.000Z"
}
}
}Link status: pending, completed, expired or canceled. url is returned only while the link can be used. verification is null until the person finishes. No personal data.
Decision
verification.status | Meaning |
|---|---|
approved | All good. The link is closed. |
manual_review | Needs someone on your team (see reasons). Review it in the dashboard. The link is closed. |
rejected | Rejected by the account rules. The person can try again while attempts remain. |
The reasons come in reasons as [{ "code", "message" }]. The most common: face_similarity_borderline, document_expired, ocr_failed, cpf_document_mismatch, cpf_name_mismatch and cpf_situation_irregular. Treat an unknown code as review and show the message only to your team.
Settings
Accepted documents, face similarity thresholds, manual review, expired documents, branding, retention and the webhook are in the dashboard, under Verificações > Configurações, and apply to every link in the account.
Errors
| Status | When it happens | What to do |
|---|---|---|
400 | Invalid parameter (redirectUrl without https, invalid cpf, value out of range) | Fix the body. Do not retry. |
401 | API key missing, invalid or inactive | Check the x-api-key header. |
403 | Inactive or blocked account | Contact support. |
404 | Link does not exist or belongs to another API key | Check the id. |
503 | Temporary failure | Retry with increasing waits (2 s, 4 s, 8 s). |
Error format: Error Codes.
Cost
5 credits per completed verification, from the same balance as lookups, even when it is rejected. The CPF cross-check is included. Creating and looking up links costs nothing, and a technical failure on our side is not charged.
The link gives access to the verification
Anyone with the url can complete the verification in the person's place. Create one link per person, send it only to them and use the shortest validity and attempts your flow allows.
Updated on October 27, 2026