AI Bot API
Two surfaces: a data plane for conversations, and an admin plane for bot definitions and deploys.
Required headers
Section titled “Required headers”The platform tenancy headers apply — X-Kis-Tenant, X-Kis-Product, X-Kis-Environment.
Conversations are tenant-scoped; one tenant’s bots and conversations are not reachable from
another.
Conversations
Section titled “Conversations”GET /v1/bots/{bot}/conversations list conversationsGET /v1/bots/{bot}/conversations/{id} one conversationPOST /v1/bots/{bot}/conversations/{id}/messages send a messagePOST /v1/bots/{bot}/conversations/{id}/messages/stream send, stream the replySending a message
Section titled “Sending a message”{ "text": "where is my order?", "locale": "en-US", "stream": false, "attachments": [ { "kind": "image", "media_type": "image/png", "uri": "https://…", "name": "receipt.png" } ], "metadata": {}}| Field | Type | Required | Notes |
|---|---|---|---|
text | string | yes | The user’s message |
locale | string | no | BCP-47; falls back to the bot’s default |
stream | bool | no | Stream the response instead of buffering it |
attachments[] | array | no | kind, media_type, uri, optional name |
metadata | object | no | Passed through to script hooks |
The response
Section titled “The response”{ "conversation_id": "01JB7CY1Q6R0GK09RZAVDQGF11", "text": "Your order shipped on Tuesday.", "cards": [], "buttons": [], "quick_replies": [], "intent": "order_status", "resolved_stage": "classifier"}| Field | Notes |
|---|---|
conversation_id | Stable id; send it back to continue the conversation |
text | The reply |
cards, buttons, quick_replies | Rich elements, when the channel supports them |
intent | The intent the cascade settled on |
resolved_stage | Which cascade stage answered |
resolved_stage is the field worth logging. It is the per-message view of the cost property
the whole block is built around — a bot whose traffic increasingly resolves at llm rather
than rules or classifier is getting more expensive, and this is where you see it before the
bill does. See Core Concepts.
Streaming
Section titled “Streaming”POST …/messages/stream streams the reply over SSE. Non-generative resolutions (a canned
answer from a rule, a fast skill) return immediately rather than streaming, so a client must
handle both. Streams are accumulated into conversation history on completion, so a streamed
answer is stored the same as a buffered one.
GET /admin/v1/bots bots in this tenantGET /admin/v1/bots/{bot} one bot definitionPOST /admin/v1/bots/{bot}/deploy promote an artifact to an environmentPOST /admin/v1/bots/{bot}/rollback restore the previous artifactGET /admin/v1/stats cascade and resolution statisticsGET /admin/v1/health readinessDeploy and rollback operate on signed, versioned artifacts that carry the bot definition, rules, scripts, model references and calibration together. Rollback therefore restores the exact prior behaviour rather than approximately restoring it — the models travel with the artifact instead of living in mutable state.
Errors
Section titled “Errors”The platform’s structured error body: a stable code, a human-readable message, and the request id for correlation against logs and audit.
| Status | Meaning |
|---|---|
400 | Malformed message |
401 / 403 | Authentication or authorisation failure |
404 | Unknown bot or conversation for this tenant |
429 | Rate limited, or a gateway budget exhausted upstream |
5xx | Cascade failure with no resolvable stage |
See also
Section titled “See also”- Core Concepts — the cascade and calibrated confidence
- Configuration — the bot definition
- Operations — the build pipeline and analytics
Authentication
Section titled “Authentication”The surface splits by audience, and the split is deliberate:
| Routes | Who calls them | Credential |
|---|---|---|
/v1/bots/:bot/conversations/* | End users talking to a bot | Anonymous or authenticated |
/admin/v1/* | Your control plane | A bearer token |
Conversation routes accept a request with no token at all. That is the point — a bot embedded in a public page has to serve visitors who have not signed in. When a token is present it is validated and the conversation is attributed to that user; when it is absent the request still proceeds.
An anonymous caller may supply a tracking id header so successive messages join the same conversation. Treat that id as a correlation handle, not an identity: it is client-supplied and proves nothing.
Tenancy
Section titled “Tenancy”The four CPET headers resolve the tenant. :bot selects within it.
Errors
Section titled “Errors”| Status | Meaning |
|---|---|
400 | Request parse or validation failure |
401 | An admin route with a missing or invalid token, as plain text |
404 | No such bot or conversation |
429 | Rate limited, or a gateway budget exhausted upstream |
500 | Unexpected server error, or a model call failed |