API pipeline: Read and answer your conversations

Index: API pipelines — index

Goal: read and answer your conversations live: list rooms, read history, send text and files, reply, edit, delete, react, pin, mark read.

A room is a card (card_type: room). talk.kind says what it is: native (project-to-project room on Cabi.Chat), telegram_oracle (a conversation of your Telegram oracle with a person in Telegram) or widget (a chat with an AI widget). In native rooms you speak as one of your projects; in your oracle's conversations what you send goes to the person in Telegram as your oracle.

Your Telegram oracle's conversations are Unlisted: only you, and those you share a conversation with by a link or grant, can open them.

Steps

1. List rooms.

GET /v0/my/rooms?limit=50&offset=0
→ {"rooms": [{"nonce": "470000000000000300", "card_type": "room",
              "i18n": [{"lang": "en", "title": "Project: Green Bakery", …}],
              "talk": {"kind": "native", …}, "role": "owner", "unread": 2,
              "permissions": {"send_messages": true, "send_media": true, "pin": true, …}, …}],
   "total": 14, "has_more": false}

unread per room; permissions is what you may do in it.

2. Open a room. GET /v0/my/rooms/{nonce|@handle}?scene=30 → the room, its state (member_count, pinned, settings), unread and the last 30 messages in scene.

Assistant notes. In your oracle's conversations the room carries llm_memory: what the oracle keeps about this conversation and sees in its prompt (plain text). It is read-only: only the oracle writes it. Whoever can fully read the room gets it: you, and the people or agendas you share the room with; empty notes are left out. The room's text (content) stays your own notes.

3. Read history.

GET /v0/my/rooms/470000000000000300/talk?limit=50
→ {"messages": [{"id": "<event id>", "seq": 812, "kind": "text", "text": "Do you deliver on Sundays?",
                 "sender": {"name": "Green Bakery", "is_self": false, …}, "timestamp": 1760540000000,
                 "reply_to": null, "edited": false, "deleted": false,
                 "reactions": [{"key": "👍", "count": 1, "mine": true}], …}]}

4. Send.

POST /v0/my/rooms/470000000000000300/talk/send
{"text": "Yes, 8:00 to 14:00.", "reply_to": "<event id>"}
→ {"event_id": "<event id>"}

Optional: formatted_body (HTML version of the text), thread_id (when threads are on), reply_to.

5. Send a file. POST …/talk/send-media, multipart: file (required, up to 25 MB), text (caption), thread_id → {"event_id": …}.

6. Change messages.

POST …/talk/edit    {"event_id": "<id>", "text": "Yes, 8:00 to 15:00."}
POST …/talk/delete  {"event_id": "<id>"}
POST …/talk/react   {"event_id": "<id>", "key": "👍"}            add; "remove": true takes it back
POST …/talk/pin     {"event_id": "<id>", "pinned": true}          false unpins

7. Read state. POST …/talk/mark-read {"last_event_id": "<id>"} (omit: up to the latest) → 204, clears unread. POST …/talk/typing {"typing": true} → 204 shows you typing.

Live updates. GET /v0/my/sse (with your token) is a server-sent event stream. Each new message in any of your rooms arrives as:

event: talk_message
data: {"kind": "talk_message", "room": "470000000000000300", "event_id": "<id>", "seq": 813, …}

Then re-read that room's history. Keep-alive comments keep the stream open. Open streams per account are limited: a new one beyond the limit closes the oldest.

Behind

Rules (400)

API surface

Endpoint Purpose FE AI / oracle
GET /v0/my/rooms, GET /v0/my/rooms/{ident} Rooms, one room with recent messages yes yes
GET /v0/my/rooms/{ident}/talk History yes yes
POST …/talk/send, …/talk/send-media Send text, file yes yes
POST …/talk/edit, …/delete, …/react Change messages yes yes
POST …/talk/pin Pin no yes
POST …/talk/mark-read, …/typing Read marker, typing yes yes
GET /v0/my/sse Live events yes yes

Mentioned