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

# Biometric verification

> A selfie with liveness and face-match check of the merchant's contact, done once and reused across your organization: how to start one, hand it to the person, read the result and reuse it.

A **biometric verification** is a selfie with a liveness and face-match check of one person, run by the provider on its own capture page. It satisfies the `BIOMETRIC_VERIFICATION` requirement, and it is the one item a person always does live, on their own phone or computer.

A verification belongs to **your organization**. Once approved, it serves every affiliation attempt with that provider, of every merchant of your organization where that person is the contact. The person does it once.

## The flow

```mermaid theme={null}
sequenceDiagram
    participant You as Your backend
    participant Rinne as Rinne API
    participant Person as Merchant contact
    participant Capture as Provider capture page

    You->>Rinne: POST /biometric-verifications
    Rinne-->>You: PENDING, verification_url
    You->>Person: Open verification_url
    Person->>Capture: Selfie and liveness
    Capture-->>Person: Redirect to redirect_url, if given
    Rinne-->>You: biometric-verification.status-changed (APPROVED or REPROVED)
    You->>Rinne: GET /biometric-verifications/{id}
    Rinne-->>You: Result, selfie and evidence package
```

The [onboarding link](/onboarding/onboarding-link) runs the same flow for you: it starts the verification when the person reaches the step, opens the same capture page in a new tab, and resumes when the person comes back.

## Start a verification

<ParamField body="provider" type="string" required>
  The provider that runs the capture: `CELCOIN`.
</ParamField>

<ParamField body="subject_document_number" type="string" required>
  The CPF of the merchant's contact; punctuation is ignored. Anyone else answers `400`.
</ParamField>

<ParamField body="redirect_url" type="string">
  Where the provider sends the person when the capture ends. The result never comes from this redirect: read it from the webhook or from `GET /v1/biometric-verifications/{id}`.
</ParamField>

A full request and response are in [Build with the API](/onboarding/api#3-run-the-biometric-verification).

## Hand the capture to the person

`verification_url` is the provider's own capture page, returned as is. Open it on the person's phone or send it to them, in a browser tab or window of its own: the provider's page does not run inside a frame, which is why the onboarding link opens it in a new tab too. In an app, open it in the browser or in an in-app browser tab, not in a webview the app frames. It works until `verification_url_expires_at`; read that field rather than assuming a lifetime.

<Tip>
  Giving a `redirect_url`? The provider's page can load it inside a frame of its own when the capture ends, so the page at `redirect_url` must allow being framed (its `frame-ancestors` must not refuse it), or the person ends on a blank frame.
</Tip>

## Status

| Status | Meaning | What to do |
| - | - | - |
| `PENDING` | Created; the person has not completed the capture, or the provider has not answered yet | Have the person open `verification_url` before `verification_url_expires_at` |
| `APPROVED` | Liveness and face match passed (`approved_at`). The selfie is stored as a `SELFIE` document (`selfie_onboarding_document_id`) | Nothing; it satisfies `BIOMETRIC_VERIFICATION` |
| `REPROVED` | The provider refused it; `rejection_reason` has the provider's `code` and `message` | Start a new verification |
| `EXPIRED` | `verification_url` expired before the person completed the capture | Start a new verification |

`APPROVED`, `REPROVED` and `EXPIRED` are terminal. `biometric-verification.status-changed` fires when a verification leaves `PENDING`.

## One pending verification per person

Only one verification per person and provider can be pending in your organization. A second `POST` answers `409` with `details.pending_verification_id`: follow that one instead. Every merchant the person is the contact of can read it, whichever merchant started it. Ten minutes after its `verification_url_expires_at`, a new one can be started.

## Reuse before you start

Before asking the person for a capture, read the merchant's `BIOMETRIC_VERIFICATION` requirement: `SATISFIED` means an approved verification already serves it. The list shows the person's verifications across your organization:

```bash cURL theme={null}
curl "https://api-sandbox.rinne.com.br/core/v1/biometric-verifications?subject_document_number=52998224806&status=APPROVED" \
  -H "x-api-key: YOUR_API_KEY"
```

An `APPROVED` verification in the list does not settle the requirement on its own, since an approved one [can have to be redone](#when-an-approved-verification-has-to-be-redone); go by the requirement's `status`. An organization sees every verification it owns, for itself and for its merchants (`company_id` narrows the list to one merchant). A merchant using its own API key sees the verifications of its contact within its organization.

<Info>
  A biometric verification never crosses organizations. Documents may be [shared](/onboarding/documents#shared-documents), but a face capture is reused only inside the organization that collected it.
</Info>

## The evidence package

For the owner organization, `GET /v1/biometric-verifications/{id}` adds `evidence_download_url` and `evidence_download_url_expires_at`: a signed link, valid for one hour, to the provider's evidence package, the PDF that records the liveness and face-match session. It is `null` until the package is stored, in the list, and for a merchant reading a verification of its contact.

## When an approved verification has to be redone

Rinne keeps its own copy of every approved selfie: it fetches the file from the provider right after the approval and stores it as the verification's `SELFIE` document, so the selfie is reused from Rinne's store from then on. Rarely, the approval arrives but the file does not, and Rinne keeps retrying for a day. If the selfie is still not stored a day after `approved_at`, Rinne sets the `BIOMETRIC_VERIFICATION` requirement back to `PENDING` and fires `affiliation.requirements-changed`. Start a new verification, or let the onboarding link ask for it. A verification whose selfie is stored is never redone this way.


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