Skip to content

Overview

The Knowledge API gives you the retrieval layer on its own. You create collections, you push documents into them, and you search them. Urai returns the matching passages with a citation for each one.

Use it when your own code builds the prompt, renders a result list, or keeps a collection in step with another system. When you want a finished answer instead, name the search_documents tool in a completion, and Urai does the search for you.

The API works on the same collections as the Knowledge page in the app. A document you upload in the browser is searchable here, and the reverse.

Your uraijs code reads the same documents. A tool or a workflow imports urai:knowledge and streams the whole text of a document, at any size, without it passing through a model. See Read documents from code.

https://chat.app.urai.dev/api/v1/knowledge

Every path on this page is relative to that base URL.

Send an API key as a bearer token, the same key the Chat Completions API uses.

Authorization: Bearer sk-urai-...

The key sets the organization. Every collection and every document you can reach belongs to that organization, and one from another organization reads as absent.

An organization admin can limit a key to some products. A key with no product list reaches everything, and that is what every key made in the app has. A key that names extraction alone gets 403 and the code product_not_enabled here, because knowledge and extraction are sold apart.

  1. You create a collection, or you use one that exists.
  2. You push a file or a block of text into it. Urai replies with 202 and the status pending.
  3. Urai reads the document, splits it into passages, and indexes them. Large files take tens of seconds.
  4. The status becomes ready, and the passages answer searches.

Poll GET /documents/{id} until the status is ready or failed. Nothing is searchable before that.

Create the collection:

Terminal window
curl https://chat.app.urai.dev/api/v1/knowledge/collections \
-H "Authorization: Bearer $URAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Billing policies", "description": "Refunds, plans, invoices" }'
{
"id": "9b1c8d2e-...",
"slug": "billing-policies",
"name": "Billing policies",
"description": "Refunds, plans, invoices",
"documents": { "ready": 0, "pending": 0, "failed": 0, "total": 0, "bytes": 0 },
"created_at": "2026-08-15T09:12:00Z",
"updated_at": "2026-08-15T09:12:00Z"
}

Push a document into it:

Terminal window
curl https://chat.app.urai.dev/api/v1/knowledge/collections/billing-policies/documents \
-H "Authorization: Bearer $URAI_API_KEY" \
-F "file=@billing-policy-2026.pdf" \
-F "tags=policy"

Search it when the status is ready:

Terminal window
curl https://chat.app.urai.dev/api/v1/knowledge/search \
-H "Authorization: Bearer $URAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "refund window for annual plans",
"collections": ["billing-policies"]
}'

Every path that takes {reference} accepts the slug or the UUID. The slug comes from the name, and a rename does not change it. Hard-code the slug in an integration, and the same code works in every environment.

/collections/billing-policies
/collections/9b1c8d2e-4a77-4c31-9f60-b1a2c3d4e5f6

The collections field of a search is different. It matches the slug or the display name, and it does not take a UUID. See Search documents.

GET /collections and the document lists return the same envelope.

{ "data": [], "total": 128, "limit": 50, "offset": 0 }

total is what exists, and data is the page you asked for. The default limit is 50 and the highest is 500. A limit or an offset outside the range is corrected, not refused, and the reply tells you what was used.

Search pages differently, because the index cannot count matches honestly. It answers has_more instead of total.

Format Extensions
PDF .pdf
Word .docx
PowerPoint .pptx
Markdown and plain text .md, .markdown, .txt, .text

Urai reads the type from the file extension first, then from the content type. Any other type is rejected with 415 before anything is stored.

Scanned PDF pages go through OCR. When no text can be read at all, the document ends as failed and says so in error.

Urai searches for keywords and for meaning at the same time, then merges the two rankings. A question that uses none of the words in the document still finds the correct passage.

Each passage carries a reference, such as p. 4 or Billing > Refunds, so your interface can cite the source. Pages appear for PDF and PowerPoint. Word files and Markdown files have no pages.

Three meters, all visible in Usage:

Kind Unit When
knowledge_indexing One page Urai reads a document into a collection. Word and Markdown are counted at 3,000 characters for one page.
knowledge_search One query Each search that reaches the index.
knowledge_storage One GB-day A daily measure of what your collections hold. The month adds up to GB-months.

A search from the app, from the search_documents tool, and from this API are all recorded, and each says where it came from. A document that is already in the collection is not charged for again, and a reprocess that reuses the earlier read is not charged for either.