Skip to content
Console

Agents

Knowledge

Copy page

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
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"]
}'
Response — 201
{
"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.

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.

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 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.

curl
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.

Files are uploaded straight to storage. The bytes never pass through the API.

curl
# 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 question and answer columns becomes one question-and-answer pair per row.
  • The upload URL stops accepting the file at expires_at. Without a content_type in 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.

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
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"] }'
Response
{ "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.

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).

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
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" }'
Response
{
"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
}
  • query is a question as a person would ask it, up to 500 characters.
  • Name agent_id to search what that agent has; omit it to search every entry. An agent that is not yours is a 404.
  • outcome is found, none (nothing relevant enough) or failed.
  • With agent_id, mode says 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.
  • GET /v1/knowledge lists every entry, most recently changed first, with its agents. q is a plain text match over title, summary and body, not the semantic search the agent uses. agent_id, category and status narrow further and combine. It is a page: limit (1 to 200, default 50) and cursor, answered as data and next_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/categories lists every category in use, alphabetically, as strings in one page: {"data": ["Returns", "Visiting"], "next_cursor": null}.
  • GET /v1/knowledge/insights shows which entries your agents drew on, by how many replies, and the newest questions whose lookups found nothing: the gaps worth filling. days sets the window, 1 to 90, default 7. An agent with its knowledge in its prompt looks nothing up, so it does not appear here.

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 body costs anything. It re-indexes: status returns to pending, 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 (the version you 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.

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.

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