API pipeline: Run a self-hosted Cabi.Chat widget with your own program
Index: API pipelines — index
Goal: your own program answers people in a Cabi.Chat widget's rooms: a script, a support service, or your own AI assistant such as Claude Code. Cabi.Chat gives the widget a token that works like a Telegram bot token; Cabi.Chat's AI does not answer. What a widget is and who can reach it: Cabi.Chat Oracles — Cabi.Chat widget
Steps
1. Create.
POST /v0/my/oracles
Idempotency-Key: widget-mine-1
{"kind": "cabi_widget", "hosting": "self", "title": "My assistant", "project": "<project nonce>"}
→ {"nonce": "470000000000000004", "card_type": "oracle", "kind": "cabi_widget",
"status": "STOPPED", "token": "…", …}
token: shown only in this answer. Store it in your program's settings, never in a card or an agenda.agenda: optional. Set it only when your program should also call the Cabi.Chat API as that agenda, with the token asAuthorization: Bearer <token>: Cabi.Chat API — Apps- Who may talk to it:
visibility,publicity,permissions, as for any widget; Private (only you) by default. topics_in_private:trueby default: a person's private chat with the widget can hold threads (topics), like «Threaded mode» in @BotFather. Change it later withPATCH(owner only).
2. Point your program at the Cabi.Chat Bot API with that token. Every request goes to https://api.cabi.chat/bot<token>/<method>, the same shape as Telegram's:
GET https://api.cabi.chat/bot<token>/getMe
GET https://api.cabi.chat/bot<token>/getUpdates?timeout=50
POST https://api.cabi.chat/bot<token>/sendMessage {"chat_id": <chat id>, "text": "…"}
Receive updates by long polling or by a webhook you set with setWebhook, and answer with the usual methods. Supported methods: Spectral — plugins via the Telegram bot emulator
Files: getFile gives a file_path; download it from https://api.cabi.chat/file/bot<token>/<file_path>.
3. Talk. Each person who opens the widget gets a room with it: a private chat with your widget, as in Telegram. Their messages arrive as updates with chat.type private and chat.id equal to the person's user id; what your program sends to that chat appears in the room.
- User ids are short and stable, in the range Telegram clients expect (52 bits); a user id is not the nonce of the person's project. Chats opened earlier keep their chat ids.
- With
topics_in_privateon,getMeshowshas_topics_enabledandallows_users_to_create_topics, and threads work in the private chat as in Telegram: a message in a thread carriesmessage_thread_id; send with the samemessage_thread_idto answer in that thread. - A group room your widget is added to is a
supergroupwith forum topics; threads work there too.
Opening a room: API pipeline: Set up a Cabi.Chat widget that Cabi.Chat's AI runs, step 4.
Example: Claude Code
Claude Code can talk to you through a Cabi.Chat widget: it runs on your own machine under your own sign-in, and Cabi.Chat is only the chat surface. The official Claude Code Telegram channel plugin speaks the Telegram Bot API, so it works with any Telegram-compatible Bot API root, https://api.cabi.chat included. The plugin setting that points it at another Bot API root is pending upstream; once your plugin version has it:
- In Claude Code:
/plugin install telegram@claude-plugins-official, then/telegram:configure <widget token>. - Set the plugin's Bot API root to
https://api.cabi.chat. - Start Claude Code with the channel:
claude --channels plugin:telegram@claude-plugins-official. - Open the widget's room on Cabi.Chat and write to it; pair with
/telegram:access pair <code>and lock it with/telegram:access policy allowlist, so only you can drive your session.
Your room with the widget is a private chat, so pairing, commands and permission prompts work as they do with a Telegram bot; with topics_in_private on, you can keep separate threads in it.
Keep the widget Private so only you can open its room.
Rules
hosting: "self"is forcabi_widgetonly; any other kind → 400only a cabi widget can be self-hosted.- Lost the token?
POST /v0/my/oracles/{nonce}/regenerate-token→{"token": "…", "token_preview": "…"}, the token shown once; the previous token stops working at once. Owner only. - The token is made from the web app or with your own personal access token, never from an app you connected (403).
- Cabi.Chat charges no AI for a self-hosted widget; your program's AI is your own.
DELETE /v0/my/oracles/{nonce}deletes the widget; its token stops working.
API surface
| Endpoint | Purpose | FE | AI / oracle |
|---|---|---|---|
POST /v0/my/oracles |
Create the widget, get its token once | yes (token: no) | your token |
POST /v0/my/oracles/{nonce}/regenerate-token |
A new token; the old one stops | no | your token |
PATCH /v0/my/oracles/{nonce} |
Title, project, visibility, agenda, topics_in_private |
yes | yes |
https://api.cabi.chat/bot<token>/<method> |
Receive and answer as the widget | — | your program |
DELETE /v0/my/oracles/{nonce} |
Delete | yes | rarely |