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

# KYC Verification

> Five-tier identity verification keyed to cumulative-withdrawal thresholds. Triggered at withdrawal, not at signup.

KYC is the withdrawal gate. Deposits stay frictionless; identity is verified only when money tries to leave. Five tiers keyed to lifetime cumulative withdrawals. Production cutover will use **SumSub**; sandbox runs against a deterministic stub.

<Note>
  Sandbox currently uses a stub vendor with deterministic triggers — see "Sandbox triggers" below.
</Note>

## Tiers

| Tier     | Withdrawal range     | Docs required               |
| -------- | -------------------- | --------------------------- |
| `tier_0` | up to \$200 lifetime | None (pre-KYC ceiling)      |
| `tier_1` | $201 – $2,000        | Email + phone OTP           |
| `tier_2` | $2,001 – $20,000     | Government ID + selfie      |
| `tier_3` | $20,001 – $100,000   | + proof of address          |
| `tier_4` | \$100,000+           | + source-of-funds documents |

Once the \$200 lifetime ceiling is crossed, the user **cannot return to `tier_0`** — `tier_1` or higher is required for every future withdrawal.

## Endpoints

| Method | Path                    | Description                                                                  |
| ------ | ----------------------- | ---------------------------------------------------------------------------- |
| `POST` | `/v1/kyc/start`         | Initiate verification for a withdrawal that exceeds the user's current tier. |
| `GET`  | `/v1/kyc/status`        | Poll for review status (webhook fallback).                                   |
| `GET`  | `/v1/kyc/tier`          | Read the user's verified tier + cumulative withdrawn.                        |
| `POST` | `/v1/kyc/manual-review` | **Admin-only.** Manual approve / reject.                                     |

### `POST /v1/kyc/start`

```bash theme={null}
curl https://sandbox.api.anunnakielite.com/v1/kyc/start \
  -H "Authorization: Bearer cur_sk_test_EXAMPLEKEY123456789012345678901234" \
  -H "Content-Type: application/json" \
  -d '{
    "user_id": "rt_usr_8a2f1c",
    "email": "jane.doe@example.com",
    "phone": "+44 7700 900123",
    "withdrawal_amount_cents": 250000,
    "currency": "USD"
  }'
```

Verification required (`201 Created`):

```json theme={null}
{
  "kyc_check_id": "kyc_3a91f7",
  "user_id": "rt_usr_8a2f1c",
  "required_tier": "tier_2",
  "required_documents": ["government_id", "selfie"],
  "sumsub_access_token": "_act-EXAMPLE-TOKEN",
  "sumsub_expires_in": 600,
  "withdrawal_held": true,
  "estimated_clear_time": "same_day"
}
```

`tier_0` fast path (`200 OK`):

```json theme={null}
{
  "kyc_check_id": null,
  "required_tier": "tier_0",
  "required_documents": [],
  "withdrawal_held": false,
  "withdrawal_remaining_cents": 5000,
  "message": "Withdrawal under pre-KYC ceiling. Approved instantly."
}
```

### `GET /v1/kyc/status`

```bash theme={null}
curl "https://sandbox.api.anunnakielite.com/v1/kyc/status?kyc_check_id=kyc_3a91f7" \
  -H "Authorization: Bearer cur_sk_test_EXAMPLEKEY123456789012345678901234"
```

| Status           | Meaning                             |
| ---------------- | ----------------------------------- |
| `not_started`    | User hasn't begun uploading.        |
| `in_progress`    | Active in vendor flow.              |
| `pending_review` | Submitted — under review.           |
| `approved`       | Tier achieved, withdrawal released. |
| `rejected`       | Verification failed.                |
| `expired`        | Abandoned 7+ days. Must restart.    |

### `GET /v1/kyc/tier`

```json theme={null}
{
  "user_id": "rt_usr_8a2f1c",
  "verified_tier": "tier_2",
  "verified_at": "2026-04-12T10:14:00Z",
  "max_withdrawal_cents": 2000000,
  "cumulative_withdrawn_cents": 187000,
  "next_tier_required_at_cents": 2000000
}
```

## Webhooks

| Event               | Fires when                                                        |
| ------------------- | ----------------------------------------------------------------- |
| `kyc.started`       | User initiated the vendor flow.                                   |
| `kyc.submitted`     | Documents uploaded, awaiting review.                              |
| `kyc.approved`      | Tier achieved — release held withdrawal.                          |
| `kyc.rejected`      | Verification failed — keep withdrawal blocked.                    |
| `kyc.tier_upgraded` | User now verified at a higher tier (monotonic; never downgrades). |
| `kyc.expired`       | Abandoned check — withdrawal cancelled.                           |

```json theme={null}
{
  "event": "kyc.approved",
  "event_id": "evt_kyc_3a91f7",
  "timestamp": "2026-05-24T16:08:22Z",
  "data": {
    "kyc_check_id": "kyc_3a91f7",
    "user_id": "rt_usr_8a2f1c",
    "verified_tier": "tier_2",
    "release_withdrawal_id": "wd_99f02a"
  }
}
```

## Sandbox triggers

The sandbox stub vendor advances checks deterministically based on `external_user_id`:

* Contains `autoapprove` → check moves to `approved`.
* Contains `autoreject` → check moves to `rejected`.
* Otherwise → `pending_review` (use the admin CLI to advance).

## Error codes

| Status | Code                                    |
| ------ | --------------------------------------- |
| 400    | `invalid_amount`                        |
| 401    | `unauthorized`                          |
| 404    | `user_not_found`, `kyc_check_not_found` |
| 409    | `already_in_progress`                   |
| 422    | `ceiling_exceeded`                      |
| 429    | `rate_limited`                          |
