Knowledge API
Open in CMSThe Knowledge API lets your own systems manage an agent's knowledge documents without opening the CMS. A script, a scheduled job, or another application holding one of the agent's API keys can list documents, upload new ones, follow their processing, activate or deactivate them, and remove them.
Use it when your documents already live somewhere else and you want the agent to stay in sync with that source, for example:
- A document management system (DMS) that pushes every newly approved SOP to the agent.
- A nightly SharePoint export job that uploads changed policies and retires old versions.
- A CI pipeline that publishes product manuals or release notes to the agent whenever they are merged.
The API works on the same documents you see in Knowledge β Documents: a document uploaded through the API appears there too, and goes through the same processing. It covers documents (PDF, Markdown, and plain text) only, not websites or videos.
In the Teach Your Agent example, Kirana Group keeps its SOPs in its own DMS. Instead of uploading SOP-FIN-007 "Project and Capex Approval Policy" to Atlas by hand, the DMS sends it through the Knowledge API as soon as Finance approves a new version.
Before you start
- Service agents only. The Knowledge API is available for service agents. A personal agent cannot switch it on, and switching an agent from Service to Personal turns the API off and revokes its keys. See Personal vs Service Agents if you are not sure which kind your agent is.
- Who can turn it on. Agent contributors and organization Owners and Admins.
- Off by default. Every agent starts with the Knowledge API switched off. Nothing can call it until someone switches it on and creates a key.
- Read Documents first. The API follows the same rules for statuses, processing modes, authors, and permissions.
- Check Knowledge β Retrieval: the agent only answers from documents when Enable reference is on. See Retrieval.
Turn on the API and create a key
In the CMS, open Knowledge β Knowledge API in your agent's sidebar.
-
Switch the Knowledge API on. The page shows the base URL for this agent; copy it, you need it in every request.
-
The agent has two key slots, Primary and Secondary. In one of them, create a key and fill in:
Field What to enter Name A label that tells you which system uses the key, for example Kirana DMS sync. Up to 80 characters.Scopes What the key is allowed to do (see below). Expiry 7, 14, 30, 90, 180, or 365 days, or never. After that date the key stops working. -
Create the key and copy it right away. The full key (it starts with
qk_) is shown only once. Qlar stores only a fingerprint of it, so neither you nor Qlar support can see it again later. Afterwards the page shows only the last four characters, the scopes, the expiry date, and when the key was last used. -
Store the key in your system's secret store (for example a vault, a pipeline secret, or an environment variable on the server that runs the sync).
Scopes
| Scope | Allows | Notes |
|---|---|---|
read | Listing documents, reading a document's status, and reading its processing log. | Always included. |
write | Uploading documents, activating, deactivating, retrying, cancelling, and deleting them. | On by default. Leave it off for a key that only monitors. |
purge | Permanently removing a document. | Off by default. Purge cannot be undone. Give it only to a key that really needs to clean up. |
Replace or revoke a key
- Lost a key? You cannot view it again. Create a new key in the same slot. The new key replaces the old one immediately, so any system still using the old key starts getting
401errors. - Revoke a key to stop it at once, for example when it may have leaked or a system is retired. A revoked key cannot be turned back on; create a new one when you need access again.
- Switch the API off to stop all keys of the agent at once. Switching it on again brings back the keys that are still valid.
Rotate a key without downtime
The two slots exist so you can change keys without interrupting your sync:
- Your system uses the Primary key.
- Create a key in the Secondary slot.
- Update your system to use the Secondary key and check that its calls succeed (the key's last-used time and the activity log show it).
- Revoke the Primary key.
Next time, do the same in the other direction. Combined with an expiry, this keeps every key short-lived.
Base URL and authentication
Every endpoint lives under the agent's base URL. It is also shown, ready to copy, on the Knowledge β Knowledge API page:
{base-url} = https://api.qlar.ai/cms/api/knowledge/v1/agents/{agentId}
The examples on this page use two shell variables, so the key never appears in the command itself:
export QLAR_BASE_URL="https://api.qlar.ai/cms/api/knowledge/v1/agents/YOUR_AGENT_ID"
export QLAR_KNOWLEDGE_KEY="qk_..." # load it from your secret store
Send the key in the X-Api-Key header on every request:
X-Api-Key: qk_...
The Primary and Secondary keys work the same way; use whichever is active. A key only works for the agent it was created on.
A missing, wrong, expired, or revoked key, an unknown agent, and an agent whose Knowledge API is switched off all get the same 401 unauthorized answer. This is on purpose: the API does not reveal which agents exist or which part of the key was wrong.
Endpoints
| Method | Path | Scope | What it does |
|---|---|---|---|
GET | /documents | read | List documents |
POST | /documents | write | Upload a document |
GET | /documents/{documentId} | read | Get one document and its status |
GET | /documents/{documentId}/logs | read | Get the processing log |
POST | /documents/{documentId}/activate | write | Activate a document |
POST | /documents/{documentId}/deactivate | write | Deactivate a document |
POST | /documents/{documentId}/retry | write | Process a failed or cancelled document again |
POST | /documents/{documentId}/cancel | write | Stop processing |
DELETE | /documents/{documentId} | write | Delete a document (it stays listed as Deleted) |
POST | /documents/{documentId}/purge | purge | Remove a document permanently |
All paths are relative to {base-url}. Responses are JSON. Times are UTC in ISO 8601 format.
The document object
Most endpoints return a document:
{
"id": "5b7f0e2a-1c3d-4e8f-9a6b-2d4c8e0f1a3b",
"code": "SOP-FIN-007",
"title": "Project and Capex Approval Policy",
"fileType": "PDF",
"status": "Active",
"inProgress": false,
"statusMessage": "Done processing. Text Chunks: 12, Table Chunks: 2. Total: 14",
"chunkingStrategy": "adaptive",
"tag": "finance",
"sourceUri": "https://dms.kirana.example/sop/SOP-FIN-007",
"permissions": [],
"totalChunks": 14,
"activeChunks": 14,
"updatedAt": "2026-11-06T03:15:42Z"
}
| Field | Description |
|---|---|
id | The document ID. Use it in the paths of the other endpoints. |
code | Your unique code for the document within the agent, for example the SOP number. |
title | The document title. |
fileType | PDF, TXT, or MD. |
status | The current status. See Document statuses. |
inProgress | true while the status is still changing by itself. Keep polling until it is false. |
statusMessage | The latest processing message. |
chunkingStrategy | The processing mode used (see the upload parameters). |
tag | Your free-text tag. |
sourceUri | Link to the original document. |
permissions | Permission codes that limit who can get answers from this document. Empty means everyone. |
totalChunks, activeChunks | How many chunks the document was split into, and how many of them are active. |
updatedAt | When the document last changed. |
List documents
Returns the agent's documents, newest first.
GET {base-url}/documents
Query parameters:
| Parameter | Type | Description |
|---|---|---|
status | string | Only documents with this status, for example Active, Processing, or Failed. |
search | string | Text contained in the title. |
code | string | Text contained in the code. |
limit | integer | Page size, 1 to 100. Default: 20. |
cursor | string | The nextCursor value from the previous page. |
Example request:
curl "$QLAR_BASE_URL/documents?code=SOP-FIN&limit=20" \
-H "X-Api-Key: $QLAR_KNOWLEDGE_KEY"
Example response:
{
"items": [
{
"id": "5b7f0e2a-1c3d-4e8f-9a6b-2d4c8e0f1a3b",
"code": "SOP-FIN-007",
"title": "Project and Capex Approval Policy",
"fileType": "PDF",
"status": "Active",
"inProgress": false,
"statusMessage": "Done processing. Text Chunks: 12, Table Chunks: 2. Total: 14",
"chunkingStrategy": "adaptive",
"tag": "finance",
"sourceUri": "https://dms.kirana.example/sop/SOP-FIN-007",
"permissions": [],
"totalChunks": 14,
"activeChunks": 14,
"updatedAt": "2026-11-06T03:15:42Z"
}
],
"nextCursor": null
}
When nextCursor is not null, pass it as cursor to get the next page. On the last page it is null.
Upload a document
Uploads a file and starts processing it right away. When processing finishes, the document becomes Active by itself; you do not need to call activate.
POST {base-url}/documents
Content-Type: multipart/form-data
Form fields:
| Field | Required | Description |
|---|---|---|
file | Yes | The document: PDF (.pdf), plain text (.txt), or Markdown (.md). At most 25 MB. The type is taken from the file name's extension. |
title | No | The document title, up to 300 characters. Default: the file name without its extension. |
code | No | Your unique code within the agent, up to 100 characters, for example SOP-FIN-007. A random code is generated when you leave it out. A code that is already in use is refused with 409 duplicate_code. |
authorCode | No | The code of an author that exists on the agent (see Citations). Default: the author Knowledge API (code KNOWLEDGE-API), which is created automatically the first time. |
chunkingStrategy | No | The processing mode: adaptive (default, Automatic in the CMS), semantic (Fast and basic), skimming (Long structured content), regulatory (Legal documents), or fact-sheet (Short fact sheets). See Processing modes. |
tag | No | A free-text tag. |
sourceUri | No | Link to the original document, shown with citations. |
permissions | No | Permission codes that may see the document, as a JSON array (["finance","management"]) or a comma-separated list (finance,management). Each code must already exist on the agent. See Knowledge Permissions. |
parameters | No | Advanced processing settings as a JSON object. Leave it out to use the defaults, which suit most documents. |
Example request:
curl -X POST "$QLAR_BASE_URL/documents" \
-H "X-Api-Key: $QLAR_KNOWLEDGE_KEY" \
-F file=@sop-fin-007.pdf \
-F code=SOP-FIN-007 \
-F "title=Project and Capex Approval Policy" \
-F authorCode=KG-FIN \
-F tag=finance \
-F sourceUri=https://dms.kirana.example/sop/SOP-FIN-007
Response: 201 Created with the new document, usually in status Processing:
{
"id": "5b7f0e2a-1c3d-4e8f-9a6b-2d4c8e0f1a3b",
"code": "SOP-FIN-007",
"title": "Project and Capex Approval Policy",
"fileType": "PDF",
"status": "Processing",
"inProgress": true,
"statusMessage": "",
"chunkingStrategy": "adaptive",
"tag": "finance",
"sourceUri": "https://dms.kirana.example/sop/SOP-FIN-007",
"permissions": [],
"totalChunks": 0,
"activeChunks": 0,
"updatedAt": "2026-11-06T03:12:08Z"
}
Save the id: you need it to follow the document and to change it later.
Note: processing a document uses AI and costs credits, the same as an upload in the CMS. When your organization is out of credit, the upload is refused with
402 insufficient_credit. This check does not apply when the organization processes knowledge with its own AI model. See How Credits Work.
Get a document
Returns one document with its current status. Use it to poll after an upload or a change.
GET {base-url}/documents/{documentId}
Example request:
curl "$QLAR_BASE_URL/documents/5b7f0e2a-1c3d-4e8f-9a6b-2d4c8e0f1a3b" \
-H "X-Api-Key: $QLAR_KNOWLEDGE_KEY"
Response: the document object.
Get the processing log
Returns the processing (chunking) log of a document, oldest entry first. It is the same log as View log on the document's detail page in the CMS, and the first place to look when a document ends up Failed.
GET {base-url}/documents/{documentId}/logs
Example request:
curl "$QLAR_BASE_URL/documents/5b7f0e2a-1c3d-4e8f-9a6b-2d4c8e0f1a3b/logs" \
-H "X-Api-Key: $QLAR_KNOWLEDGE_KEY"
Example response:
{
"documentId": "5b7f0e2a-1c3d-4e8f-9a6b-2d4c8e0f1a3b",
"status": "Active",
"entries": [
{ "timestamp": "2026-11-06T03:12:10Z", "message": "Routing to document processor" },
{ "timestamp": "2026-11-06T03:12:11Z", "message": "Detected file type: PDF" },
{ "timestamp": "2026-11-06T03:15:40Z", "message": "Done processing. Text Chunks: 12, Table Chunks: 2. Total: 14" }
]
}
Activate a document
Puts a Pending or Inactive document (back) into use. Calling it on a document that is already Active (or activating) changes nothing and is not an error.
POST {base-url}/documents/{documentId}/activate
Example request:
curl -X POST "$QLAR_BASE_URL/documents/5b7f0e2a-1c3d-4e8f-9a6b-2d4c8e0f1a3b/activate" \
-H "X-Api-Key: $QLAR_KNOWLEDGE_KEY"
Response: the document, usually in status Activating or Reactivating with inProgress: true. Poll until it is Active. Any other status is refused with 409 invalid_state.
Deactivate a document
Stops the agent from using an Active document without deleting it. You can activate it again later. Calling it on a document that is already Inactive changes nothing.
POST {base-url}/documents/{documentId}/deactivate
Example request:
curl -X POST "$QLAR_BASE_URL/documents/5b7f0e2a-1c3d-4e8f-9a6b-2d4c8e0f1a3b/deactivate" \
-H "X-Api-Key: $QLAR_KNOWLEDGE_KEY"
Response: the document, in status Deactivating and then Inactive. Any other status is refused with 409 invalid_state.
Retry processing
Processes a Failed or Cancelled document again, with the same file and settings.
POST {base-url}/documents/{documentId}/retry
Example request:
curl -X POST "$QLAR_BASE_URL/documents/5b7f0e2a-1c3d-4e8f-9a6b-2d4c8e0f1a3b/retry" \
-H "X-Api-Key: $QLAR_KNOWLEDGE_KEY"
Response: the document, back in status Processing.
Cancel processing
Stops a document that is still Processing. It ends up Cancelled; you can then retry or purge it.
POST {base-url}/documents/{documentId}/cancel
Example request:
curl -X POST "$QLAR_BASE_URL/documents/5b7f0e2a-1c3d-4e8f-9a6b-2d4c8e0f1a3b/cancel" \
-H "X-Api-Key: $QLAR_KNOWLEDGE_KEY"
Response: the document, in status Cancelled.
Delete a document
Takes the document out of use and marks it Deleted. The record stays in the list (also in the CMS) so you can still see it and purge it later.
DELETE {base-url}/documents/{documentId}
- An Active document is deactivated first. The call waits up to 30 seconds for that; if the document is still deactivating after that, you get
409 invalid_stateand can simply try again. - A Failed or Cancelled document has nothing to delete and is refused with
409 invalid_state: purge it instead. - A document that is still changing (for example Processing) is refused with
409 invalid_state; wait until it has settled, or cancel it. - Deleting a document that is already Deleted changes nothing.
Example request:
curl -X DELETE "$QLAR_BASE_URL/documents/5b7f0e2a-1c3d-4e8f-9a6b-2d4c8e0f1a3b" \
-H "X-Api-Key: $QLAR_KNOWLEDGE_KEY"
Response: the document, in status Deleted.
Purge a document
Removes a document permanently: the record, its chunks, its processing log, its cover, and its source file. This cannot be undone. Requires a key with the purge scope.
POST {base-url}/documents/{documentId}/purge
- An Active, Inactive, or Pending document is deactivated and deleted first, then purged, in one call.
- A document that is still Processing is refused with
409 invalid_state. Cancel it first, or wait until it finishes.
Example request:
curl -X POST "$QLAR_BASE_URL/documents/5b7f0e2a-1c3d-4e8f-9a6b-2d4c8e0f1a3b/purge" \
-H "X-Api-Key: $QLAR_KNOWLEDGE_KEY"
Response: 204 No Content.
Document statuses
The status field uses the same statuses as the badges on the Documents page.
| Status | inProgress | What it means |
|---|---|---|
Initial | true | The record exists and the file is still being stored. |
Processing | true | The document is being split into chunks. The agent cannot use it yet. |
Pending | true | Processing is done; the document is about to be activated. |
Activating | true | The document is being put into use. |
Active | false | The agent uses the document in its answers. |
Deactivating | true | The document is being taken out of use. |
Inactive | false | The agent ignores the document until it is activated again. |
Reactivating | true | An inactive document is being put back into use. |
Failed | false | Processing failed. Read the processing log, then retry or purge. |
Cancelled | false | Processing was cancelled. Retry or purge. |
Deleted | false | The document is deleted and no longer used. It can still be purged. |
A typical life of a document:
- Upload β
Processing - Processing finishes β
PendingβActivatingβActive(all by itself) - Deactivate β
DeactivatingβInactive; Activate βReactivatingβActive - Delete β
Deleted - Purge β gone
If processing fails or is cancelled, the document stops at Failed or Cancelled. From there, retry goes back to step 1, and purge removes it.
Polling
Webhooks are not available yet. To know when a document is ready, poll Get a document every 5 to 10 seconds while inProgress is true. Stop when it is false, then check status: Active means the agent can use it, Failed means you should read the log. Large PDFs processed with the adaptive mode can take several minutes.
Polling much faster does not make processing quicker; it only uses up your rate limit.
Delete versus purge
| Delete | Purge | |
|---|---|---|
| Endpoint | DELETE /documents/{documentId} | POST /documents/{documentId}/purge |
| Scope | write | purge |
| The agent uses the document | No | No |
| The document stays in the list | Yes, as Deleted | No |
| Chunks, log, and file are kept | Yes | No, all removed |
| Can be undone | The record remains, but a deleted document cannot be activated again; upload the file again to use it | No, never |
| Use it for | Retiring a document while keeping a trace of it | Removing it for good, for example outdated or wrongly uploaded content, or to free the code |
A common sync pattern: when a new version of an SOP is approved, upload it with a new code (for example SOP-FIN-007-v4), wait until it is Active, then delete the previous version. Purge old versions later, in a separate clean-up job that has its own key with the purge scope.
Limits
| Limit | Value | When exceeded |
|---|---|---|
| File size | 25 MB per file | 413 file_too_large |
| File types | PDF, TXT, MD | 415 unsupported_file_type |
| Requests | 120 per minute per key | 429 rate_limited |
| Failed authentication | 20 per minute per IP address | 429 rate_limited for that IP address |
| Uploads | 500 per day per agent (resets at 00:00 UTC) | 429 rate_limited |
Every 429 answer carries a Retry-After header with the number of seconds to wait. Wait at least that long before you try again; do not retry in a tight loop.
Uploads use credits; when your organization is out of credit, uploads are refused with 402 insufficient_credit (see Upload a document).
Errors
Errors use the HTTP status code and a JSON body with a machine-readable code and a human-readable message:
{
"error": {
"code": "invalid_state",
"message": "Only an Active document can be deactivated; it is Processing."
}
}
Build your logic on code. The message can change and is meant for people.
| HTTP status | code | Meaning |
|---|---|---|
| 400 | invalid_request | A parameter is missing or not valid, for example no file, an unknown chunkingStrategy, an author or permission code that does not exist on the agent, or a cursor that is not valid. |
| 401 | unauthorized | The key is missing, wrong, expired, or revoked, the agent does not exist, or its Knowledge API is switched off. |
| 402 | insufficient_credit | The organization is out of credit. Top up, then upload again. |
| 403 | insufficient_scope | The key does not have the scope this endpoint needs (for example purge). |
| 403 | forbidden | The action is not allowed for this agent. |
| 404 | not_found | No document with this ID exists on this agent. |
| 409 | duplicate_code | Another document of this agent already uses this code. |
| 409 | invalid_state | The action does not fit the document's current status, for example deactivating a document that is still Processing. |
| 413 | file_too_large | The file is larger than 25 MB. |
| 415 | unsupported_file_type | The file is not a PDF, TXT, or MD file. |
| 429 | rate_limited | A limit was exceeded. Wait for the number of seconds in Retry-After. |
| 500 | internal_error | Something went wrong on Qlar's side. Try again later. |
Activity log
Every API call, successful or not, and every settings change is recorded in the agent's activity log. Contributors see it on the Knowledge β Knowledge API page, and can filter it by type (API calls or settings changes), by outcome (success or failure), by document, and by date.
| Recorded for API calls | Recorded for settings changes |
|---|---|
Time, action (for example documents.add), and outcome | Time and action: API switched on or off, key created, replaced, or revoked |
| HTTP method, path, status code, and duration | The user who made the change |
| Key slot, key name, and the key's last four characters | The key's slot, name, scopes, and expiry |
| IP address and user agent of the caller | |
| Document ID and code, error code and message |
Entries are kept for 90 days. The log never contains API keys or the contents of your files.
Use the log to check that a new key works after a rotation, to see which system uploaded a document, and to spot calls from an unexpected IP address.
Security best practices
- Keep the key on a server. Call the Knowledge API only from back-end code, scheduled jobs, or pipelines. Never put a key in a browser page, a mobile app, a desktop app you distribute, or a public repository: anyone who can read the code can use the key.
- Store it as a secret. Use your vault or your pipeline's secret variables, not a config file checked into source control. Do not print the key in logs.
- Give each system its own scope. A monitoring job only needs
read. A sync job needswrite. Givepurgeonly to the job that must remove documents for good. - Set an expiry. A key that expires limits the damage of a leak you did not notice. Plan the rotation before the expiry date.
- Rotate regularly using the two slots, as described in Rotate a key without downtime.
- Revoke at once on a leak. If a key may have been exposed, revoke it on the Knowledge β Knowledge API page, create a new one, and check the activity log for calls you do not recognise.
- Switch the API off when you no longer use it.
Troubleshooting
| Symptom | What to check |
|---|---|
Every call returns 401 unauthorized | Check that the Knowledge API is switched on, that the key is the full value starting with qk_, that it is sent in the X-Api-Key header, that it has not expired or been revoked (or replaced by a newer key in the same slot), and that the agent ID in the URL matches the agent of the key. The agent must also still be a service agent. |
429 rate_limited right away, even with a correct key | Your IP address made more than 20 failed attempts in a minute, for example from a job with an old key. Wait a minute and fix the key. |
403 insufficient_scope | The key lacks the scope this endpoint needs. Create a new key with the right scopes in that slot. |
409 duplicate_code on upload | A document with that code already exists, also if it is Deleted. Use a new code, or purge the old document first. |
400 about an author or permission | The authorCode or a permission code does not exist on the agent. Create it in the CMS first (Citations, Knowledge Permissions). |
| The document stays Failed | Read the processing log. Scanned PDFs without text and very complex layouts are common causes. Try another chunkingStrategy (upload again with a new code), or prepare the file as described in Documents. |
| The document is Active but the agent does not use it | Check that Enable reference is on in Retrieval, that the document's permissions include the user, and test in a fresh conversation. |
402 insufficient_credit | Top up your organization's credit, then upload again. |
409 invalid_state on delete of an Active document | Deactivation took longer than 30 seconds. Wait a moment and call delete again. |
Related Pages
- Documents: upload and manage documents in the CMS, and the processing modes.
- Citations: create authors to use as
authorCodeand show sources in answers. - Knowledge Permissions: permission codes for the
permissionsfield. - Chunks: inspect the chunks a document was split into.
- Retrieval: make sure the agent answers from its documents.
- Teach Your Agent