Skip to main content

Documents API

Manage knowledge base documents. All endpoints require authentication.

Document object

{
"id": "a1b2c3d4-...", // UUID, auto-generated on create
"identifier": "shipping-policy", // string, unique per instance (used for upsert)
"name": "Shipping Policy", // string, document title
"body": "We ship worldwide...", // string, document content (Markdown supported)
"categoryID": "e5f6a7b8-...", // UUID or null, parent category ID
"visibility": "ALL" // string, currently always "ALL" (reserved)
}

createdAt and updatedAt are tracked but not returned for documents.

List documents

GET /api/kb/documents

Returns all documents for your instance. There is no pagination and no filtering on this endpoint, so on a synced catalog the response holds every product document at once. Fetch it sparingly, and prefer GET /api/kb/documents/:id when you know the id.

Response:

{
"success": true,
"data": [
{
"id": "a1b2c3d4-...",
"identifier": "shipping-policy",
"name": "Shipping Policy",
"body": "We ship worldwide...",
"categoryID": "e5f6a7b8-...",
"visibility": "ALL"
}
]
}

Get document

GET /api/kb/documents/:id

Response:

{
"success": true,
"data": {
"id": "a1b2c3d4-...",
"identifier": "shipping-policy",
"name": "Shipping Policy",
"body": "We ship worldwide...",
"categoryID": "e5f6a7b8-...",
"visibility": "ALL"
}
}

Errors: 400 invalid id, 404 document not found.

Create document

POST /api/kb/documents

Request body:

{
"identifier": "shipping-policy", // unique identifier within the instance
"name": "Shipping Policy", // document title
"body": "We ship worldwide...", // document content
"categoryID": "e5f6a7b8-...", // optional, parent category ID
"visibility": "ALL", // optional, currently always "ALL"
"attributes": { // optional, key-value pairs added as YAML frontmatter to the body
"source": "help-desk",
"priority": "high"
}
}
note

identifier, name and body are what a usable document needs, but none of them is enforced by the API: a request omitting them succeeds and stores empty values. Validate before posting.

Create is an upsert

Documents are unique on identifier within an instance, and a create call for an identifier that already exists updates the existing document rather than adding a second one. This is what lets a sync run repeatedly without duplicating content. Because of that, make identifiers stable: shipping-policy must always mean the same document.

Response (status 201):

{
"success": true,
"data": {
"id": "generated-uuid",
"identifier": "shipping-policy",
"name": "Shipping Policy",
"body": "---\nsource: help-desk\npriority: high\n---\nWe ship worldwide...",
"visibility": "ALL"
}
}
info

When attributes are provided, they are prepended to the body as YAML frontmatter. The chatbot uses these attributes as additional context when answering questions.

Update document

PUT /api/kb/documents/:id

Request body: same as Create document.

Response (status 200): same structure as Create.

Errors: 400 invalid id, 404 document not found.

An update is a full replacement, not a patch

The request body replaces the stored document field by field. A field you leave out is not preserved - it is cleared. Omitting categoryID moves the document out of its category; omitting body empties it. Read the document first, change what you need, and send the whole object back.

Delete document

DELETE /api/kb/documents/:id

Response:

{
"success": true,
"message": "deleted"
}

Deleting an id that does not exist is also reported as success.

Errors: 400 invalid id.