---
title: "Upload one or more documents for async parse + chunk + embed (T383)"
method: POST
path: "/api/documents"
tags: ["Documents"]
---

# Upload one or more documents for async parse + chunk + embed (T383)

`POST /api/documents`

## Request

- Base URL: `http://localhost:38200`
- URL: `http://localhost:38200/api/documents`
- Auth: one of:
  - HTTP bearer
  - API key in cookie `token`

Multipart intake. Each accepted file's real MIME type is sniffed from magic bytes (never the filename or client Content-Type). Files are deduped on (tenant, external_id, sha256) and one `document-parse` pg-boss job is enqueued per newly-accepted file.

## Response `202`

Files accepted; parse jobs enqueued (or skipped as duplicates).

- object
  - `jobs` object[]
    - `fileId` string
    - `contextId` integer
    - `jobId` string, nullable
    - `statusUrl` string, nullable
    - `filename` string
    - `mime` string
    - `skipped` boolean
  - `rejected` object[]
    - `filename` string
    - `reason` string

## Other responses

- `400`: No files uploaded, or an invalid multipart payload.
- `401`: Missing or invalid credentials.
- `413`: A file exceeded the per-file byte limit.

---

[API](https://skmtc.dev/contextq/apis/contextq-api.md) · [All operations](https://skmtc.dev/contextq/apis/contextq-api/llms.txt) · [OpenAPI document](https://skmtc.dev/contextq/apis/contextq-api/revisions/7afc44056a22?raw)
