> ## Documentation Index
> Fetch the complete documentation index at: https://docs.proofage.net/llms.txt
> Use this file to discover all available pages before exploring further.

# Verification statuses

> Every status a verification can be in, how it moves between them, and which are final.

The `status` field of a [verification](/api-reference/data-models#verification) tells you where it is. Your integration mostly needs the final ones, which arrive by [webhook](/integration/webhooks).

```mermaid theme={null}
stateDiagram-v2
    [*] --> created
    created --> started: capture begun
    created --> expired: not started in 7 days
    started --> submitted: submit
    submitted --> documents_required: selfie can't confirm 18+
    documents_required --> submitted: ID added
    started --> abandoned: no progress in 7 days
    submitted --> approved
    submitted --> declined
    submitted --> resubmission_requested
    submitted --> review
    review --> approved
    review --> declined
    review --> resubmission_requested
    resubmission_requested --> started: person retries
    resubmission_requested --> abandoned: no progress in 7 days
    approved --> [*]
    declined --> [*]
    abandoned --> [*]
    expired --> [*]
```

| Status | Meaning | Final | Webhook |
| - | - | - | - |
| `created` | The verification exists; no image has been uploaded yet. | No | No |
| `started` | The person is capturing: the selfie is in, or on Identity (KYC) both sides of the document are. | No | No |
| `documents_required` | A facial age estimation could not confirm 18+ from the selfie; the person adds an identity document. Reported by `GET` only. | No | Yes, as `resubmission_requested` with `reason: null` |
| `submitted` | The images are in and are being analysed. | No | No |
| `review` | The verification waits for a person's decision. Test workspaces always stop here. | No | Yes |
| `resubmission_requested` | Something must be captured again; the person retries in the same verification. | No | Yes |
| `approved` | The verification passed. | Yes | Yes |
| `declined` | The verification failed; `reason` says why. | Yes | Yes |
| `abandoned` | Started, or asked to resubmit, and then no progress for 7 days. | Yes | Yes |
| `expired` | Never started within 7 days of being created. | Yes | Yes |

## Notes

* **`documents_required`** only happens on Facial age estimation workspaces, when the selfie can't confirm 18+. `GET /v1/verifications/{id}` reports it while the person adds an ID in the same verification. The webhook for this step is `resubmission_requested` with `reason: null`, so a handler must accept a `null` reason on that status.
* **`review`** means a person on your team decides in the console; the decision webhook follows when they do, with no fixed time. In a test workspace every submission stops here until you set the outcome: see [Sandbox and test data](/integration/sandbox-testing). A live verification is decided automatically and doesn't stop in `review` today, but handle the status anyway.
* **`resubmission_requested`** is not final. The person retakes what failed in a new attempt of the same verification. Attempts are limited: when they run out the verification is `declined`, and `reason` is the last attempt's reason, not a separate code. Treat `declined` as final whatever the code.
* **`abandoned`** and **`expired`** are set by a daily job, so they can arrive up to a day after the seven days have passed.
* A final status can still change when someone on your team corrects a decision by hand in the console. The webhook for the new status carries `manual_moderation`.

## Reading the status

Rely on the webhook, and fetch the verification with `GET /v1/verifications/{id}` when you need the current state, for example when the person returns to your site before the webhook arrived. Do not poll in a tight loop: see [Rate limiting](/integration/rate-limiting).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.