> ## 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.

# Self-Exclusion

> Real-time exclusion list with three-layer propagation (webhook + REST + nightly snapshot).

Anunnaki holds the master self-exclusion list and propagates it to operators in real time. The list is enforced via webhook push (sub-second), live REST check (signup / login / pre-deposit), and a daily 03:00 UTC bulk snapshot — three independent layers so an exclusion is never missed.

## Supported durations

| Type                  | API value            | Reversible?           |
| --------------------- | -------------------- | --------------------- |
| 24-hour cool-off      | `duration_24h`       | Auto-expires          |
| 7-day short break     | `duration_7d`        | Auto-expires          |
| 30-day cool-off       | `duration_30d`       | Auto-expires          |
| 6-month time-out      | `duration_6m`        | Auto-expires          |
| 1-year long exclusion | `duration_1y`        | Auto-expires          |
| Permanent             | `duration_permanent` | **Irrevocable** (KGC) |

## Endpoints

| Method | Path                      | Description                                                 |
| ------ | ------------------------- | ----------------------------------------------------------- |
| `POST` | `/v1/exclusions`          | Register a new exclusion. Idempotent on `(user, duration)`. |
| `GET`  | `/v1/exclusions/check`    | Cross-tenant lookup by email or phone.                      |
| `GET`  | `/v1/exclusions/snapshot` | Paginated full snapshot (for nightly reconciliation).       |

### `POST /v1/exclusions`

```bash theme={null}
curl https://sandbox.api.anunnakielite.com/v1/exclusions \
  -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",
    "duration": "duration_6m",
    "reason": "self_initiated",
    "initiated_at": "2026-05-24T14:32:00Z"
  }'
```

```json theme={null}
{
  "exclusion_id": "ex_4f9a02",
  "user_id": "rt_usr_8a2f1c",
  "duration": "duration_6m",
  "effective_from": "2026-05-24T14:32:00Z",
  "expires_at": "2026-11-24T14:32:00Z",
  "is_permanent": false,
  "kgc_propagated": true
}
```

<Warning>
  Permanent exclusions cannot be undone via API. Block all gameplay immediately on `201`.
</Warning>

### `GET /v1/exclusions/check`

Lookup by `email` or `phone`. Returns the most-restrictive active exclusion if any (permanent > latest expiry); `is_excluded:false` otherwise.

<Note>
  **KGC master-list rows are matched cross-tenant by default.** The Kahnawake comprehensive self-exclusion list (`source: "kgc_comprehensive"`) applies across every licensed brand, so a `check` will return a KGC exclusion regardless of which tenant the listed player registered with. Your own tenant-scoped exclusions are matched as well.
</Note>

<ParamField query="email" type="string">
  Player email to check. Either `email` or `phone` is required.
</ParamField>

<ParamField query="phone" type="string">
  Player phone to check. Either `email` or `phone` is required.
</ParamField>

<ParamField query="include_kgc" type="boolean" default="true">
  Whether to match against the KGC comprehensive master list. Defaults to `true` — leave it unless you are deliberately testing your own tenant rules in isolation. Setting `include_kgc=false` skips `source: "kgc_comprehensive"` rows and is intended for diagnostics only; **do not disable it in production**, as KGC cross-brand exclusions are a licence obligation.
</ParamField>

```bash theme={null}
curl "https://sandbox.api.anunnakielite.com/v1/exclusions/check?email=jane.doe@example.com" \
  -H "Authorization: Bearer cur_sk_test_EXAMPLEKEY123456789012345678901234"
```

```json theme={null}
{
  "is_excluded": true,
  "exclusion_id": "ex_4f9a02",
  "duration": "duration_permanent",
  "expires_at": null,
  "is_permanent": true,
  "source": "kgc_comprehensive"
}
```

### `GET /v1/exclusions/snapshot`

Paginated tenant-scoped active rows. `?cursor=<base64url>&limit=<1..1000>`. Use for nightly reconciliation against missed webhooks.

## Webhooks

| Event                  | Fires when                                                         |
| ---------------------- | ------------------------------------------------------------------ |
| `exclusion.created`    | A user is excluded — locally or via another KGC-licensed operator. |
| `exclusion.expired`    | A timed exclusion auto-expires.                                    |
| `exclusion.permanent`  | A permanent (irrevocable) exclusion is registered.                 |
| `exclusion.kgc_synced` | A user is excluded via the KGC Comprehensive Form.                 |

```json theme={null}
{
  "event": "exclusion.created",
  "event_id": "evt_8f9a02",
  "timestamp": "2026-05-24T14:32:01Z",
  "data": {
    "exclusion_id": "ex_4f9a02",
    "user_email": "jane.doe@example.com",
    "user_phone": "+44 7700 900123",
    "duration": "duration_6m",
    "is_permanent": false,
    "expires_at": "2026-11-24T14:32:00Z",
    "source": "rain_trade"
  }
}
```

## Error codes

| Status | Code                     |
| ------ | ------------------------ |
| 400    | Invalid payload          |
| 401    | Missing / invalid bearer |
| 404    | User not found           |
| 409    | Already excluded         |
| 429    | Rate limit (100/min)     |
