Base URL: https://<tenant-host>/api/v1. Errors: { "error": { "code", "message" } } with appropriate HTTP status.
Config & help center
GET /public/config
GET /public/categories
GET /public/articles?category=&q=
GET /public/articles/:slugSession
POST /widget/session
{ identityToken?, anonymousId?, channel: "web"|"ios"|"android"|"api" }
→ { sessionToken, expiresAt, user: { id, name?, email?, verified } }Conversations
GET /conversations
POST /conversations { subject? }
GET /conversations/:id
POST /conversations/:id/messages { content } → SSE (or JSON when human-handling)
POST /conversations/:id/actions/:actionId { decision: "confirm"|"cancel" }
POST /conversations/:id/escalate { reason? }
POST /conversations/:id/rating { score: 1..5, comment? }
GET /conversations/:id/ws?token=<sessionToken>SSE events
Stream format: event: <type>\ndata: <json>\n\n. Types: message.created, assistant.delta, tool.started, tool.finished, action.required, action.updated, assistant.completed, conversation.updated, error, done.
Authorization
All conversation routes require Authorization: Bearer <sessionToken>. Conversations are scoped to (tenant, end_user).