> Toden documentation. For the full index fetch /llms.txt. Every page is available as Markdown by appending .md to its URL. Identity verification uses /api/kyc, Risk Intelligence uses /api/v1; they are separate contracts with different error shapes. Never invent an endpoint, field or enum value: read the API reference page for the operation first.

# Spot checks

> "POST /checks: run one-off individual and business checks server to server, and read their history."

For manual crypto investigations, open **Spot Checks → Wallet** in the dashboard. Enter a wallet address for an on-demand risk result and case actions. Backend integrations can use the [On-Demand Wallet Screening API](/risk-intelligence/crypto/wallet-screening-api). [Transaction Monitoring](/risk-intelligence/monitoring/events) uses the same engine to screen crypto counterparties automatically.

```
POST /api/kyc/checks/individual
POST /api/kyc/checks/business
GET  /api/kyc/checks/individual
GET  /api/kyc/checks/business
GET  /api/kyc/checks/individual/:id
GET  /api/kyc/checks/business/:id
```

Run a one-off check without the SDK capture flow: verify a person's ID number against the government database, or a business registration number against the registry. This is the server-to-server counterpart of the dashboard's Spot Checks tabs — the same gates, pricing and sandbox behaviour, and the same history (API checks appear there labelled "API").

**Authentication:** `Authorization: Bearer sk_…` (**secret keys only**, for the whole surface). Results carry PII, so this never belongs in client-side code.
**Production note:** `sk_live_` keys require an [approved business](/get-started/environments#production). Sandbox and development checks are free and serve [test data](/get-started/sandbox-testing).

Checks run **asynchronously**: the submit returns `202` with a `verificationId` within milliseconds, and the result is ready seconds later on the detail endpoint.

## Individual checks

```
POST /api/kyc/checks/individual
```

| Field            | Required | Description                                                                                                                                                                                                                                                                                                                                                                                                                       |
| ---------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `country`        | yes      | `NG`, `GH`, `KE`, `ZA` or `CI` (the government-database markets).                                                                                                                                                                                                                                                                                                                                                                 |
| `idType`         | yes      | The ID type, e.g. `bvn`, `nin`, `passport`. See [Countries & ID types](/user-verification/concepts/id-types).                                                                                                                                                                                                                                                                                                                     |
| `idNumber`       | no\*     | The ID number. Required for number-based IDs; a document ID may instead send the document front for extraction.                                                                                                                                                                                                                                                                                                                   |
| `userData`       | no       | Details to validate against the government record: `firstName`, `lastName`, `dateOfBirth`.                                                                                                                                                                                                                                                                                                                                        |
| `mediaIds`       | no       | Pre-uploaded photos from [`POST /upload`](/user-verification/server-api/upload-media): `documentFront`, `documentBack`, `selfie`. A selfie adds the facial comparison against the record photo.                                                                                                                                                                                                                                   |
| `images`         | no       | The same three slots **inline** instead of pre-uploaded: each an https URL, a data URI, or base64 — the same forms the [face match](/user-verification/server-api/face-match) endpoint takes. Send each slot as `mediaIds` **or** `images`, never both.                                                                                                                                                                           |
| `consent`        | yes      | Must be `true`: you attest the person consented to the check.                                                                                                                                                                                                                                                                                                                                                                     |
| `requestId`      | no       | Your idempotency key. A retry with the same value returns the same check instead of running (and billing) a second one. Recommended.                                                                                                                                                                                                                                                                                              |
| `externalUserId` | no       | Your own reference for the person. A verified check is saved on the customer record with that reference.                                                                                                                                                                                                                                                                                                                          |
| `createEntity`   | no       | Defaults to `true`: a verified check is saved as a customer record. Without `externalUserId`, it is saved on the record that already holds this ID number, or as a new record. Send `false` to keep the result in spot-check history only. If you later send the same ID number with your own reference (a verification, a check or the entity API), the record created here is renamed to that reference rather than duplicated. |

```bash
curl -X POST https://api.toden.co/api/kyc/checks/individual \
  -H "Authorization: Bearer sk_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "country": "NG",
    "idType": "bvn",
    "idNumber": "12345678901",
    "userData": { "firstName": "John", "lastName": "Doe" },
    "consent": true,
    "requestId": "check-user-42-2026-08-20"
  }'
# → 202 { "verificationId": "cmt…", "status": "pending" }
```

Then read the result:

```
GET /api/kyc/checks/individual/:id
```

```json
{
  "check": {
    "id": "cmt…",
    "status": "verified",
    "country": "NG",
    "idType": "bvn",
    "idNumber": "12345678901",
    "result": {
      "firstName": "JOHN",
      "lastName": "DOE",
      "dateOfBirth": "1990-01-01",
      "dataMatch": true,
      "facialMatch": { "match": true, "confidence": 85 }
    },
    "govRecord": { "…": "customer-safe record extract" },
    "media": { "selfie": "https://api.toden.co/api/kyc/verifications/…/media/selfie" },
    "chargedAmount": "0.0500",
    "createdAt": "…",
    "completedAt": "…"
  }
}
```

`status` is `pending` until processing finishes, then `verified`, `failed`, `not_found` or `error` with `reason` and a stable [`reasonCode`](/get-started/errors). `result` is present on `verified` only.

## Business checks

```
POST /api/kyc/checks/business
```

| Field                | Required | Description                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| -------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `country`            | yes      | ISO-2 country code (about 48 registry countries are supported).                                                                                                                                                                                                                                                                                                                                                                             |
| `registrationNumber` | yes      | The registration number (e.g. `RC123456`).                                                                                                                                                                                                                                                                                                                                                                                                  |
| `registrationName`   | no       | The registered name, cross-checked against the registry when given.                                                                                                                                                                                                                                                                                                                                                                         |
| `subdivisionCode`    | maybe    | ISO 3166-2 region (e.g. `US-DE`) — **required** for the countries whose registry is split by region (US, IN, CA, AE) and rejected elsewhere.                                                                                                                                                                                                                                                                                                |
| `product`            | no       | The check product; defaults to the standard business check. Nigeria adds tax-related products.                                                                                                                                                                                                                                                                                                                                              |
| `consent`            | yes      | Must be `true`.                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `requestId`          | no       | Your idempotency key, as above.                                                                                                                                                                                                                                                                                                                                                                                                             |
| `externalUserId`     | no       | Your own reference for the business. A verified check is saved on the customer record with that reference.                                                                                                                                                                                                                                                                                                                                  |
| `createEntity`       | no       | Defaults to `true`: a verified check is saved as a customer record. Without `externalUserId`, it is saved on the record that already holds this registration number, or as a new record. Send `false` to keep the result in spot-check history only. If you later send the same ID number with your own reference (a verification, a check or the entity API), the record created here is renamed to that reference rather than duplicated. |
| `sandboxOutcome`     | no       | `verified` or `not_found` — pins the canned result outside production. Silently ignored on live keys.                                                                                                                                                                                                                                                                                                                                       |

The detail (`GET /api/kyc/checks/business/:id`) returns the registry's answer as `businessRecord`: company particulars, status, share capital and key personnel in a customer-safe extract, plus `businessName`, the `product`, and the region the registry was asked about.

## History

```
GET /api/kyc/checks/individual
GET /api/kyc/checks/business
```

Paginated, newest first, scoped to your organisation and the key's environment. Query parameters: `status` (`pending` / `verified` / `failed` / `not_found` / `error`), `country`, `idType` (individual) or `product` (business), `from` / `to` (ISO dates), `page`, `pageSize` (max 100). Rows are light — identifiers, status, cost, timestamps and `initiatedVia` (`api` or `dashboard`) — with the full result on the detail endpoints.

A check you no longer want in your history can be removed with `DELETE /api/kyc/checks/individual/:id` or `DELETE /api/kyc/checks/business/:id`. See [Delete records](/user-verification/server-api/manage-records): the delete is soft, and a check that is still running is refused with `409 check_in_progress`.

## Errors

| Status | Code                                                                                                            | Meaning                                                                                          |
| ------ | --------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| 400    | `invalid_input`                                                                                                 | The body failed validation, or a slot was sent both as `mediaIds` and `images`.                  |
| 400    | `product_unsupported`                                                                                           | That product is not offered for the country.                                                     |
| 400    | `subdivision_required` / `subdivision_unsupported` / `subdivision_unknown`                                      | The registry-region rule above.                                                                  |
| 400    | `invalid_image` / `unsupported_media_type` / `image_too_large` / `image_url_not_allowed` / `image_fetch_failed` | An inline image problem — same rules as [face match](/user-verification/server-api/face-match).  |
| 402    | `insufficient_credits`                                                                                          | Your balance cannot cover the check.                                                             |
| 403    | `spot_checks_disabled` / `business_checks_disabled`                                                             | The module is not enabled for your organisation.                                                 |
| 403    | `id_type_not_enabled`                                                                                           | The ID type is not granted to your organisation, or the required feature is disabled.            |
| 403    | `spot_check_unavailable`                                                                                        | The ID type is temporarily switched off for spot checks.                                         |
| 403    | `secret_key_required`                                                                                           | A publishable key was used; this surface is secret-key only.                                     |
| 403    | `business_not_approved`                                                                                         | A live key before KYB approval.                                                                  |
| 422    | `only_test_ids_allowed`                                                                                         | A sandbox key sent a real ID number; use the published [test IDs](/get-started/sandbox-testing). |
| 429    | `rate_limited`                                                                                                  | The hourly verification cap was reached; retry later.                                            |