Agents
Knowledge
Give your agents reference material, written, from a web page or from a file, that they look up by meaning, and choose which agent reads which entry.
Knowledge is reference material your agents can draw on: opening hours, a returns policy, a product catalogue, a help centre. You write entries once for your organisation and assign each to any number of agents. When a question comes up, the agent looks the answer up by meaning rather than relying on what the model happens to know.
curl https://api.lumavox.ai/v1/knowledge \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "Opening hours", "category": "Visiting", "body": "We are open 9:00 to 18:00, Tuesday to Sunday. Closed on Mondays and on 25 December.", "agent_ids": ["0193b1e2-6c1d-7a4e-9f20-5d8a3c2b1e07"] }'{ "id": "0193b210-4b9e-7e21-a3c7-58d0f1b2c946", "title": "Opening hours", "category": "Visiting", "body": "We are open 9:00 to 18:00, Tuesday to Sunday. Closed on Mondays and on 25 December.", "summary": null, "status": "pending", "body_chars": 83, "source_kind": "text", "source_name": null, "refresh": null, "refreshed_at": null, "searchable": false, "summary_source": null, "error": null, "chunks": 0, "agents": [{ "id": "0193b1e2-6c1d-7a4e-9f20-5d8a3c2b1e07", "name": "Mira" }], "created_at": "2026-10-24T09:55:02.000Z", "updated_at": "2026-10-24T09:55:02.000Z", "version": 1}The entry comes back pending and no agent can find it yet. Indexing takes seconds to a few minutes: an entry is ready once the search index returns it. Poll GET /v1/knowledge/{entry_id} until status is ready, or failed with the reason in error.
Scopes
Section titled “Scopes”Reading, listing and testing knowledge need agent. Writing, assigning and deleting need agent:write. Writing or editing an entry, importing a page or a file, re-indexing and refreshing also count against your rate limit like a generation, because indexing is model work.
Write an entry
Section titled “Write an entry”POST /v1/knowledge:
| Field | What it is |
|---|---|
title |
Required, 1 to 255 characters. |
body |
Required, up to 100,000 characters. |
category |
Optional, up to 120 characters. For your own filtering. |
summary |
Usually left out. See below. |
agent_ids |
The agents that may use it. May be empty: an entry nobody has yet is a draft, not a fault. Ids that are not yours are skipped. |
The summary is what the agent sees on every turn. The body is only fetched when the agent decides to look something up, so a vague summary makes it less likely to consult a good entry. The indexer writes a one-line summary for you (summary_source: "model") and rewrites it with every new body. If you write your own (up to 200 characters, summary_source: "customer"), it is kept through every later edit. Sending summary: null on an edit hands it back to the indexer.
Status
Section titled “Status”status |
Meaning |
|---|---|
importing |
A page or file is being read into text. |
pending |
The latest body is being indexed. |
ready |
Indexed. |
failed |
Indexing failed; the reason is in error. |
status is about the latest body. searchable says whether an agent can find the entry at all. An edited entry stays searchable at its previous version while the new one indexes, and keeps that version if the new one fails.
From a web page
Section titled “From a web page”curl https://api.lumavox.ai/v1/knowledge/urls \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com/help/returns", "refresh": "weekly", "agent_ids": ["0193b1e2-6c1d-7a4e-9f20-5d8a3c2b1e07"] }'The page is fetched, read into text and indexed. The entry comes back 202, importing. A PDF, Word, CSV or text file at a public address works the same way. Only the public internet is reached.
| Field | What it does |
|---|---|
url |
Required. A public http or https address. |
refresh |
off (the default), daily or weekly: read the page again on that schedule and re-index it when it has changed. |
crawl |
Also import the pages this one links to, and those the site’s sitemap lists, in the same part of the site (/help/… finds /help/… and nothing else). One level deep, robots.txt honoured, pages already imported skipped. Each becomes its own entry with the same agents, category and refresh. |
max_pages |
With crawl: the most entries made, this page included. 2 to 100, default 25. |
title, category, agent_ids |
As for a written entry. |
POST /v1/knowledge/{entry_id}/refresh reads a page-made entry again now, rather than at its next scheduled refresh.
From a file
Section titled “From a file”Files are uploaded straight to storage. The bytes never pass through the API.
# 1. Ask where to upload it.curl https://api.lumavox.ai/v1/knowledge/upload-url \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filename": "catalogue.pdf", "size_bytes": 482113 }'# → { "upload_id": "…", "url": "https://…", "content_type": "application/pdf", "expires_at": "2026-10-24T10:05:00.000Z" }
# 2. PUT the bytes there, with exactly that Content-Type and no Authorization header.curl -X PUT "$UPLOAD_URL" -H "Content-Type: application/pdf" --data-binary @catalogue.pdf
# 3. Make the entry.curl https://api.lumavox.ai/v1/knowledge/files \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "upload_id": "'"$UPLOAD_ID"'", "filename": "catalogue.pdf", "agent_ids": ["0193b1e2-6c1d-7a4e-9f20-5d8a3c2b1e07"] }'- Formats, by the file’s extension:
.pdf,.docx,.xlsx,.xls,.ods,.odt,.csv,.html,.htm,.txt,.md. - Up to 10 MB. Larger is a 413.
- A CSV with
questionandanswercolumns becomes one question-and-answer pair per row. - The upload URL stops accepting the file at
expires_at. Without acontent_typein the request, the ticket names the one the file’s extension calls for: send exactly that.
The entry comes back 202, importing while the file is read, then pending while it is indexed, then ready. The extracted text becomes the entry’s body, editable like any other. Without a title the file’s own is used.
Assign entries to agents
Section titled “Assign entries to agents”Entries belong to your organisation, not to an agent. Assigning only says which agents may read which entries. There are three ways to do it, and all of them are declarative or idempotent:
| Call | What it sets |
|---|---|
PUT /v1/knowledge/{entry_id}/agents |
The complete set of agents that have this entry: {"agent_ids": [...]}. |
PUT /v1/agents/{agent_id}/knowledge |
The complete set of entries this agent has: {"entry_ids": [...]}. |
POST /v1/knowledge/bulk |
assign or unassign agents on up to 200 entries at once, leaving each entry’s other agents alone; or delete up to 200 entries. It answers how many entries it acted on, how many links or entries it changed, and the ids it skipped. |
curl -X PUT https://api.lumavox.ai/v1/agents/$AGENT_ID/knowledge \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "entry_ids": ["0193b210-4b9e-7e21-a3c7-58d0f1b2c946"] }'{ "added": 1, "removed": 0, "skipped": [] }An empty list clears every assignment, which is a real thing to want and not an error. Nothing is created or deleted by assigning. Ids that are not yours come back in skipped rather than failing the call.
GET /v1/agents/{agent_id}/knowledge lists the entries an agent has, newest first, in one page (next_cursor is null). Only ready entries are visible to the agent itself.
An agent’s knowledge_enabled switch (on by default) turns its knowledge off without unassigning anything, which is how to try an agent without its reference material.
How an agent reads its knowledge
Section titled “How an agent reads its knowledge”Three fields on the agent decide it:
| Field | What it does |
|---|---|
knowledge_mode |
auto (the default) puts the whole text in the prompt while it fits the platform’s agents.knowledge.inline_budget_tokens, so there is nothing to look up and nothing to miss, and looks it up beyond that. prompt puts it in the prompt up to the platform’s agents.knowledge.prompt_cap_tokens (Limits); the more there is, the slower each turn’s first word. lookup always looks it up. |
knowledge_lookup_first |
On by default: search before every reply and hand the model what matches, so it never answers from memory what its material says. Off, the model searches only when it decides to, which is slower when it does and wrong more often when it does not. |
knowledge_max_results |
How many pieces a lookup hands the model, 1 to 8. 4 when unset. |
A lookup hands over only pieces with a similarity score of at least the platform’s agents.knowledge.min_score (Limits). What the agent looked up for each reply is reported live on the socket as a knowledge event, and stored on the message as knowledge (see Conversations and memory).
Test a question
Section titled “Test a question”POST /v1/knowledge/search runs one question exactly as an agent’s lookup would, and returns the pieces it would be handed with their scores. It costs nothing and changes nothing.
curl https://api.lumavox.ai/v1/knowledge/search \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "query": "Are you open on Mondays?", "agent_id": "0193b1e2-6c1d-7a4e-9f20-5d8a3c2b1e07" }'{ "outcome": "found", "mode": "lookup", "hits": [ { "entry_id": "0193b210-4b9e-7e21-a3c7-58d0f1b2c946", "title": "Opening hours", "text": "We are open 9:00 to 18:00, Tuesday to Sunday. Closed on Mondays and on 25 December.", "score": 0.82 } ], "embed_ms": 41, "query_ms": 23}queryis a question as a person would ask it, up to 500 characters.- Name
agent_idto search what that agent has; omit it to search every entry. An agent that is not yours is a 404. outcomeisfound,none(nothing relevant enough) orfailed.- With
agent_id,modesays whether that agent looks things up (lookup) or has its whole knowledge in its prompt (prompt). The hits show what a lookup would find either way.
Find and understand entries
Section titled “Find and understand entries”GET /v1/knowledgelists every entry, most recently changed first, with its agents.qis a plain text match over title, summary and body, not the semantic search the agent uses.agent_id,categoryandstatusnarrow further and combine. It is a page:limit(1 to 200, default 50) andcursor, answered asdataandnext_cursor(Conventions).GET /v1/knowledge/{entry_id}reads one entry, with how many chunks it was indexed into and which agents have it.GET /v1/knowledge/categorieslists every category in use, alphabetically, as strings in one page:{"data": ["Returns", "Visiting"], "next_cursor": null}.GET /v1/knowledge/insightsshows which entries your agents drew on, by how many replies, and the newest questions whose lookups found nothing: the gaps worth filling.dayssets the window, 1 to 90, default 7. An agent with its knowledge in its prompt looks nothing up, so it does not appear here.
Edit, re-index and delete
Section titled “Edit, re-index and delete”PATCH /v1/knowledge/{entry_id} is a partial update of title, body, category, summary, refresh (for a page) and agent_ids (the complete set, saved in the same step). An explicit null clears category, and on summary hands the line back to the indexer.
- Only a changed
bodycosts anything. It re-indexes:statusreturns topending, and the previous version stays searchable until the new one is ready, so no agent loses the entry meanwhile. Renaming or recategorising is immediate. - Send
expected_version(theversionyou read) to be refused with 409 if somebody edited the entry since. - A written entry’s body stays within 100,000 characters.
POST /v1/knowledge/{entry_id}/reindex queues an entry for indexing again as it stands, for example one that failed while a provider was down. Entries stuck pending are retried on their own after half an hour.
DELETE /v1/knowledge/{entry_id} removes the entry, everything indexed from it and every assignment to it, and answers 204 with no body. This affects every agent that had it. To take it from one agent only, change that agent’s set with PUT /v1/agents/{agent_id}/knowledge.
When changes reach conversations
Section titled “When changes reach conversations”An edit, an assignment or a deletion that an agent can see reaches its open conversations within about a minute, from their next turn, the same way an edit to the agent does. A new body is used once it is ready; until then the previous version answers.
Limits
Section titled “Limits”| Limit | Value |
|---|---|
| A written entry’s body | 100,000 characters |
| Text read from a page or file | 1,000,000 characters |
| An uploaded file | 10 MB |
| One bulk call | 200 entries, 100 agents |
| A test query | 500 characters, up to 8 results |
| Entries per organisation | capped by the platform; past the cap, a new entry is a 409 |
- Agents: the switches that decide how knowledge is read
- The WebSocket: the
knowledgeevent - Knowledge reference