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.
Endpoints
Section titled “Endpoints”| 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. |
Query parameters
Section titled “Query parameters”| 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. |
The list envelope
Section titled “The list envelope”{ "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.
The collection object
Section titled “The collection object”{ "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. |
The document object
Section titled “The document object”{ "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.
The search response
Section titled “The search response”{ "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.
Errors
Section titled “Errors”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.
Limits
Section titled “Limits”| 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 |