Verification Flow
This guide walks through the complete lifecycle of a ProofAge verification — from session creation to a terminal decision.
Status State Diagram
stateDiagram-v2
[*] --> created : POST /v1/verifications
created --> started : Media uploaded
created --> expired : 7 days with no activity
started --> submitted : POST /v1/verifications/:id/submit
started --> abandoned : 7 days with no submission
submitted --> approved : Pipeline approved
submitted --> declined : Pipeline declined
submitted --> resubmission_requested : Quality or technical issue
submitted --> review : Requires admin review
resubmission_requested --> started : User re-uploads media
review --> approved : Admin approves
review --> declined : Admin declines
approved --> [*]
declined --> [*]
abandoned --> [*]
expired --> [*]Lifecycle Walkthrough
A typical verification session follows these steps:
1. Create a Verification
Your server calls POST /v1/verifications. The flow type and check method are determined by your workspace configuration (set in the dashboard). The API returns a verification object in created status with a unique ID.
2. Record Consent
Before any media can be uploaded, the user must accept the current consent text. Fetch the active consent version with GET /v1/consent, display the text to the user, and record acceptance with POST /v1/verifications/{id}/consent. See the Consent Handling guide for details.
3. Upload Media
Upload the required media files using POST /v1/verifications/{id}/media. The first successful upload transitions the verification from created to started. See Uploading Media for file requirements and validation errors.
Required media depends on the workspace's flow type and check method:
| Flow | Check Method | Required media |
|---|---|---|
| Age | Face Age Estimate (estimation) | selfie |
| Age | ID Age Verification (document_verification) | selfie + document front + document back (passport only needs front) |
| KYC | — | selfie + document front + document back (passport only needs front) |
4. Submit for Processing
Once all required media is uploaded, call POST /v1/verifications/{id}/submit. This transitions the verification to submitted and kicks off the processing pipeline.
The endpoint validates that all required media is present before accepting the submission. If anything is missing, it returns 422 with details about which media is still needed.
5. Receive a Decision
ProofAge processes the submission and delivers a decision via webhook. The verification moves to one of four statuses:
approved— The verification passed all checks.declined— The verification failed (fraud, blocklist match, or unresolvable quality issues).resubmission_requested— The media had quality or technical issues that the user can fix by re-uploading.review— The submission requires manual review by a ProofAge admin.
6. Handle Resubmissions
If the status becomes resubmission_requested, the user can re-upload the problematic media. This moves the verification back to started, and you repeat steps 3–5. Each re-upload counts as an attempt.
Status Reference
| Status | Description | Next possible statuses |
|---|---|---|
created | Session initialized, no media uploaded yet. | started, expired |
started | At least one media file uploaded. Awaiting more media or submission. | submitted, abandoned |
submitted | All media submitted and the processing pipeline is running. | approved, declined, resubmission_requested, review |
resubmission_requested | Media had issues. The user should re-upload and resubmit. | started |
review | Flagged for manual admin review. | approved, declined |
approved | Verification passed. Terminal state. | — |
declined | Verification failed. Terminal state. | — |
abandoned | No submission within 7 days of starting. Terminal state. | — |
expired | No media uploaded within 7 days of creation. Terminal state. | — |
Decision Reasons
When a verification is declined or resubmission_requested, the response includes a reason field. Reasons fall into three categories:
Blocklist and Fraud — Declined
These always result in a declined status with no option to resubmit:
| Reason | Description |
|---|---|
blocklist_match | The user's biometrics match a previously blocklisted identity. |
fraud_detected | Automated fraud signals were detected (e.g., screen capture, printed photo). |
identity_mismatch | The selfie does not match the document photo. |
Quality Issues — Resubmission Requested
These indicate problems the user can fix by re-uploading:
| Reason | Description |
|---|---|
selfie_quality | The selfie is too blurry, too dark/bright, or the face is occluded. |
document_quality | The document photo is unreadable, blurry, or poorly lit. |
liveness_failed | The liveness check did not pass. The user should retry in better conditions. |
Technical Issues — Resubmission Requested
These indicate transient processing failures:
| Reason | Description |
|---|---|
processing_error | An internal error occurred during pipeline processing. Safe to retry. |
Maximum Attempts
Each verification session allows up to 5 submission attempts. An attempt is consumed each time the verification moves from started to submitted.
When all 5 attempts are exhausted and the verification still cannot be approved, the session is declined with reason max_attempts_exceeded. At that point you should create a new verification session if the user wants to try again.
TIP
Track the attempts_remaining field in the verification response to show users how many retries they have left.
Example flow with resubmissions:
Attempt 1: submitted -> resubmission_requested (selfie_quality) — 4 remaining
Attempt 2: submitted -> resubmission_requested (document_quality) — 3 remaining
Attempt 3: submitted -> approved — doneIf instead all 5 attempts result in resubmission requests or declines:
Attempt 5: submitted -> declined (max_attempts_exceeded) — 0 remainingThe user must start a completely new verification session to try again.
Expiry and Abandonment
ProofAge automatically cleans up inactive sessions:
- Expired — A verification in
createdstatus with no media upload for 7 days transitions toexpired. - Abandoned — A verification in
startedstatus with no submission for 7 days transitions toabandoned.
Both are terminal states. Create a new verification if the user returns after expiry.
Next Steps
- Uploading Media — File requirements, validation errors, and HMAC signing for uploads.
- Consent Handling — How to retrieve and record user consent before uploading.
- Authentication — HMAC signature computation for all request types.