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

# Data handling and transparency

> What AnonAge sends to its identity provider, what it keeps, when documents are destroyed, and where to read the code that does it.

Age verification usually works by making people hand identity documents to whoever runs the site.
AnonAge is built so that neither the site nor AnonAge ever holds them. This page states exactly
what happens to a user's data, so you can check the claim rather than trust it.

## What your site receives

A single boolean. `true` or `false` against the age threshold you asked for.

Your servers never receive a name, a date of birth, a document image, or a face. There is nothing
for you to store, encrypt, retain or delete, and nothing that can be taken from you in a breach.

<Note>
  This is the part that reduces your liability: you cannot expose data you never held.
</Note>

## What AnonAge sends to Sumsub

Identity verification is performed by [Sumsub](https://sumsub.com). The user goes to Sumsub's own
hosted page, so their documents travel from the user to Sumsub directly — not through us.

What we send when starting a verification:

| Field            | Value                                                                        |
| ---------------- | ---------------------------------------------------------------------------- |
| `externalUserId` | An internal reference, e.g. `user_<id>`. Meaningless outside our system.     |
| `email`          | The account email address, so Sumsub can contact the user about their check. |

That is the entire payload. No name, no date of birth, no address, no country.

## What AnonAge keeps

| We keep                                            | We do not keep                               |
| -------------------------------------------------- | -------------------------------------------- |
| Age bands (`over13`, `over16`, `over18`, `over21`) | Identity documents                           |
| Assurance level and verification timestamp         | Selfies or biometric data                    |
| A verification reference                           | **A date of birth — for anyone, at any age** |
|                                                    | Names, addresses, document numbers           |
|                                                    | Which sites a user verified on               |

Four booleans and a timestamp. That is the whole record.

<Warning>
  Until August 2026 this page said we kept the full date of birth for under-21s and collapsed it to
  bands on their 21st birthday. That was wrong, and the reason is worth stating: **the job that was
  meant to do the collapsing was never written**, so "retained temporarily" was in practice
  "retained indefinitely". Rather than write the job, we deleted the storage. The columns are gone
  from the schema, and the schema says not to add them back.
</Warning>

The consequence is a real cost, carried deliberately. A band cannot update itself, so somebody
verified at 17 has a record saying "not over 18" until they run a new check — which they pay for.
What makes that safe rather than merely cheaper is an asymmetry: **a `true` band never goes stale,
because people only get older.** Only a `false` band can become wrong, so the failure mode is
always "an adult is asked to verify again", never "a minor gets in".

## When documents are destroyed

**By default, immediately.** As soon as a verification returns a result — approved or rejected —
AnonAge calls Sumsub's reset endpoint, which destroys the documents and biometrics held for that
person. It happens on the webhook that delivers the result, not on a schedule.

A verification somebody abandons half-way never returns a result, so nothing on that path would
ever ask for its documents to be deleted. A weekly sweep covers exactly that case, destroying the
documents behind anything left unfinished for more than 48 hours. The delay is deliberate: it has
to be longer than a slow but genuine verification, or we would be deleting documents while someone
is still using them.

After the reset, the only thing connecting AnonAge to Sumsub for that user is the applicant
reference. There is nothing behind it.

**Rejected verifications are reset too.** Someone who failed a check has even less reason to have
their passport sitting with a third party.

<Note>
  Deletion is triggered by us on the result, not by waiting for a retention period to expire. Under
  Sumsub's terms the retention period for a client's data is defined by the client contractually
  rather than by a dashboard toggle, so we do not rely on one: the reset call is the mechanism.
</Note>

### The user can opt out

Before a user is sent to Sumsub, they are shown this choice, ticked by default:

> **Delete my Sumsub records** — By default we ask Sumsub to destroy your documents as soon as we
> receive the result, leaving only a verification reference. Untick this only if you want your
> record kept at Sumsub for other reasons.

If they untick it, their documents remain at Sumsub, we record that they chose this and when, and
the choice is shown back to them on their account page. Documents persist at a third party only
because the person asked for that — and we can evidence that they asked.

## Read the code

The Sumsub integration is published as open source. It is deliberately small — a few hundred lines
— so that someone technical can read all of it in one sitting:

* **`sumsubClient.ts`** — the only code that talks to Sumsub. Every request we send and every
  field we read back is in this one file, including the reset call described above.
* **`ageVerification.ts`** — the logic around the result, with no network calls: how a verified
  date of birth becomes a minimal age claim, and how inbound webhooks are authenticated.

The **mobile app** is published too. It is worth knowing what is *not* in it: the app never
decides an age and never holds one. When a user scans a merchant's QR code, the app sends only a
session id and a nonce; the answer is computed server-side from the claim AnonAge itself verified.
A client that decided its own answer could be lied to. This one cannot be.
