Skip to content

Reference

Base URL: https://chat.app.urai.dev/api/v1/knowledge. Every request carries Authorization: Bearer sk-urai-....

{reference} is a collection slug or a collection UUID. {id} is a document UUID.

Method and path Purpose
GET /collections List collections. Paged.
POST /collections Create a collection. Returns 201.
GET /collections/{reference} Read one collection.
PATCH /collections/{reference} Change the name or the description.
DELETE /collections/{reference} Delete the collection and everything in it. Returns 204.
GET /collections/{reference}/documents List documents. Paged, and filtered by status.
POST /collections/{reference}/documents Push a file. Returns 202, or 200 for a file already there.
POST /collections/{reference}/documents/text Push Markdown or plain text. Returns 202.
GET /documents/{id} Read one document.
GET /documents/{id}/text The extracted Markdown, as text/markdown.
GET /documents/{id}/content The original bytes.
POST /documents/{id}/reprocess Index the document again. Returns 202.
DELETE /documents/{id} Delete the document and its passages. Returns 204.
POST /search Search passages across collections.
Parameter Endpoints Notes
limit The two list endpoints Default 50, highest 500. A value outside the range is corrected.
offset The two list endpoints Default 0.
status GET /collections/{reference}/documents pending, processing, ready, or failed.
reextract POST /documents/{id}/reprocess true reads the original bytes again and is charged for.
{ "data": [], "total": 128, "limit": 50, "offset": 0 }

total counts everything that matches, and data holds this page. Search does not use this envelope. See Search documents.

{
"id": "9b1c8d2e-...",
"slug": "billing-policies",
"name": "Billing policies",
"description": "Refunds, plans, invoices",
"documents": { "ready": 12, "pending": 1, "failed": 0, "total": 13, "bytes": 8419203 },
"created_at": "2026-08-15T09:12:00Z",
"updated_at": "2026-08-15T09:12:00Z"
}
Field Notes
slug The stable handle. A rename does not change it.
documents Counts from a summary that refreshes on a timer, so they lag. pending covers pending and processing. bytes is the size of the ready documents.
{
"id": "3f2a7c19-...",
"collection_id": "9b1c8d2e-...",
"name": "billing-policy-2026.pdf",
"mime_type": "application/pdf",
"size_bytes": 184320,
"status": "ready",
"page_count": 18,
"chunk_count": 96,
"tags": ["policy", "2026"],
"source": "api",
"created_at": "2026-08-15T09:14:02Z",
"updated_at": "2026-08-15T09:14:44Z",
"indexed_at": "2026-08-15T09:14:44Z"
}
Field Notes
status pending, processing, ready, or failed.
error Why the read failed. Present when status is failed.
page_count Present for PDF and PowerPoint. Word and Markdown have no pages.
chunk_count Passages search can return. Zero until the document is ready.
source api for this API, upload for the app, connector for a connector.
indexed_at When the document became searchable.

A field with no value is left out. Read status first, then the field that belongs to that status.

{
"query": "refund window",
"results": [
{
"document": { "id": "...", "name": "...", "collection_id": "...", "collection": "..." },
"score": 0.82,
"passages": [
{ "seq": 41, "page": 4, "section": "Billing > Refunds", "reference": "p. 4", "score": 0.82, "content": "..." }
]
}
],
"limit": 10,
"offset": 0,
"has_more": true
}

limit and offset count passages. There is no total. page and section appear only when the format has them.

The error shape is the one the Chat Completions API uses.

{
"error": {
"message": "No collection \"billing\" in this organization",
"type": "invalid_request_error",
"code": "collection_not_found"
}
}
Status Code Cause
400 missing_name POST /collections had no name.
400 collection_exists Another collection already has that name.
400 invalid_name Urai cannot make a slug from the name.
400 invalid_collection_reference The {reference} in the path is neither a UUID nor a valid slug.
400 invalid_status The status filter has an unknown value.
400 missing_file An upload had no part with a filename.
400 too_many_files More than one file in the request.
400 invalid_body Urai could not read the multipart body.
400 empty_document The file or the text has no content.
400 not_ready GET /documents/{id}/text before the document is ready.
400 already_processing A reprocess while the document is being processed.
400 missing_query POST /search had an empty query.
400 unknown_collection collections names a collection that does not exist. The message lists the valid slugs.
400 document_not_found document_ids names a document outside the collections being searched.
401 missing_api_key No Authorization header.
401 invalid_api_key Urai does not recognise the key.
401 api_key_disabled Someone disabled the key.
401 expired_api_key The key is past its expiry.
403 product_not_enabled The key is not enabled for the knowledge product.
404 collection_not_found No such collection in this organization.
404 not_found No such document in this organization.
404 no_extracted_text The document has no stored Markdown.
404 no_stored_file The document has no stored original.
415 unsupported_file_type No reader handles this file type.
500 (none) Server error. Urai logs the detail and does not return it.
502 (none) The search could not run.

A document Urai accepts and then cannot read is not an HTTP error. The upload returns 202, and the document ends as failed with the reason in error.

A collection or a document in another organization is reported as absent. One organization cannot learn that another one’s collection exists.

Limit Value
Files in one upload 1
Size of one file 100 MB
Collections or documents in one page 50 by default, 500 at most
Passages in one search 8 by default, 100 at most
Passages in one search_documents tool call 8 by default, 25 at most