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

# Set Up and Use API Upload

> Generate a Bearer Token and upload, query and delete documents in a knowledge base via the HTTP API

> [!TIP]
>
> Open **Admin Menu** > **Knowledge Bases**.

With the **API Upload** data source, external systems (e.g. a DMS, CMS or a custom integration) populate a knowledge base via HTTP calls. The source provides three endpoints: upload a document, query its processing status, and delete a document. Authentication uses a **Bearer Token** that is generated per source in the user interface. For an overview of all source types, see [Knowledge Bases](https://docs.varios-ai.com/en/monthly/admin/knowledgebases/index.md#api-upload).

## Prerequisites

* A saved knowledge base with a source of type **API Upload** (only one such source is allowed per knowledge base).
* The external system must be able to reach the VARIOS AI domain via HTTPS.

## Endpoint and Bearer Token

VARIOS AI generates the Bearer Token as soon as you save the source with **Create source**. You find the endpoint and the token in the edit view of the source, in the **Connection** section:

| Field | Content |
| - | - |
| **API endpoint** | Upload URL of the source, copy it with the copy icon |
| **Bearer Token** | Shown masked, reveal it with the eye icon |

Use **Create new token** and confirm to replace the token, for example if it has fallen into the wrong hands.

> [!WARNING]
>
> Treat the Bearer Token like a password and only share it with the external
> system. After **Create new token**, the previous token becomes invalid
> immediately. Systems that upload with it receive errors until you enter the
> new token there.

## Endpoints

The **API endpoint** shown in the user interface is the upload URL of the source. The source UUID (`{source}`) is part of the path; the status and delete endpoints use the same path with a different suffix.

| Method | Path | Purpose |
| - | - | - |
| `POST` | `/api/knowledgebase-source/{source}/upload` | Upload a document as a file or as text |
| `GET` | `/api/knowledgebase-source/{source}/status` | Retrieve the processing status of a document |
| `DELETE` | `/api/knowledgebase-source/{source}/delete` | Remove a document from the source |

All endpoints respond with JSON and require the header `Authorization: Bearer <token>`.

### Authentication

Every request must include the Bearer Token of the source:

```http theme={null}
Authorization: Bearer vrai_...
```

Authentication failures return HTTP status `401` with the header `WWW-Authenticate: Bearer`. The JSON body names the cause in `errorMessage`. The following example shows a token mismatch:

```json theme={null}
{
  "success": false,
  "errorMessage": "Invalid API secret"
}
```

### External identifier

Each document is identified within the source by the `externalIdentifier` parameter. Use a stable, unique identifier from your system (e.g. the document ID in the source system). You use the same identifier later for the status query and for deletion.

## Upload a document

`POST /api/knowledgebase-source/{source}/upload`

**externalIdentifier** `string` *required*

Unique identifier of the document in the external system. Each identifier may
only be used once per source. An empty identifier is rejected. Can be passed
as a query parameter or as a form field.

**resource** `file`

The file to upload (`multipart/form-data`). Required if no `text` is
provided.

**text** `object`

Text upload as JSON (`application/json`). Required if no file is provided.

**Properties**

**text.content** `string` *required*

Content of the document. Empty or whitespace-only content is rejected.

**text.name** `string`

File name without extension. The text is stored as a file named
`<name>.txt`. Without a name, VARIOS AI uses the external identifier.

The request must contain **either** a file in `resource` **or** a `text` object with non-empty `text.content`. If both a file and text are provided, the text is used.

```bash File upload theme={null}
curl -X POST 'https://your-domain.com/api/knowledgebase-source/<source>/upload?externalIdentifier=doc-4711' \
  -H 'Authorization: Bearer <token>' \
  -F 'resource=@/path/to/manual.pdf'
```

```bash Text upload theme={null}
curl -X POST 'https://your-domain.com/api/knowledgebase-source/<source>/upload?externalIdentifier=faq-42' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{"text": {"content": "Answers to frequently asked questions ...", "name": "faq-support"}}'
```

```json Success theme={null}
{
  "success": true
}
```

```json Error theme={null}
{
  "success": false,
  "errorMessage": "A document with the external identifier \"doc-4711\" and this source already exists."
}
```

The endpoint answers errors with `"success": false` and a matching HTTP status:

| Status | Meaning |
| - | - |
| `400` | Invalid request, for example an empty external identifier or no document |
| `401` | Authentication failed |
| `404` | The source is unknown or not a source of type **API Upload** |
| `405` | Wrong HTTP method. The `Allow` header names the right one. |
| `409` | The identifier or the content already exists in the source, or a parallel request with the same identifier is still running |
| `422` | The document violates the source settings, for example the file extension or the file size |

Before saving, the API validates the document against the source configuration:

* **External identifier:** If a document with the same identifier already exists in this source, the upload is rejected. Delete the document first if you want to replace it.
* **Content:** If a document with identical content already exists in this source, the upload is rejected.
* **File extensions:** The extension must be included in the source's **File Extensions** setting. For text uploads this is always `txt`.
* **Maximum file size:** The document must not exceed the **Maximum file size (MB)** setting.
* **Empty documents:** Documents without content are rejected.

> [!NOTE]
>
> After a successful upload, the document appears in the source under
> **Documents** and is then processed and embedded – just like
> with all other source types.

## Query the status

`GET /api/knowledgebase-source/{source}/status`

**externalIdentifier** `string` *required*

Identifier that was used for the upload.

```bash cURL theme={null}
curl 'https://your-domain.com/api/knowledgebase-source/<source>/status?externalIdentifier=doc-4711' \
  -H 'Authorization: Bearer <token>'
```

```json Success theme={null}
{
  "success": true,
  "status": "done"
}
```

**status** `string` *required*

Processing status of the document for the embedding model of the knowledge
base.

| Value | Meaning |
| - | - |
| `in_progress` | Document was accepted; processing or embedding is still running. |
| `done` | Document was embedded successfully and is available for search. |
| `error` | Processing failed (e.g. file format, read error). |
| `not_existing` | No document exists in the source for this identifier. |

> [!TIP]
>
> Poll the status after the upload at intervals until `done` or `error` is
> returned. On `error`, you can delete the document and upload a corrected
> version.

## Delete a document

`DELETE /api/knowledgebase-source/{source}/delete`

**externalIdentifier** `string` *required*

Identifier that was used for the upload.

```bash cURL theme={null}
curl -X DELETE 'https://your-domain.com/api/knowledgebase-source/<source>/delete?externalIdentifier=doc-4711' \
  -H 'Authorization: Bearer <token>'
```

```json Success theme={null}
{
  "success": true
}
```

```json Error theme={null}
{
  "success": false,
  "errorMessage": "No document found for source <source> and external identifier doc-4711"
}
```

The document is removed from the source and is no longer available in the knowledge base. The same external identifier can then be used again for a new upload.

If no document exists for the identifier, the endpoint responds with HTTP status `404`. If another request with the same identifier is still running, it responds with `409`.

## Example: Update a document

The API has no dedicated update endpoint. To ingest a changed document, combine delete and upload with the same identifier:

**1. Delete the old document**

`DELETE .../delete?externalIdentifier=doc-4711`

**2. Upload the new version**

`POST .../upload?externalIdentifier=doc-4711` with the new file or text.

**3. Check the status**

`GET .../status?externalIdentifier=doc-4711` until `done` is returned.

## Common Errors and Solutions

| Error message | Cause | Solution |
| - | - | - |
| `Authorization header missing` (HTTP 401) | The `Authorization` header is missing. | Send the header `Authorization: Bearer <token>`. |
| `Authorization header is not a Bearer token` (HTTP 401) | The header is not in the format `Bearer <token>`. | Check the `Bearer` prefix and the space before the token. |
| `Knowledgebase source could not be resolved` (HTTP 404) | The source identifier in the path is unknown. | Copy the **API endpoint** from the **Connection** section of the source. |
| `API secret not configured` (HTTP 401) | No token is stored for the source. | Select **Create new token** in the source. |
| `Invalid API secret` (HTTP 401) | The token does not match the token of the source. | Use the current token; after **Create new token**, only the new token is valid. |
| `The external identifier must not be empty.` (HTTP 400) | `externalIdentifier` is missing or empty. | Send an identifier. |
| `No valid document provided` (HTTP 400) | Neither a file in `resource` nor a `text` object with non-empty `content` was sent. | Send a file as `multipart/form-data` or text as JSON. |
| `A document with the external identifier "…" and this source already exists.` (HTTP 409) | The identifier is already used in this source. | Delete the document first or use a different identifier. |
| `A document with the same content already exists in this source.` (HTTP 409) | A document with identical content already exists. | No re-upload needed; check the content if necessary. |
| `The file extension "…" is not allowed. …` (HTTP 422) | The extension is not included in **File Extensions**. | Extend the source's **File Extensions** setting or convert the file. |
| `The file size … exceeds the configured maximum of … bytes.` (HTTP 422) | The document is larger than **Maximum file size (MB)**. | Increase the setting or reduce/split the document. |
| `The document is empty.` (HTTP 422) | The document has no content. | Upload a document with content. |
| `No document found for source … and external identifier …` (HTTP 404) | When deleting, no document exists in the source for the identifier. | Check the identifier; the status `not_existing` indicates that no document exists. |
| `Another operation for external identifier "…" on this source is already in progress.` (HTTP 409) | A parallel request with the same identifier is still being processed. | Send the request again later. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.