Organization
For organization administrators. You need the rights named for each task. Only a
platform admin can change settings under /v1/platform. Start with the
administrator manual.
This page shows how many people share OpenBot. An organization is a group of people who share Bots, models and settings. One platform has many organizations. A user and an organization are separate things. A user can create organizations, also one just for themselves, and can be a member of many organizations.
The routes of the current organization are under /v1/organization. They accept
a user token or the session cookie. With the cookie, send the
OpenBot-Organization header when you belong to more than one organization. See
Authentication.
Who can join
Section titled “Who can join”Each time an account signs in, OpenBot checks where it belongs. It also checks on each request with the session cookie.
| Way | Role it gets | Needs |
|---|---|---|
| Invitation | The roles of the invitation | An administrator invited the verified email of the account, and the account accepts. See Invitations. |
| Verified domain | The defaultRoles of the organization |
The organization verified the domain of the email, joinByDomain is true, and the provider verified the email. |
| SSO connection | The defaultRoles of the organization |
The account signed in through the SSO connection of the organization. |
| New organization | super_administrator |
The account calls POST /v1/organizations. See Create an organization. |
OpenBot never makes an organization for a new account. An account without any
organization gets 403 with MembershipRequired from organization routes. It
can still create an organization and answer invitations.
Older versions of OpenBot made an organization named “Personal” for each new
account. Those organizations stay. They are normal organizations, so you can
rename them, invite people, or leave them. See SSO and domains to verify
a domain, and Platform for
organizationCreation.
Your organizations
Section titled “Your organizations”GET /v1/organizations lists the organizations where you are a member. A user
token sees only its own organization.
curl -b cookies.txt https://api.example.com/v1/organizations{ "items": [ { "id": "org_8f3a", "name": "Example", "status": "active", "createdAt": "2026-10-21T09:00:00.000Z" } ]}status is active or suspended. A platform admin can suspend an
organization. Then nobody can use it, and its tokens stop working. See
Platform.
Create an organization
Section titled “Create an organization”POST /v1/organizations creates an organization. You become its Super
Administrator.
curl -b cookies.txt \ -H "Origin: https://api.example.com" \ -H "Content-Type: application/json" \ -d '{"name":"Research"}' \ https://api.example.com/v1/organizationsWhen organizationCreation in the platform settings is platform_admins, only
platform admins can do this. Other callers get 403 with
OrganizationCreationDisabled.
Leave an organization
Section titled “Leave an organization”DELETE /v1/organizations/:organizationId/membership takes you out of an
organization. Your tokens for it stop working at once.
curl -X DELETE -b cookies.txt \ -H "Origin: https://api.example.com" \ https://api.example.com/v1/organizations/org_8f3a/membership- The last active Super Administrator cannot leave. OpenBot returns
409withLastSuperAdministrator. Give someone else the role first. - A user token can only leave its own organization.
- If your email domain is still verified and
joinByDomainis on, you join again the next time you sign in.
Read and change the organization
Section titled “Read and change the organization”GET /v1/organization reads the current organization. It returns the same
object as above. PATCH /v1/organization changes its name. It needs write
on Organization.
curl -X PATCH -H "Authorization: Bearer $OPENBOT_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name":"Example Inc."}' \ https://api.example.com/v1/organizationSettings
Section titled “Settings”Each organization has its own settings. They live in the database, so every
OpenBot instance uses the same values. GET /v1/organization/settings reads
them. It needs read on Organization.
{ "version": 2, "rulesModel": { "_tag": "Config.Selection", "provider": "prov_4c1e...", "model": "gpt-4.1-mini" }, "botMemoryModel": null, "botMemory": true, "requestTimeoutMs": 86400000, "delegationTimeLimitMs": 3600000, "toolForegroundBudgetMs": 30000, "toolMaxDurationMs": 3600000, "maxBackgroundOperations": 8, "planApproval": { "approver": "chain", "timeoutMs": 86400000, "onTimeout": "stay" }, "appReadRules": [], "defaultRoles": ["member"], "joinByDomain": true, "tokenRate": { "organization": null, "member": null, "bot": null, "token": null }, "updatedAt": "2026-10-21T09:00:00.000Z"}| Field | Default | What it does |
|---|---|---|
rulesModel |
null |
The model that judges Rules. It can be a language model or a decision model. null means that no model judges them. See Models. |
botMemoryModel |
null |
The model that learns Bot memory. null means that Bots learn nothing. |
botMemory |
true |
Let the memory Bot learn from Chats and add to the input of Turns. |
requestTimeoutMs |
24 hours | How long a request waits for an answer before OpenBot denies it. From 1 second to 7 days. |
delegationTimeLimitMs |
1 hour | The time limit of work that has none of its own, such as the work of a trigger. From 1 minute to 30 days. |
toolForegroundBudgetMs |
30 seconds | How long a tool call runs in its Turn before it goes to the background. From 0 to 10 minutes. 0 sends every call to the background. |
toolMaxDurationMs |
1 hour | The longest time of a background tool call. After it, the call stops and fails. From 1 second to 24 hours. |
maxBackgroundOperations |
8 | How many background tool calls of one Chat may run at one time. From 0 to 100. |
planApproval |
ask the decider above, stay a plan after 24 hours | How a plan is approved when no member, Bot or Chat sets it. See Plan mode. |
appReadRules |
[] |
App tools that only read: { cardUrl, tool }. See Requests. |
defaultRoles |
["member"] |
The roles of a new member. |
joinByDomain |
true |
People with a verified email in a verified domain of the organization join when they sign in. |
tokenRate |
no limit | Token rates of each scope. Where the platform sets a lower rate, the lower rate applies. See Token rate. |
PATCH /v1/organization/settings changes them. It needs write on
Organization. The body needs expectedVersion, the version that you read.
Add only the fields that you want to change.
curl -X PATCH -H "Authorization: Bearer $OPENBOT_TOKEN" \ -H "Content-Type: application/json" \ -d '{"expectedVersion":2,"requestTimeoutMs":3600000,"joinByDomain":false}' \ https://api.example.com/v1/organization/settings- If someone changed the settings after you read them, OpenBot returns
409withSettingsConflictand the currentversion. Read them again, then try again. - A role that does not exist returns
400withSettingsInvalid. - Only a Super Administrator can put
super_administratorindefaultRoles.
Every instance uses a change at once. See Configuration.
Members
Section titled “Members”GET /v1/organization/members lists members in pages. It needs read on
Member. Use limit (1 to 100, default 50) and after with the next value
of the last page.
{ "items": [ { "userId": "u_123", "email": "ada@example.com", "name": "Ada", "status": "active", "roles": ["super_administrator"], "policy": "{\"_tag\":\"Rules\",\"algorithm\":\"denyOverrides\",\"rules\":[]}", "joinedAt": "2026-10-21T09:00:00.000Z" } ], "next": null}GET /v1/organization/members/:userId reads one member.
Change a member
Section titled “Change a member”PATCH /v1/organization/members/:userId changes status, roles or policy.
It needs write on Member.
statusisactiveorsuspended. A suspended member cannot use this organization, and their tokens for it stop working at once.rolesis a list of role IDs: built-in roles and custom roles. See Permissions.policyis an extra policy for the member, on top of their roles. A deny rule in it wins over the roles. See Permissions.
curl -X PATCH -b cookies.txt \ -H "Origin: https://api.example.com" \ -H "Content-Type: application/json" \ -d '{"roles":["administrator"]}' \ https://api.example.com/v1/organization/members/u_456Role IDs in paths must match the role ID schema. A member update that names a
role which does not exist returns 404 RoleNotFound.
Remove a member
Section titled “Remove a member”DELETE /v1/organization/members/:userId removes the member and revokes their
tokens. It needs write on Member. If their email domain is still verified
and joinByDomain is on, or they sign in through an SSO connection, they join
again the next time they sign in. To keep them out, suspend them.
Rules for Super Administrators
Section titled “Rules for Super Administrators”- Only a Super Administrator can change or remove a Super Administrator, or give someone the role.
- Only a Super Administrator can give a member a policy with allow rules, or put
super_administratorin the default roles. Other administrators can only give policies with deny rules. So nobody can give more than they have. - The organization keeps at least one active Super Administrator. A change that
breaks this returns
409withLastSuperAdministrator.
Invitations
Section titled “Invitations”An administrator invites a person by email. The person signs in with that email, and then accepts or declines. OpenBot does not send the email. Tell the person yourself.
POST /v1/organization/invitations makes an invitation. It needs write on
Member.
curl -b cookies.txt \ -H "Origin: https://api.example.com" \ -H "Content-Type: application/json" \ -d '{"email":"grace@example.com","roles":["member"]}' \ https://api.example.com/v1/organization/invitations{ "id": "inv_51c2", "organizationId": "org_8f3a", "organizationName": "Example", "email": "grace@example.com", "roles": ["member"], "status": "pending", "invitedBy": "u_123", "createdAt": "2026-10-23T09:00:00.000Z", "expiresAt": "2026-10-30T09:00:00.000Z"}- Without
roles, the person gets thedefaultRolesof the organization. Each role must exist, or OpenBot returns404withRoleNotFound. - Only a Super Administrator can invite with the
super_administratorrole. - An invitation lasts 7 days. Then its
statusisexpired. - An email can have only one pending invitation in an organization. OpenBot
returns
400withInvitationInvalidwhen there is one, or when a member already has the email.
You can also invite people to use one Bot. See Share Bots.
GET /v1/organization/invitations lists the invitations, newest first. It needs
read on Member. Add ?status=pending to see only the open ones.
DELETE /v1/organization/invitations/:invitationId takes back a pending
invitation. It needs write on Member.
Answer an invitation
Section titled “Answer an invitation”These routes are for the invited person. They do not need a membership.
GET /v1/invitationslists the pending invitations for your verified email. An invitation to use a Bot hasbotand noroles. Accept it withPOST /v1/bot-invitations/accept. See Share Bots.POST /v1/invitations/:invitationId/acceptmakes you a member with the roles of the invitation. It returns the organization.POST /v1/invitations/:invitationId/declinesays no.
To answer, use the session cookie, not a user token. Your email must be verified
and equal to the email of the invitation. An invitation for another email
answers 404 with InvitationNotFound.
curl -X POST -b cookies.txt \ -H "Origin: https://api.example.com" \ https://api.example.com/v1/invitations/inv_51c2/acceptAudit log
Section titled “Audit log”The audit log records important changes. Nothing can change or remove an entry.
GET /v1/organization/audit_logs lists entries, newest first. It needs read
on AuditLog.
| Query | What it does |
|---|---|
limit |
1 to 100. The default is 50. |
after |
The next value of the last page. |
action |
Only entries with this action. |
actor |
Only entries by the member with this user ID. |
{ "items": [ { "id": "42", "createdAt": "2026-10-21T09:05:00.000Z", "action": "member.updated", "actor": { "kind": "member", "userId": "u_123", "organizationId": "org_8f3a" }, "resource": "openbot.org.org_8f3a.user.u_456", "details": { "before": { "status": "active", "roles": ["member"], "policyRules": 0 }, "after": { "status": "active", "roles": ["administrator"], "policyRules": 0 } } } ], "next": "42"}| Action | When |
|---|---|
member.joined |
An account joins the organization. |
member.updated |
A member gets a new status, roles or policy. |
member.removed |
A member is removed. |
member.left |
A member leaves the organization. |
invitation.created |
A member invites an email. |
invitation.revoked |
A member takes back an invitation. |
invitation.accepted |
The invited person accepts. |
invitation.declined |
The invited person declines. |
organization.created |
Someone creates an organization. |
organization.updated |
The organization gets a new name. |
settings.updated |
The organization settings change. |
role.created |
A member makes a custom role. |
role.updated |
A member changes a custom role. |
role.deleted |
A member deletes a custom role. |
model.created |
A member adds a model. |
model.updated |
A member changes a model. |
model.deleted |
A member removes a model. |
model_provider.created |
A member adds a model provider. |
model_provider.updated |
A member changes a model provider. |
model_provider.deleted |
A member removes a model provider. |
domain.added |
A member adds an email domain. |
domain.verified |
An email domain becomes verified. |
domain.removed |
A member removes an email domain. |
sso_connection.created |
A member adds an SSO connection. |
sso_connection.updated |
A member changes an SSO connection. |
sso_connection.deleted |
A member removes an SSO connection. |
token.created |
A member creates a user token. |
token.revoked |
A member revokes a user token. |
bot.created |
A member makes a Bot. |
bot.updated |
A member changes a Bot. |
bot.memory.updated |
A member changes Bot memory. |
bot.memory.purged |
A member removes Bot memory by a tag. |
bot.memory_bot.updated |
A member changes the memory Bot. |
delegation.started |
A Bot gives work to a Bot. |
delegation.completed |
Delegated work ends. |
capability.decided |
A person answers a request. |
request.resolved |
A request closes. details.chain lists the Bots. |
grant.created |
A member makes a Grant. |
grant.revoked |
A member revokes a Grant. |
rule.created |
A member adds a Rule. |
rule.updated |
A member changes a Rule. |
Errors
Section titled “Errors”InvitationNotFound returns 404. It has invitationId when the request names
an invitation. When a Bot link secret matches no invitation, this field is
absent.
| Status | Error | When |
|---|---|---|
400 |
InvitationInvalid |
The invitation cannot be made or answered now, for example because it expired. |
404 |
InvitationNotFound |
There is no invitation with this ID for you. |
404 |
RoleNotFound |
An invitation names a role that does not exist. |
403 |
Forbidden |
The policy of the caller does not allow it. See Permissions. |
400 |
OrganizationRequired |
A cookie request without OpenBot-Organization, and you have more than one organization. |
400 |
SettingsInvalid |
A value in the settings is not valid, such as a role that does not exist. |
403 |
MembershipRequired |
You are not an active member of the organization. |
403 |
OrganizationCreationDisabled |
Only platform admins can create organizations on this platform. |
404 |
MemberNotFound |
No member has this user ID. |
409 |
SettingsConflict |
Someone changed the settings after you read them. |
409 |
LastSuperAdministrator |
The change would leave no active Super Administrator. |
503 |
OrganizationStorageUnavailable |
OpenBot cannot reach its database. |