Skip to content

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.


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.


GET /v1/organizations lists the organizations where you are a member. A user token sees only its own organization.

Terminal window
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.

POST /v1/organizations creates an organization. You become its Super Administrator.

Terminal window
curl -b cookies.txt \
-H "Origin: https://api.example.com" \
-H "Content-Type: application/json" \
-d '{"name":"Research"}' \
https://api.example.com/v1/organizations

When organizationCreation in the platform settings is platform_admins, only platform admins can do this. Other callers get 403 with OrganizationCreationDisabled.

DELETE /v1/organizations/:organizationId/membership takes you out of an organization. Your tokens for it stop working at once.

Terminal window
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 409 with LastSuperAdministrator. Give someone else the role first.
  • A user token can only leave its own organization.
  • If your email domain is still verified and joinByDomain is on, you join again the next time you sign in.

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.

Terminal window
curl -X PATCH -H "Authorization: Bearer $OPENBOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Example Inc."}' \
https://api.example.com/v1/organization

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.

Terminal window
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 409 with SettingsConflict and the current version. Read them again, then try again.
  • A role that does not exist returns 400 with SettingsInvalid.
  • Only a Super Administrator can put super_administrator in defaultRoles.

Every instance uses a change at once. See Configuration.


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.

PATCH /v1/organization/members/:userId changes status, roles or policy. It needs write on Member.

  • status is active or suspended. A suspended member cannot use this organization, and their tokens for it stop working at once.
  • roles is a list of role IDs: built-in roles and custom roles. See Permissions.
  • policy is an extra policy for the member, on top of their roles. A deny rule in it wins over the roles. See Permissions.
Terminal window
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_456

Role IDs in paths must match the role ID schema. A member update that names a role which does not exist returns 404 RoleNotFound.

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.

  • 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_administrator in 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 409 with LastSuperAdministrator.

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.

Terminal window
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 the defaultRoles of the organization. Each role must exist, or OpenBot returns 404 with RoleNotFound.
  • Only a Super Administrator can invite with the super_administrator role.
  • An invitation lasts 7 days. Then its status is expired.
  • An email can have only one pending invitation in an organization. OpenBot returns 400 with InvitationInvalid when 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.

These routes are for the invited person. They do not need a membership.

  • GET /v1/invitations lists the pending invitations for your verified email. An invitation to use a Bot has bot and no roles. Accept it with POST /v1/bot-invitations/accept. See Share Bots.
  • POST /v1/invitations/:invitationId/accept makes you a member with the roles of the invitation. It returns the organization.
  • POST /v1/invitations/:invitationId/decline says 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.

Terminal window
curl -X POST -b cookies.txt \
-H "Origin: https://api.example.com" \
https://api.example.com/v1/invitations/inv_51c2/accept

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.

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.