Tone docs

Knowledge bases

Documents an agent can answer from, without putting them in the prompt.

A knowledge base is a set of documents an agent retrieves from mid-call. Attaching one is how an agent answers "what's your returns window?" without that answer living in the prompt.

The shape of it

# 1. create
curl "$TONE_API/v1/knowledge-bases" -X POST \
  -H "Authorization: Bearer $TONE_KEY" -H 'content-type: application/json' \
  -d '{"name":"Shipping and returns policy"}'

# 2. import a page, or upload a file (see below)
curl "$TONE_API/v1/knowledge-bases/$KB/documents/url" -X POST \
  -H "Authorization: Bearer $TONE_KEY" -H 'content-type: application/json' \
  -d '{"url":"https://example.com/help/returns"}'

# 3. attach it to an agent
curl "$TONE_API/v1/agents/$AGENT" -X PATCH \
  -H "Authorization: Bearer $TONE_KEY" -H 'content-type: application/json' \
  -d "{\"knowledgeBaseIds\":[\"$KB\"]}"

Builds are asynchronous

Indexing runs in the background and swaps atomically — the old index keeps serving until the new one succeeds. Status is derived, not stored:

StatusMeaning
emptyNo documents yet
indexingA build is running; the previous index still answers
readyAt least one build has succeeded
errorThe last build failed. The previous index, if any, still answers

Subscribe to knowledge.build.completed and knowledge.build.failed rather than polling. Attaching a base that has never built successfully and then dialling gives 409 knowledge_base_not_ready — there is nothing to answer from.

Uploading a file

Uploads are two-phase, because nothing about a file is trusted until we have read it ourselves:

  1. POST /documents/upload-url — declare the filename, type and exact byte length. The length is signed into the URL; a presigned PUT that does not pin it is an unbounded write.
  2. PUT the bytes to the URL you get back.
  3. POST /documents/{id}/confirm — we re-read the object, check its real size and type against what you declared, and queue it for indexing.

Test what the agent will actually get

curl "$TONE_API/v1/knowledge-bases/$KB/search" -X POST \
  -H "Authorization: Bearer $TONE_KEY" -H 'content-type: application/json' \
  -d '{"query":"How long do I have to return an item?"}'

This runs the same retrieval a live turn runs — a preview that queried differently would be worse than no preview. It optionally generates the answer a caller would hear.

degraded: true in the response means embeddings were unavailable and it fell back to keyword search alone. The results are real, just weaker.

Writing documents that retrieve well

Retrieval works on passages, so structure beats prose. Headings that name the question ("Returns window", "COD refunds") retrieve far better than a wall of text, because the heading travels with the passage.

Was this page helpful?

On this page