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

# Upload Documents

> Upload text documents to a text namespace. Embeddings are computed via Ollama. Returns an async job id.

## Overview

Upload one or more documents to a **text** namespace. Each document is embedded with the configured Ollama model and stored for semantic search.

The upload runs asynchronously. Poll [Upload job status](/on-prem/api-references/data/upload-job-status) with the returned `job_id`.

<Note>
  Any extra fields on each document object (for example `team`, `source`) are stored as metadata and can be used in search filters.
</Note>

## Path parameters

<ParamField path="namespace_name" type="string" required>
  Target text namespace.
</ParamField>

## Headers

<ParamField header="Content-Type" type="string" required>
  Must be `application/json`
</ParamField>

## Body

<ParamField body="documents" type="array" required>
  Non-empty array of document objects.
</ParamField>

<ParamField body="documents[].id" type="string" required>
  Item id, unique within this namespace.
</ParamField>

<ParamField body="documents[].text" type="string" required>
  Document text to embed and store.
</ParamField>

<ParamField body="documents[].{metadata}" type="any">
  Optional additional keys on each document are saved as metadata (for example `"team": "ai"`).
</ParamField>

<RequestExample>
  ```bash theme={null}
  curl -X POST "http://localhost:8080/namespaces/my-documents/documents" \
    -H "Content-Type: application/json" \
    -d '{
      "documents": [
        {
          "id": "doc-1",
          "text": "Moorcheh on-prem retrieval test",
          "team": "ai"
        }
      ]
    }'
  ```
</RequestExample>

## Response fields

<ResponseField name="status" type="string">
  Request outcome. `"success"` when the upload job was started; `"failure"` on error.
</ResponseField>

<ResponseField name="message" type="string">
  Human-readable result or error description.
</ResponseField>

<ResponseField name="job_id" type="string">
  Id of the async upload job. Poll [Upload job status](/on-prem/api-references/data/upload-job-status) with this value. Present when the upload job was started.
</ResponseField>

<ResponseField name="namespace_name" type="string">
  Namespace the documents are being uploaded to. Present when the upload job was started.
</ResponseField>

<ResponseField name="total" type="number">
  Number of documents accepted into the upload job. Present when the upload job was started.
</ResponseField>

<ResponseField name="items" type="number">
  Current total item count on the instance. Present on **409** item limit errors.
</ResponseField>

<ResponseField name="max_items" type="number">
  Global item cap for this instance. Present on **409** item limit errors.
</ResponseField>

<ResponseField name="requested_new" type="number">
  Number of new item ids in the request that would exceed the cap. Present on **409** item limit errors.
</ResponseField>

<ResponseExample>
  ```json 202 - Accepted theme={null}
  {
    "status": "success",
    "message": "Documents upload started. Poll job status for progress.",
    "job_id": "job-a0e3d54b9d0d4616949474697308a39c",
    "namespace_name": "my-documents",
    "total": 1
  }
  ```

  ```json 400 - Empty documents array theme={null}
  {
    "status": "failure",
    "message": "Bad Request: documents must be a non-empty array."
  }
  ```

  ```json 400 - Missing id or text theme={null}
  {
    "status": "failure",
    "message": "Bad Request: each document must include non-empty 'id' and 'text'."
  }
  ```

  ```json 400 - Wrong namespace type theme={null}
  {
    "status": "failure",
    "message": "Namespace 'my-embeddings' is not a text namespace."
  }
  ```

  ```json 404 - Namespace not found theme={null}
  {
    "status": "failure",
    "message": "Namespace 'my-documents' not found."
  }
  ```

  ```json 409 - Item limit exceeded theme={null}
  {
    "status": "failure",
    "message": "Item limit exceeded: max 100000, current 99999, requested 2 new items.",
    "items": 99999,
    "max_items": 100000,
    "requested_new": 2
  }
  ```
</ResponseExample>

## Important Notes

<Warning>
  * At most **100,000 items** total across all namespaces
  * **409** is returned before the job starts if new ids would exceed the cap
  * Re-uploading an existing id in the same namespace updates the item and does not consume extra quota
</Warning>

## Next Steps

* [Upload job status](/on-prem/api-references/data/upload-job-status)
* [Search](/on-prem/api-references/search/query)

## Related

* [CLI: moorcheh upload-documents](/on-prem/cli/data/upload-documents)
* [Python: documents.upload()](/on-prem/python-client/data/upload-documents)
