# Add a knowledge-base document

`POST https://api.morevoice.ai/v1/kb/documents`

Adds a document from a file (JSON with base64, or multipart/form-data with a `file` part, ≤ 25 MB), a public URL, or text, and indexes it in the background: answers 202 with the document `pending`. Poll it until `status` is `ready` (searchable) or `error`. Beyond the plan's knowledge-base storage: 402 plan_limit.

Authenticate with a secret API key: `Authorization: Bearer $MOREVOICE_API_KEY`.

Operation ID: `kb_documents_create`.

## Parameters

### Headers

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `MoreVoice-Version` | `string` | no | The API version to use for this request. Defaults to the version the API key is pinned to. |
| `Idempotency-Key` | `string` | no | A unique key (for example a UUID) that makes this request safe to retry: for 24 hours, a retry with the same key and parameters returns the first response instead of acting twice. |

## Request body

Required, `application/json` or `multipart/form-data`.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `file` | `object` | no | A file to upload. Or send the request as multipart/form-data with a `file` part. |
| `file.filename` | `string` | yes | Its name; the extension picks the format (.pdf, .docx, .xlsx, .csv, .md, .txt, .html). |
| `file.content_base64` | `string` | yes | The file, base64-encoded (≤ 25 MB decoded). |
| `format` | `"md" \| "txt" \| "csv"` | no | With `text`: how to read it (default md). |
| `text` | `string` | no | Text to index as it is. |
| `title` | `string` | no | Default: the file's name, the page's title, or (text) "Document". |
| `url` | `string` | no | A public web page or file (http/https) to fetch and index. It is fetched again on reingest. |

Example:

```json
{
  "text": "# Opening hours\nSunday–Thursday 08:00–18:00, Friday 08:00–13:00.",
  "title": "Opening hours"
}
```

## Responses

### 202 Accepted

Accepted: the document is indexed in the background. Returns `KbDocument`.

| Field | Type | Description |
| --- | --- | --- |
| `id` | `string` | The document's ID. |
| `object` | `"kb_document"` | — |
| `livemode` | `boolean` | `true` in live mode, `false` in test mode. |
| `title` | `string` | — |
| `kind` | `"pdf" \| "docx" \| "md" \| "txt" \| "csv" \| "xlsx" \| "html" \| "url"` | The format it was read as; `url` for a web page. |
| `source` | `string` | The uploaded file's name, or the URL. |
| `status` | `"pending" \| "processing" \| "ready" \| "error"` | pending → processing → ready (searchable) \| error. Poll the document, or follow `kb.document.*` events. |
| `error` | `string \| null` | Why ingestion failed (status error). |
| `bytes` | `integer` | — |
| `chunk_count` | `integer` | Searchable passages the document was split into. |
| `original_stored` | `boolean` | The original file is kept (encrypted): GET …/content downloads it and reingest re-reads it. |
| `created` | `string` | An ISO-8601 timestamp in UTC. |
| `updated` | `string` | An ISO-8601 timestamp in UTC. |

Example:

```json
{
  "bytes": 184320,
  "chunk_count": 42,
  "created": "2026-11-03T09:14:22.000Z",
  "error": null,
  "id": "kbd_6Nq0Sv3Xa5Cf8Hk1Mp4Rt7",
  "kind": "pdf",
  "livemode": true,
  "object": "kb_document",
  "original_stored": true,
  "source": "price-list-2026.pdf",
  "status": "ready",
  "title": "Price list 2026",
  "updated": "2026-11-03T09:14:31.000Z"
}
```

### 400 Bad Request

The request is invalid: a parameter is missing, malformed or unknown, or the version header is unknown. Returns `ErrorEnvelope`.

### 401 Unauthorized

No valid API key was sent. Returns `ErrorEnvelope`.

### 403 Forbidden

The key may not do this (a missing scope, a plan limit, or a compliance block). Returns `ErrorEnvelope`.

### 409 Conflict

The request conflicts with the object's state, or the Idempotency-Key was reused with other parameters. Returns `ErrorEnvelope`.

### 429 Too Many Requests

Too many requests, or no call capacity right now. Retry after the Retry-After delay. Returns `ErrorEnvelope`.

### 500 Internal Server Error

Something went wrong on MoreVoice's side. Retry with the same Idempotency-Key. Returns `ErrorEnvelope`.

## Code samples

**TypeScript**

```ts
import MoreVoice from "@morevoice/sdk";

const mv = new MoreVoice(); // MOREVOICE_API_KEY from the environment

const kbDocument = await mv.kbDocuments.create({
	text: "# Opening hours\nSunday–Thursday 08:00–18:00, Friday 08:00–13:00.",
	title: "Opening hours",
});
console.log(kbDocument);
```

**Python**

```python
from morevoice import MoreVoice

client = MoreVoice()  # MOREVOICE_API_KEY from the environment

kb_document = client.kb_documents.create({
    "text": "# Opening hours\nSunday–Thursday 08:00–18:00, Friday 08:00–13:00.",
    "title": "Opening hours",
})
print(kb_document)
```

**cURL**

```sh
curl -X POST https://api.morevoice.ai/v1/kb/documents \
  -H "Authorization: Bearer $MOREVOICE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "text": "# Opening hours\nSunday–Thursday 08:00–18:00, Friday 08:00–13:00.",
  "title": "Opening hours"
}'
```
