Documents

Ingest a file into a chunked document

Parses an already-uploaded file and creates one Document split into one or more embedded chunks. The source format is detected from the file's content type: PDFs are parsed page-by-page; text/plain and text/markdown files are read as a single source. How the source is chunked is controlled by chunk_strategy.

A file can only back one Document — a second call with the same file_id returns 409 FILE_ALREADY_INGESTED. To re-process an already-ingested file (e.g. with a different chunk_strategy), use POST /documents/{document_id}/ingest; to ingest the same source under a different path, upload a new copy of the file first.

post/v1/projects/{project_id}/documents/ingest

Request

  • Base URL: https://api.naturali.ai
  • URL: https://api.naturali.ai/v1/projects/{project_id}/documents/ingest
  • Auth: one of:
    • HTTP bearer
    • OAuth 2 (authorization code, authorization URL https://api.naturali.ai/authorize, token URL https://api.naturali.ai/token, scopes: mcp:access)

Query parameters

waitboolean

When omitted or false (default), processing runs in the background and 202 Accepted is returned immediately with status=pending. Pass true to block until processing completes and receive 201 Created with status=ready.

Request body

file_idstring required

ID of the uploaded file. Must be one of application/pdf, text/plain, text/markdown.

path_prefixstring

Path prefix under which to store the document (e.g. /docs/). The filename is appended automatically.

tagsTagBag

Key-value labels on a resource. A flat object of string values — an array, a nested object or a number is rejected with 400 VALIDATION_FAILED, never coerced. Keys are opaque and stored verbatim, so cost_center and costCenter are two different tags. Matched by JSONB containment wherever tags are read: the ?tags= filter and knowledge search.

Keys beginning system. are reserved: the platform writes them to record which conversation, actor, agent and role a row came from, and a write naming one is refused with 400 RESERVED_TAG_KEY. They are read and filtered like any other tag.

The bag is bounded, because every pair reaches the IAM context of every access check on the resource: at most 50 keys, each key at most 128 characters and each value at most 256. A write past a bound — including a merge that would grow the stored bag past the key count — is 400 VALIDATION_FAILED with meta.limit naming the bound it crossed. system.* keys are the platform's and do not count against the 50.

chunk_strategy'page' | 'whole' | 'size'

How to split the source into chunks. page (default) creates one chunk per non-empty page (PDF); for non-paged sources it yields a single chunk. whole joins everything into one chunk. size splits into fixed-size character windows with overlap.

chunk_sizeinteger

Window size in characters when chunk_strategy=size. Defaults to 1000.

chunk_overlapinteger

Overlap in characters between consecutive windows when chunk_strategy=size. Defaults to 200.

session_idstring

Session the ingest runs for. The converter's generation and the chunk embeddings are metered against the session and its actor.

actor_idstring

Actor the ingest runs for when there is no session; metered like session_id. Beside session_id it must be that session's actor, else 400 VALIDATION_FAILED.

Example request

{
  "file_id": "file_V1StGXR8Z5jdHi6B",
  "path_prefix": "/docs/",
  "tags": {
    "team": "finance",
    "env": "prod"
  },
  "chunk_size": 1000,
  "chunk_overlap": 200,
  "session_id": "sess_V1StGXR8Z5jdHi6B",
  "actor_id": "actor_V1StGXR8Z5jdHi6B"
}

Response

Ingestion completed synchronously (only when ?wait=true). The document is fully indexed and ready for search.

idstring

Document ID

file_idstring

Underlying file ID

project_idstring

Project ID

pathstring nullable

Logical path of the document within the project (e.g. /reports/q1.txt)

filenamestring

Original filename

content_typestring

Media type of the source file the document was ingested from. Absent when the underlying file is gone.

sizeinteger

File size in bytes

status'pending' | 'processing' | 'ready' | 'failed' | 'withdrawn'

Ingestion lifecycle state. pending — enqueued; processing — chunks being extracted and embedded; ready — fully indexed; failed — processing error (see the error field on GET /documents/{id}/status); withdrawn — taken out of listings and search, with its chunks dropped, and restorable from an earlier version.

versioninteger

The document's content version, starting at 1. Every write that changes the content or its annotations archives the state it replaced and increments this.

contentstring nullable

Text content (only present on getDocument, and only when status is ready)

chunk_strategy'page' | 'whole' | 'size'

The chunk strategy the document was last (re-)ingested with. Absent when the default (whole) was used — the mapper omits the key rather than sending null.

chunk_sizeinteger

Window size in characters used when chunk_strategy=size. Absent otherwise.

chunk_overlapinteger

Overlap in characters between consecutive windows used when chunk_strategy=size. Absent otherwise.

created_atstring date-time
updated_atstring date-time
chunk_countinteger

Number of chunks created from the file.

Example response

{
  "id": "doc_V1StGXR8Z5jdHi6B",
  "file_id": "file_V1StGXR8Z5jdHi6B",
  "project_id": "proj_V1StGXR8Z5jdHi6B",
  "path": "/reports/q1.txt",
  "filename": "my-doc.txt",
  "content_type": "application/pdf",
  "size": 42,
  "status": "ready",
  "version": 1,
  "content": "The quick brown fox jumps over the lazy dog.",
  "chunk_strategy": "size",
  "chunk_size": 800,
  "chunk_overlap": 120,
  "chunk_count": 10
}

Changes

No recorded changes to this operation across all 1 revision of this API.