Webhooks

Our identity validation process is an asynchronous workflow. Once a user finishes or abandons the verification flow, our system sends an HTTP POST webhook notification to your backend with the final results.

Important Session Limit: The entire identity validation session must be completed by the user within 20 minutes from instantiation. If this limit is exceeded, the session automatically times out.

Setting up the webhook

To maintain high security and system integrity, webhook endpoints and access tokens are managed exclusively by authorized operators.

  • Setup Request: Submit your webhook destination URL through your designated communication channels with our support team.
  • Endpoint Requirements: Your server endpoint must accept incoming POST requests with a JSON body (Content-Type: application/json) and immediately respond with a 2xx success status code.

Example of Webhook Payload:

{
  "id": "5169bc58-5777-472b-8eb6-8bb660d62812",
  "document": "12345678910",
  "approved": true,
  "status": "APPROVED",
  "merchant_id": "3da83a2e-92f7-4e6c-b799-84cf84b6ab8b",
  "reason": "FACEMATCH_APPROVED",
  "reason_description": "Comparação facial aprovada",
  "step": "FACEMATCH"
}

Field Definitions:

fieldtypealways presentdescription
idstring (uuid)yesthe validation session id (the same session_id returned when the session was created)
documentstringyesthe document number (CPF) of the validated user
approvedbooleanyestrue when the validation was approved
statusstringyesfinal status of the validation session (see Webhook Status)
merchant_idstring (uuid)yesyour merchant id
reasonstringnocode identifying the reason for the result (see Reason values)
reason_descriptionstringnohuman-readable description of the reason, in Portuguese, ready for display
stepstringnothe validation step that produced the result: OCR, QUALITY, LIVENESS, FACEMATCH or CPF_VALIDATION

⚠️ Backward Compatibility Note: The fields reason, reason_description, and step are strictly additive extensions of the webhook structure. Core historical fields (id, document, approved, status, merchant_id) remain unchanged in name, type, and behavior. Additive fields are omitted entirely (never sent as null) if they do not apply to the specific session event. Your parsing architecture must accept new additive keys without rejecting the payload.

Webhook Status

The status parameter reflects the overarching business outcome of the session. It will always equal one of the following four values:

{
    "APPROVED"
    "REPROVED"
    "EXPIRED"
    "ERROR"
}

Reason and Step Breakdown

When the reason key is provided, use this matrix to map out granular failures or successes within your internal user tracking systems:

reasonreason_descriptionstepresult
FACEMATCH_APPROVEDComparação facial aprovadaFACEMATCHapproved
DOCUMENT_APPROVEDDocumento aprovadoOCRapproved
LIVENESS_APPROVEDProva de vida aprovadaLIVENESSapproved
FACEMATCH_NOT_APPROVEDComparação facial reprovadaFACEMATCHreproved — selfie does not match the document photo
DOCUMENT_NOT_APPROVEDDocumento não aprovadoOCRreproved — document rejected
DOCUMENT_NOT_ALLOWEDDocumento não permitidoOCRreproved — document type not accepted
DOCUMENT_WITHOUT_CPFDocumento sem CPFOCR or CPF_VALIDATIONreproved — document has no readable CPF, or the CPF is not regular at the federal registry (non-existent, suspended, cancelled or deceased holder)
MAX_RETRIES_EXCEEDEDReprovado por excesso de tentativasLIVENESSreproved — too many failed liveness attempts

💡 Open Set Design: Treat the reason column as an open, evolving list. If your backend encounters an unrecognized code due to a future system update, fallback to status and approved for your automated business rules, and safely pipe reason_description to your administrative dashboards.


Early CPF Pre-Validation
Validation sessions can fail instantly before a user ever activates their camera hardware. If the provided CPF string is flags an irregular status at the Federal Registry level, the webhook will fire almost instantly with step: "CPF_VALIDATION" and status: "REPROVED". Your receiving endpoint should be structurally prepared to handle callbacks immediately following session creation.


Structured Payload Examples

Approved session:

{
    "id": "5169bc58-5777-472b-8eb6-8bb660d62812",
    "document": "12345678910",
    "approved": true,
    "status": "APPROVED",
    "merchant_id": "3da83a2e-92f7-4e6c-b799-84cf84b6ab8b",
    "reason": "FACEMATCH_APPROVED",
    "reason_description": "Comparação facial aprovada",
    "step": "FACEMATCH"
}

Reproved session (facematch failed):

{
    "id": "5169bc58-5777-472b-8eb6-8bb660d62812",
    "document": "12345678910",
    "approved": false,
    "status": "REPROVED",
    "merchant_id": "3da83a2e-92f7-4e6c-b799-84cf84b6ab8b",
    "reason": "FACEMATCH_NOT_APPROVED",
    "reason_description": "Comparação facial reprovada",
    "step": "FACEMATCH"
}

Reproved session (irregular CPF):

{
    "id": "5169bc58-5777-472b-8eb6-8bb660d62812",
    "document": "12345678910",
    "approved": false,
    "status": "REPROVED",
    "merchant_id": "3da83a2e-92f7-4e6c-b799-84cf84b6ab8b",
    "reason": "DOCUMENT_WITHOUT_CPF",
    "reason_description": "Documento sem CPF",
    "step": "CPF_VALIDATION"
}

Best practices

  • Idempotency: process notifications idempotently, using the id field as the deduplication key.
  • Respond fast: acknowledge with 2xx right away and do any heavy processing asynchronously.
  • Tolerant parsing: ignore unknown fields and unknown reason codes — the payload contract is additive.


Did this page help you?