API: Knowledge bases
Halo HTTP API for knowledge bases: create and delete collections, bind them to workspaces and Digital Humans, import documents and follow indexing.
A knowledge base is a collection of documents Halo can search (tlon in the API paths). Use these operations to create and delete knowledge bases, bind them to workspaces and Digital Humans, import and remove documents, and follow indexing.
Paths are relative to your Halo base URL, and every request carries the access password. Set $HALO_URL and $HALO_TOKEN as in the quickstart; base URL, authentication and error conventions are in the HTTP API overview.
List all knowledge collections
GET /api/tlon Assistant
Response
{success:true,data:[{id,name,icon,description,status,spaceIds,appIds,stats,isDefault?,...}]}Example
curl -s "$HALO_URL/api/tlon" \
-H "Authorization: Bearer $HALO_TOKEN"Create a knowledge collection
POST /api/tlon Assistant
- Optional fields: icon, description, linkedDirs (array of {path,label}).
Request body
{
"name": "Product Docs"
}Response
{success:true,data:{id,name,icon,description,status:"active",createdAt,updatedAt,path,linkedDirs:[],spaceIds:[],appIds:[],stats:{...}}}Example
curl -sX POST "$HALO_URL/api/tlon" \
-H "Authorization: Bearer $HALO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Product Docs"}'Get one knowledge collection by id
GET /api/tlon/:kbId Assistant
Path parameters
| Name | Description |
|---|---|
kbId | Knowledge base id, from GET /api/tlon. |
Response
{success:true,data:{id,name,icon,description,status,linkedDirs,spaceIds,appIds,stats,...}} or {success:false,error:"Knowledge base not found"}Example
curl -s "$HALO_URL/api/tlon/<kbId>" \
-H "Authorization: Bearer $HALO_TOKEN"Rename or edit a collection's description/status
PUT /api/tlon/:kbId Reversible Assistant
- All fields optional: name, icon, description, status ("active"|"paused"|"error").
Path parameters
| Name | Description |
|---|---|
kbId | Knowledge base id, from GET /api/tlon. |
Request body
{
"name": "New name"
}Response
{success:true,data:<updated entry>} or {success:false,error:"Knowledge base not found"}Example
curl -sX PUT "$HALO_URL/api/tlon/<kbId>" \
-H "Authorization: Bearer $HALO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"New name"}'Delete a knowledge collection and all its data
DELETE /api/tlon/:kbId Irreversible Assistant
Irreversible
This cannot be undone, and nothing goes to a trash folder. Make sure it is what the user wants before you call it. If you only need something narrower, use POST /api/tlon/:kbId/remove-raw
- Permanently deletes the collection's entire folder — original source files, extracted text, and the index. Not just the registry entry. If the user only meant to remove one document, use remove-raw instead.
Path parameters
| Name | Description |
|---|---|
kbId | Knowledge base id, from GET /api/tlon. |
Response
{success:true,data:<deletion result>}Example
curl -sX DELETE "$HALO_URL/api/tlon/<kbId>" \
-H "Authorization: Bearer $HALO_TOKEN"Bind a knowledge collection so a digital human can read it
POST /api/tlon/:kbId/bind-app Reversible Assistant
Path parameters
| Name | Description |
|---|---|
kbId | Knowledge base id, from GET /api/tlon. |
Request body
{
"appId": "<appId — a uuid from GET /api/apps>"
}Response
{success:true,data:<updated entry>}Errors
- 400 if appId is missing.
Example
curl -sX POST "$HALO_URL/api/tlon/<kbId>/bind-app" \
-H "Authorization: Bearer $HALO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"appId":"<appId — a uuid from GET /api/apps>"}'Bind a knowledge collection to a space
POST /api/tlon/:kbId/bind-space Reversible Assistant
Path parameters
| Name | Description |
|---|---|
kbId | Knowledge base id, from GET /api/tlon. |
Request body
{
"spaceId": "<spaceId — a uuid from GET /api/spaces>"
}Response
{success:true,data:<updated entry>}Errors
- 400 if spaceId is missing.
Example
curl -sX POST "$HALO_URL/api/tlon/<kbId>/bind-space" \
-H "Authorization: Bearer $HALO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"spaceId":"<spaceId — a uuid from GET /api/spaces>"}'Wipe extracted text and re-index a collection from scratch
POST /api/tlon/:kbId/clear-relearn Reversible Assistant
- Use when documents were updated in place and stale extracted text needs replacing. Only clears derived/regeneratable data (extracted text, index) — original source files are untouched and text is rebuilt automatically.
Path parameters
| Name | Description |
|---|---|
kbId | Knowledge base id, from GET /api/tlon. |
Response
{success:true,data:true} or {success:false,error:"Learning is already in progress"}Example
curl -sX POST "$HALO_URL/api/tlon/<kbId>/clear-relearn" \
-H "Authorization: Bearer $HALO_TOKEN"Add existing server-local files to a collection by absolute path
POST /api/tlon/:kbId/files Assistant
Path parameters
| Name | Description |
|---|---|
kbId | Knowledge base id, from GET /api/tlon. |
Request body
{
"filePaths": [
"/absolute/path/to/file.pdf"
]
}Response
{success:true,data:{added:string[],rejected:string[]}}Errors
- 400 if filePaths is missing or empty. Files are copied in, not linked — see linked-dirs for live-watched folders.
Example
curl -sX POST "$HALO_URL/api/tlon/<kbId>/files" \
-H "Authorization: Bearer $HALO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"filePaths":["/absolute/path/to/file.pdf"]}'Read a collection's document map (index.md)
GET /api/tlon/:kbId/index Assistant
Path parameters
| Name | Description |
|---|---|
kbId | Knowledge base id, from GET /api/tlon. |
Response
{success:true,data:string} — markdown text, empty string if not yet generatedExample
curl -s "$HALO_URL/api/tlon/<kbId>/index" \
-H "Authorization: Bearer $HALO_TOKEN"Start indexing a collection's documents (fire-and-forget)
POST /api/tlon/:kbId/ingest Assistant
- Returns immediately; the indexing job runs in the background. Poll
GET /api/tlon/:kbId/ingest-statusfor progress — back off (2s, then double), do not tight-loop.
Path parameters
| Name | Description |
|---|---|
kbId | Knowledge base id, from GET /api/tlon. |
Response
{success:true,data:true}Example
curl -sX POST "$HALO_URL/api/tlon/<kbId>/ingest" \
-H "Authorization: Bearer $HALO_TOKEN"Get the current indexing progress for a collection
GET /api/tlon/:kbId/ingest-status Assistant
Path parameters
| Name | Description |
|---|---|
kbId | Knowledge base id, from GET /api/tlon. |
Response
{success:true,data:{kbId,total,completed,current?,phase:"idle"|"running"|"done"|"error",error?,errors?:[{file,message}]}}Example
curl -s "$HALO_URL/api/tlon/<kbId>/ingest-status" \
-H "Authorization: Bearer $HALO_TOKEN"Watch a server-local directory as a live document source
POST /api/tlon/:kbId/linked-dirs Assistant
- Optional field: label (defaults to path).
- Failure carries a code instead of throwing: TOO_MANY_FILES (data:{count,limit}), DISK_ROOT (cannot watch a filesystem root), FOLDER_TOO_LARGE, PATH_NOT_FOUND, KB_NOT_FOUND.
Path parameters
| Name | Description |
|---|---|
kbId | Knowledge base id, from GET /api/tlon. |
Request body
{
"path": "/Users/me/Documents/product-docs"
}Response
{success:true,data:{id,path,label,watching,lastScannedAt?}} on successErrors
- 400 if path is missing.
Example
curl -sX POST "$HALO_URL/api/tlon/<kbId>/linked-dirs" \
-H "Authorization: Bearer $HALO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"path":"/Users/me/Documents/product-docs"}'Stop watching a linked directory
DELETE /api/tlon/:kbId/linked-dirs/:linkId Reversible Assistant
- Only removes the watch registration — the target folder and its files are untouched, and can be re-linked.
Path parameters
| Name | Description |
|---|---|
kbId | Knowledge base id, from GET /api/tlon. |
linkId | Id of a folder linked to a knowledge base. |
Response
{success:true,data:<removal result>}Example
curl -sX DELETE "$HALO_URL/api/tlon/<kbId>/linked-dirs/<linkId>" \
-H "Authorization: Bearer $HALO_TOKEN"Look for an unavailable linked directory again and resume watching it if it is back
POST /api/tlon/:kbId/linked-dirs/:linkId/retry Reversible Assistant
- A link shows watching:false when its folder was missing at the last check (e.g. an unplugged drive). Halo looks again at every start; this asks now.
- Failure carries a code: PATH_NOT_FOUND (the folder is still missing), LINK_NOT_FOUND, KB_NOT_FOUND.
- learningPaused ({reason:"too-many-files",count,limit} or {reason:"too-large"}) on a link means the folder is there but over the watched-folder limits, so its files are not learned.
Path parameters
| Name | Description |
|---|---|
kbId | Knowledge base id, from GET /api/tlon. |
linkId | Id of a folder linked to a knowledge base. |
Response
{success:true,data:{id,path,label,watching:true,lastScannedAt?,learningPaused?}} when the folder is thereExample
curl -sX POST "$HALO_URL/api/tlon/<kbId>/linked-dirs/<linkId>/retry" \
-H "Authorization: Bearer $HALO_TOKEN"List the raw source files added to a collection
GET /api/tlon/:kbId/raw Assistant
Path parameters
| Name | Description |
|---|---|
kbId | Knowledge base id, from GET /api/tlon. |
Response
{success:true,data:[{name,path,size,learned:boolean,state:"learned"|"pending"|"no-text"|"failed",error?,source:"raw"|"linked",dirLabel?}]}Example
curl -s "$HALO_URL/api/tlon/<kbId>/raw" \
-H "Authorization: Bearer $HALO_TOKEN"Remove one document (raw source file) from a collection
POST /api/tlon/:kbId/remove-raw Irreversible Assistant
Irreversible
This cannot be undone, and nothing goes to a trash folder. Make sure it is what the user wants before you call it.
Path parameters
| Name | Description |
|---|---|
kbId | Knowledge base id, from GET /api/tlon. |
Request body
{
"relativePath": "raw/file.pdf"
}Response
{success:true,data:<removal result>}Errors
- 400 if relativePath is missing. Permanently deletes the copied file from the collection — no trash, no undo.
Example
curl -sX POST "$HALO_URL/api/tlon/<kbId>/remove-raw" \
-H "Authorization: Bearer $HALO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"relativePath":"raw/file.pdf"}'Map paths read from a collection back to their source documents
POST /api/tlon/:kbId/resolve-sources Assistant
- Maps paths read from a knowledge base back to the original documents, deduplicated and absolute. Paths that no longer exist are dropped, so a shorter list than the one sent is normal.
Path parameters
| Name | Description |
|---|---|
kbId | Knowledge base id, from GET /api/tlon. |
Request body
{
"readPaths": [
"/absolute/path/inside/the/collection"
]
}Response
{success:true,data:[{name:string,path:string}]} — deduped, absolute, files that still existErrors
- 400 when
readPathsis not an array; an empty array returns nothing.
Example
curl -sX POST "$HALO_URL/api/tlon/<kbId>/resolve-sources" \
-H "Authorization: Bearer $HALO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"readPaths":["/absolute/path/inside/the/collection"]}'Unbind a knowledge collection from a digital human
POST /api/tlon/:kbId/unbind-app Reversible Assistant
Path parameters
| Name | Description |
|---|---|
kbId | Knowledge base id, from GET /api/tlon. |
Request body
{
"appId": "<appId — a uuid from GET /api/apps>"
}Response
{success:true,data:<updated entry>}Errors
- 400 if appId is missing.
Example
curl -sX POST "$HALO_URL/api/tlon/<kbId>/unbind-app" \
-H "Authorization: Bearer $HALO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"appId":"<appId — a uuid from GET /api/apps>"}'Unbind a knowledge collection from a space
POST /api/tlon/:kbId/unbind-space Reversible Assistant
Path parameters
| Name | Description |
|---|---|
kbId | Knowledge base id, from GET /api/tlon. |
Request body
{
"spaceId": "<spaceId — a uuid from GET /api/spaces>"
}Response
{success:true,data:<updated entry>}Errors
- 400 if spaceId is missing.
Example
curl -sX POST "$HALO_URL/api/tlon/<kbId>/unbind-space" \
-H "Authorization: Bearer $HALO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"spaceId":"<spaceId — a uuid from GET /api/spaces>"}'List knowledge collections bound to a space (or the default one)
GET /api/tlon/for-space/:spaceId Assistant
Path parameters
| Name | Description |
|---|---|
spaceId | Workspace id, from GET /api/spaces. The Halo Workspace is always halo-temp. |
Response
{success:true,data:[{id,name,icon,description,status,...}]}Example
curl -s "$HALO_URL/api/tlon/for-space/<spaceId>" \
-H "Authorization: Bearer $HALO_TOKEN"Set (or clear) the collection new conversations auto-load
POST /api/tlon/set-default Reversible Assistant
- kbId can be null to clear the default.
Request body
{
"kbId": "<kbId — a uuid from GET /api/tlon>"
}Response
{success:true,data:<updated entry or null>}Example
curl -sX POST "$HALO_URL/api/tlon/set-default" \
-H "Authorization: Bearer $HALO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"kbId":"<kbId — a uuid from GET /api/tlon>"}'