A knowledge base that came out wrong is nearly always one of three things: an entry the model will never choose because its summary is vague, a page that never transcribed, or a structure that groups things nobody would look for that way. Each has its own repair, and none of them needs a re-crawl. Start by reading what the agent is given.

Read the map the agent gets

GET /v1/knowledge/{kb_id}/prompt returns the table of contents exactly as it is injected into the agent’s system prompt — not a rendering of it, the string itself.
What comes back looks like this:
Read it as the model will. k1 | Returns and refunds — How to return an item, the 30-day window… tells a model exactly when to fetch it. An entry that read k1 | Information — Details about our policies does not, and the model will not fetch it — there is no similarity search behind this that would find it anyway. See overview for why. chars is how much of the agent’s context this knowledge base occupies. It is the same string on every turn, so it sits in the prompt cache, but it is not free — see using knowledge in agents.

Find what never made it in

GET /v1/knowledge/{kb_id}/pages is the per-URL transcription store behind the table of contents. This is where you look when the agent cannot answer something you know is on the site.
Each row carries url, parent_url, kind (html or pdf), status, error, title, summary, content_len and updated_at. Two readings matter:
  • A status that is not done means the page never made it in. pending means the build did not reach it. failed means it did not survive the stage, and error always reads the same generic fetch or transcription failed — one string covering both “the page could not be fetched” and “the page rendered but had under 40 characters on it”. A landing page that is one hero image and a button lands here, and so does a page whose text is drawn by a script the render did not wait for.
  • content_len of 0 means the row holds no text at all, which always accompanies a non-done status. A page that transcribed has content by definition, so a zero here is another way of reading the same failure.
A page that is done with real content but is not in the table of contents is a different problem — see unplaced pages below.

Correct one entry by hand

PATCH /v1/knowledge/{kb_id}/nodes/{node_id} writes an entry’s title, summary and content. Read it first with GET /v1/knowledge/{kb_id}/nodes/{node_id}, which also gives you the version you need for a safe write.
Omitted fields are left alone. Every successful write bumps version by one, whether or not you sent it.

Optimistic concurrency

Send the version you read. If the entry changed underneath you — somebody else edited it, or the CoPilot rewrote the tree — the write is refused with a 409: this node was edited elsewhere — reload and retry. Re-read and re-apply. Omitting version force-writes. That is a deliberate escape hatch for a script that owns the knowledge base outright, not a convenience. In an editor, send it.

Content lives on the page, not on the entry

content is a special case. A table-of-contents entry is pure structure; the text lives on the transcribed page, keyed by the entry’s source_url. So:
  • Sending content on an entry with a source_url rewrites that page’s text. Every entry pointing at that URL sees the change, and so does the agent’s next fetch.
  • Sending content on a category, or on any entry with no source_url, does nothing. There is no page to write to. The request succeeds and the content is discarded — title and summary in the same request still apply.

The node model

Structure is expressed by nesting and sibling order in the tree GET /v1/knowledge/{kb_id} returns. patch_node cannot move an entry to a different parent or reorder siblings — restructuring is regenerate_toc or the CoPilot.

Deleting an entry

DELETE /v1/knowledge/{kb_id}/nodes/{node_id} drops an entry permanently, and its entire subtree with it. Agents can no longer retrieve any of it. The transcribed pages survive — only the table-of-contents entries are removed — so a regenerate_toc afterwards may put them back. Delete an entry to hide a page from the agent right now; delete the URL from the selection and rebuild to remove it for good.

Rebuild the structure without re-crawling

POST /v1/knowledge/{kb_id}/toc re-runs only the last stage: one model pass over the pages already transcribed, producing a fresh table of contents and a fresh overview. Nothing is crawled and nothing is transcribed again.
This is the specific repair for “the structure came out wrong”, and for a build that failed at the generating stage — the pages are already there, so there is nothing to redo but the organizing. It moves the knowledge base to generating and back to ready.
It replaces the tree. Hand edits to titles and summaries are written over, entries you deleted come back, and every entry gets a new id with its version reset to 0. A script holding node ids must re-read the tree afterwards.If you have curated the map, use the CoPilot to adjust it instead — that also replaces the tree and re-issues ids, but it starts from the current one rather than from scratch.
A knowledge base with no transcribed pages is a 400: no transcribed pages — run a build first. A build already in flight is a 409.

Pages the table of contents left out

On a ready knowledge base, GET /v1/knowledge/{kb_id} returns unplaced: URLs that transcribed successfully but that the table-of-contents pass did not put anywhere. The model drops a page when it judges it redundant — a duplicate, an empty stub — and it is told to be conservative, but it does drop some.
An unplaced page is not reachable by the agent. It has no entry in the map, so there is no id to fetch and nothing will surface it. Its content is stored and paid for and never used.
Treat a non-empty unplaced as a signal, not an error. Look at what is in it:
  • If they really are redundant, leave them.
  • If something important is there, ask the CoPilot to place it — that is what it is for, and it is the only way to add an entry to the tree.
  • If a lot is there, the build probably selected too many near-identical pages. Narrow the selection and build again.
unplaced is computed on read and is null on a knowledge base that is not ready. discovered and parents work the same way in reverse — they are populated only at review.

Troubleshooting

Next

KnowledgeCoPilot

Restructure the tree, rewrite summaries in bulk and place dropped pages by describing what you want.

Using it in an agent

What the agent does with the map at runtime, and how to prompt it so it uses one.