Skip to content

Bots

An Bot is a worker with a role, such as a programmer, a writer or a designer. Each Bot has its own instructions, its own Sessions and its own long-term memory. Bots give work to each other, so each one keeps its attention on its own task. This page shows the kinds of Bots and the routes under /v1/bots. Every route accepts a user token or the session cookie. See Authentication.


Kind Owner Lives What it is for
persistent A member, the organization, or another Bot Until you archive it A lasting worker with a role. It learns from its work over time.
session One Session As long as the Session that owns it A helper for one line of work. It keeps its context in that Session.

A top Bot is a lasting Bot that a member or the organization owns, not another Bot. You can pick one top Bot as your default Bot.

A Session Bot is “almost lasting”. A Bot starts it with a tool while it works. The Session Bot keeps its context while its Session lasts, so the Bot can give it work many times. When you delete the Session, its Session Bots are archived too. You can promote a useful Session Bot to a lasting Bot.

A Bot can own lasting Bots too. See Bots that own Bots.

Every Session belongs to one Bot. See Sessions. How Bots give work to each other is on Delegation.

Your default Bot works when you create a Session or a trigger without a Bot. OpenBot does not make Bots for you, so a new member has no default Bot. Then a Session or a trigger without a Bot fails with 400 and BotInvalid.

To set your default Bot, make a Bot, and then send its ID in your member settings:

Terminal window
curl -X PATCH -H "Authorization: Bearer $OPENBOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"expectedVersion":0,"defaultBot":"bot_5c0e…"}' \
https://openbot.example.com/v1/me/settings

expectedVersion is the version from GET /v1/me/settings. The Bot must be one of your own top Bots or a shared Bot, and you need bots.delegate on it. If not, OpenBot returns 400 with SettingsInvalid. Send null to remove your default Bot.

You can still archive your default Bot. After that, a Session or a trigger without a Bot fails until you pick another default Bot.

Older versions of OpenBot made a Main Bot for each member. When you upgrade, each Main Bot becomes a normal lasting Bot, and it becomes the default Bot of its member. Its Sessions, memory and Grants stay.

Bots have no list of things they may do. A Bot just tries. When it tries something new for the first time, such as making a Bot or calling an App tool, the decider above it decides. See Requests. The decisions are kept, so the limits of each Bot grow from real work.


Terminal window
curl -H "Authorization: Bearer $OPENBOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Programmer","role":"Writes and reviews TypeScript code","instructions":"Write small, tested changes. Explain each change in one short paragraph."}' \
https://api.example.com/v1/bots
Field Meaning
name Required. A short name. OpenBot removes spaces at the start and end. The rest must have 1 to 100 characters.
role Required. What the Bot does, in one line. Other Bots read it to choose workers.
instructions Required. The lasting instructions of the Bot, like a job description.
model Optional. The model of the Sessions of this Bot, when a Session does not choose its own.
planApproval Optional. How the plans of this Bot are approved. See Plan mode.
shared Optional. true makes an organization Bot that every member can use.
bot Optional. The ID of the Bot that owns the new Bot. You cannot use it with shared.

OpenBot returns 201 with the Bot:

{
"id": "bot_5c0e…",
"kind": "persistent",
"owner": { "_tag": "Member", "userId": "u-1" },
"name": "Programmer",
"role": "Writes and reviews TypeScript code",
"instructions": "Write small, tested changes. …",
"archived": false,
"revision": 0,
"createdAt": 1792486800000,
"updatedAt": 1792486800000
}

owner is Member, Organization, Session or Bot. A shared Bot works with the permissions and the App connections of the member who uses it, never with those of the person who made it.

GET /v1/bots lists your own Bots and the shared Bots that you may use. Add ?archived=false to hide archived Bots. Add ?session=<id> to list the Session Bots of one Session. Add ?bot=<id> to list the Bots that one Bot owns.

GET /v1/bots/:botId returns one Bot.

Terminal window
curl -X PATCH -H "Authorization: Bearer $OPENBOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"expected":0,"instructions":"Write small changes with tests first."}' \
https://api.example.com/v1/bots/$BOT

expected is the current revision. You can change name (with the same rules as above), role, instructions, model (send null to remove it) and archived. When you archive a Bot, OpenBot also archives every Bot that it owns, and the Bots below them. When you unarchive it, only that one Bot comes back.

Terminal window
curl -H "Authorization: Bearer $OPENBOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"expected":3}' \
https://api.example.com/v1/bots/$BOT/promote

The Session Bot becomes a lasting Bot of the member. Send bot with the ID of a Bot to make that Bot its owner. OpenBot also adds the lasting entries of its Session memory to its Bot memory.

A Bot can promote a Session Bot of its own Session with the openbot_promote_bot tool. Then the Bot owns it.


A Bot can own lasting Bots. So a Bot can build its own team, and each member of the team keeps its own memory.

  • A Bot makes a Bot that it owns with the openbot_create_bot tool. A person makes one with POST /v1/bots and the bot field.
  • A Bot that another Bot makes with a tool, a lasting Bot or a Session Bot, gets the model of the Bot that makes it. The tool call can name another model.
  • The owner is { "_tag": "Bot", "bot": "<owner ID>", "userId": "<member>" }. userId is the member at the top of the owner tree. It is null when the organization owns the Bot at the top.
  • A Bot can give work to the Bots it owns without a request.
  • The owner chain of a Bot goes up through its owners to a top Bot, and then to the person. For example: person → Assistant → Worker → Scout. Requests of a Bot go up this chain, also when a person works with the Bot directly. See Requests.
  • Above a top Bot is the person who works with it. This is true for your own top Bots and for shared Bots.

OpenBot adds these to the instructions of every Turn:

  • the name, role and instructions of the Bot,
  • the person it works with now, with their name and member ID. In a Channel, it is the person who wrote the message of the Turn,
  • for a Session with work from another Bot, how to send the result back,
  • that it carries experience from its earlier work, and that the current instructions win over it.

The memory Bot can also add what helps to the input of the Turn. The Bot sees the additions as its own experience. It has the confide tool, and it knows it only as a place to say how its work goes.

You can also share a Bot with people in other organizations. They get a linked Bot with source, which uses your Bot.


Permission Lets you
bots.read Read Bots, their memory, Rules and Grants.
bots.write Make and change Bots, their memory, Rules and Grants.
bots.delegate Give work to a Bot, from a client or from another Bot.
bots.share Invite people to use a Bot.

Your own Bots are below your member key. Shared Bots are below openbot.org.<org>.bot. Members may read and use shared Bots. Administrators may also change and share them. See Permissions.

Status Error When
400 BotInvalid The change is not allowed, or you have no default Bot.
403 PermissionDenied You may read the Bot, but not change or use it.
404 BotNotFound There is no Bot with this ID that you may read.
409 BotConflict expected is old. Read the Bot again and retry.
503 BotStorageUnavailable OpenBot cannot reach its database.