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

# Upload media

> POST /upload: store a document, selfie, or liveness file and get a mediaId.

```
POST /api/kyc/upload
```

Uploads a single capture file (document image, selfie, or video) and returns a `mediaId`. You then reference these IDs in [`POST /verify`](/user-verification/server-api/create-verification). Number-only verifications (e.g. BVN) don't require any upload.

**Authentication:** `Authorization: Bearer pk_…` (required).
**Content type:** `multipart/form-data`.
**Production note:** like verify, this endpoint requires an [approved business](/get-started/environments#production) for `pk_live_` keys.

## Form fields

| Field  | Required | Description                                |
| ------ | -------- | ------------------------------------------ |
| `file` | yes      | The raw file bytes.                        |
| `type` | yes      | What the file is: one of the values below. |

### Allowed `type` values

`document_front`, `document_back`, `selfie`, `document_front_video`, `document_back_video`, `liveness_video`, `proof_of_address`, `business_document`, `address_photo`, `auth_reference`

`auth_reference` is the reference face photo for a biometric-authentication session: upload it here, then pass its `mediaId` as `faceReferenceMediaId` on [`POST /api/kyc/sessions`](/user-verification/server-api/create-session). It is never sent by an applicant mid-flow.

### Allowed MIME types

`image/jpeg`, `image/png`, `image/webp`, `video/webm`, `video/mp4`. Proof-of-address and business documents also accept `application/pdf`.

### Limits

Maximum file size is **25 MB**. Uploaded files are held with a short TTL and are only retained permanently once referenced by a verification. Orphaned uploads are discarded automatically.

## Request

```bash
curl "https://api.toden.co/api/kyc/upload" \
  -H "Authorization: Bearer $TODEN_KEY" \
  -F "type=document_front" \
  -F "file=@./id-front.jpg"
```

## Response `200 OK`

```json
{ "mediaId": "media_01j9abc..." }
```

Pass the returned IDs to verify under `mediaIds`, keyed by capture slot:

```json
{
  "mediaIds": {
    "documentFront": "media_01j9abc...",
    "selfie": "media_01j9def..."
  }
}
```

## Errors

| Status | Body                                       | Cause                      |
| ------ | ------------------------------------------ | -------------------------- |
| `400`  | `{ "error": "file is required" }`          | No `file` field sent.      |
| `400`  | `{ "error": "type must be one of …" }`     | Missing or invalid `type`. |
| `400`  | `{ "error": "mimeType one of …" }`         | Unsupported MIME type.     |
| `400`  | `{ "error": "File too large (max 25MB)" }` | File exceeds the size cap. |
| `401`  | `{ "error": "Invalid API key" }`           | Auth failed.               |

See [Errors](/get-started/errors) for the complete reference.