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

# How a verification works

> The lifecycle of a single check, from request to stored result.

Every check on Pruva, whatever the scope, follows the same lifecycle. Understanding it once means you understand all of them, because a NIN lookup, a face match, and an AML screen differ only in their inputs and results, not in their shape.

## The lifecycle

<Steps>
  <Step title="You send a request">
    A POST to the scope's endpoint, for example `POST /v1/nin`, with that scope's inputs as the JSON body.
  </Step>

  <Step title="Pruva checks the gate">
    We confirm your key is valid, your organization is approved, the scope is active for you, and your wallet can cover the check. If any of these fail, nothing is charged and you get a clear reason.
  </Step>

  <Step title="Pruva calls the provider">
    We route the request to the provider configured for that scope, using your organization's credentials and pricing, and wait for their answer.
  </Step>

  <Step title="Pruva records the result">
    The answer is stored as a verification with a unique `reference`. Any images are moved to secure storage and replaced with links, never kept in the record itself.
  </Step>

  <Step title="You get the result">
    The verification comes back as JSON: a `status`, the `result` details, and the `reference` you can use to fetch it again later.
  </Step>
</Steps>

## The three outcomes

A completed check resolves to one of three statuses:

<CardGroup cols={3}>
  <Card title="found" icon="circle-check">
    The record exists and matched. The `result` object carries the details.
  </Card>

  <Card title="not_found" icon="circle-question">
    The lookup ran and the record does not exist. This is a real answer, not an error.
  </Card>

  <Card title="failed" icon="circle-xmark">
    The check could not be completed, a provider timeout or outage. This is not an answer about the subject.
  </Card>
</CardGroup>

<Warning>
  `not_found` and `failed` are different, and the difference matters for billing. `not_found` is a real answer the provider gave, so it is charged. `failed` is a breakdown on our side or the provider's, so it is never charged. See [Wallet and billing](/concepts/billing).
</Warning>

## What comes back

The verification resource is the same whether you get it from the run, fetch it by reference, or list it. The core fields:

| Field          | Meaning                                                              |
| -------------- | -------------------------------------------------------------------- |
| `reference`    | Unique id for this verification.                                     |
| `scope`        | The scope that was run, for example `nin`.                           |
| `category`     | The scope's family: `kyc`, `kyb`, `vision`, or `aml`.                |
| `status`       | `found`, `not_found`, or `failed`.                                   |
| `result`       | The details found, shaped by the scope. `{}` when nothing was found. |
| `errorMessage` | Why a check failed, when it did. `null` otherwise.                   |
| `priceKobo`    | What the check cost, in kobo.                                        |
| `charged`      | Whether your wallet was actually debited.                            |
| `createdAt`    | When the check ran, in ISO 8601 with the West Africa offset.         |

<Note>
  Prices are always in **kobo**, the minor unit, so `5000` means ₦50.00. Working in the minor unit avoids rounding errors; divide by 100 only for display.
</Note>
