Bots and chats
List, create, edit and delete bots, read conversations, and edit, pin and delete messages.
Bots
| Method | Path | Body | Returns |
|---|---|---|---|
GET |
/bots |
BotSummary[]: each bot's profile, the latest message, message count and whether a reply is running |
|
GET |
/bots/{id} |
BotConversation: the profile, every message, the running turn and its waiting cards |
|
PUT |
/bots |
BotProfile |
The saved BotProfile. An id that doesn't exist yet creates the bot. |
DELETE |
/bots/{id} |
204. Deletes the bot and its conversation. |
|
DELETE |
/bots/{id}/messages |
204. Clears the conversation; the bot stays. |
Create a bot
curl -s -X PUT $INKBOT/api/bots \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{
"id": "scout",
"name": "Scout",
"job": "Research assistant",
"askMeFor": "finding sources and summarizing them",
"instructions": "Cite every source with a link.",
"modelKey": "anthropic/claude-opus-5-5",
"effort": "Balanced"
}'
modelKey is a key from GET /models: the provider id and the model id, as in anthropic/claude-opus-5-5. PUT replaces the whole profile, so send every field you want to keep: read the bot first, change it, and send it back. For a group chat, set isGroup: true and list members (bot ids). See BotProfile for every field.
Adding Blotter or Quill sites (blotterSites, quillSites) issues the bot's own agent or key on those sites during the save, and removing one revokes it. If a site can't be reached, the call returns an error, but the profile is still saved; a missing Quill key is tried again before the bot's next reply. name is required. An empty id gets a new one.
Messages
| Method | Path | Body | Returns |
|---|---|---|---|
PUT |
/bots/{id}/messages/{messageId} |
{ "text": "..." } |
Changes one of your messages and removes everything after it. Then call respond. |
POST |
/bots/{id}/messages/{messageId}/truncate |
{} |
Removes every message after this one (to regenerate the reply that followed). |
DELETE |
/bots/{id}/messages/{messageId} |
204. Not while the bot is replying. |
|
PUT |
/bots/{id}/messages/{messageId}/pin |
{ "pinned": true } |
Pins or unpins. Pinned messages are always kept in what the model sees. |
GET |
/bots/{id}/attachments/{fileName} |
The file's bytes. fileName is an attachment's fileName from a message. |
Memory and prompt
| Method | Path | Body | Returns |
|---|---|---|---|
GET |
/bots/{id}/memory |
BotMemory: its facts, the archive, and the file they're kept in |
|
PUT |
/bots/{id}/memory |
MemoryEntry[] |
BotMemory. Replaces every fact. |
POST |
/bots/{id}/memory/tidy |
BotMemory. Tidies with the bot's model now. |
|
GET |
/bots/{id}/prompt |
PromptPreview: what the bot is sent besides your message, section by section, with token counts |
A MemoryEntry is { "text": "...", "topic": "Work", "until": "2026-11-02" }; topic and until are optional.
Files the chat changed
| Method | Path | Returns |
|---|---|---|
GET |
/bots/{id}/changes |
ChangeSetInfo[]: replies that changed files, newest first, each with its files and their lines added and removed |
GET |
/bots/{id}/changes/{messageId}?path=... |
FileDiff: one file's diff in one reply |
POST |
/bots/{id}/changes/{messageId}/undo |
UndoResult |
POST |
/bots/{id}/changes/{messageId}/redo |
UndoResult |
GET |
/bots/{id}/outputs |
OutputFile[]: files the chat's bots wrote or edited, newest first |
undo and redo take two optional query parameters: path (just that file) and overwrite=true. Files that changed again since the reply come back in conflicts, and nothing is done unless you send overwrite=true. Files that can't be put back (binary, or larger than 1 MB) come back in skipped.
Group goals
| Method | Path | Body | Returns |
|---|---|---|---|
PUT |
/bots/{groupId}/goal |
{ "text", "doneWhen", "maxRounds": 20, "maxMinutes": 60, "start": true } |
The group's BotProfile, with its goal |
DELETE |
/bots/{groupId}/goal |
204. Clears the goal. |