Organisations
Roles
An organisation can hold more than the person or agent who signed up for it. Everyone in it is a member holding one of three roles:
| Role | What it may do |
|---|---|
owner | Everything an admin may do, and also invite owners, make someone an owner, and change or remove another owner. |
admin | Invite people as admins or members, change a member's or admin's role, remove members and admins, cancel invitations, manage the organisation's API keys, and turn services on and off. |
member | Use the organisation's services, see who else is a member, and leave. A member cannot invite, cancel an invitation, change a role or remove anyone. |
The rule behind the table is that nobody grants more than they hold. An owner
grants any role, an admin grants admin or member, and a member grants
nothing. The same rule covers the role a member has now: an admin cannot
change or remove an owner. A request outside the rule is refused with
MEMBER_ROLE_NOT_GRANTABLE.
The founding owner, whoever first owned the organisation, cannot be
demoted, removed or leave, by anyone (MEMBER_FOUNDING_OWNER_PROTECTED). So
every organisation always has an owner. Any other owner can be demoted,
removed or leave like anyone else.
An agent's organisation belongs to the agent: its API key acts as the organisation's own agent, which is the founding owner. That agent manages members with the tools below, as an owner would.
Inviting people
Owners and admins invite from the dashboard's Members page, at
/dashboard/members, or with the organization_invite tool:
role: the role everyone in this invitation gets, one you may grant;emails: the addresses to invite. Case and repeats do not matter: each distinct address is invited once. The tool's input schema says how many one call takes.
Each address gets its own outcome, and one address refused does not stop the rest:
| Outcome | What it means |
|---|---|
invited | An invitation was recorded and its message sent. |
reissued | The address already had an invitation waiting. It was cancelled and a new one sent, so only the newest link works. |
already-member | The address already belongs to the organisation. Nothing was sent. |
refused | That address could not be invited this time. The outcome carries a code; invite it again to retry. |
The person invited must accept with an account whose address is the one invited, and that address must be verified. An invitation expires after the period its message states; a pending invitation shows when it expires, and an expired one can simply be sent again.
The whole invitation is refused, and nothing recorded, when invitations are
switched off on this deployment (INVITATIONS_DISABLED) or when it would take
the organisation past one of its limits (see Limits).
Accepting
The invitation message has a link. It opens the invitation page, where you sign in with the invited address (or sign up with it, if you have no account yet, and verify it) and accept or decline.
Accepting makes you a member at the invited role and lands you in the organisation you joined: the dashboard and your AI now work there. Your own organisation stays yours, with its keys, credit and data, and you can switch back to it at any time.
Switching
Every person works in one organisation at a time, their current organisation. Everything you do, in the dashboard and through an AI signed in as you, happens there: its keys, its credit, its services, its data.
- In the dashboard, the switcher at the top of the rail lists every organisation you belong to once you belong to more than one. Choosing one makes it current.
- An AI acting as you, through your own sign-in, uses
organization_listto see your organisations and which is current, andorganization_switchwith anorganizationIdto change it. A switch either of you makes is seen by the other from its next request. - An API key cannot switch. It acts as its organisation's own agent and
always works in that organisation;
organization_switchwith a key is refused withORGANIZATION_SWITCH_NOT_ALLOWED.
Switching is not leaving. You stay a member of the organisation you switched away from, with your role, and everything there is kept.
Managing members
Each of these acts on the current organisation, and the Members page offers the same actions to anyone whose role allows them:
organization_memberslists the members with their roles, marks the organisation's own agent and the founding owner, and gives each member'suserId.organization_invitationslists the invitations still waiting, with each one's role and expiry and itsinvitationId.organization_invitation_cancelcancels a waiting invitation by itsinvitationId; its link stops working.organization_member_rolegives a member (memberUserId) a newrole. You must be able to grant both the role they have and the new one. On the Members page, choosing a new role asks you to confirm before anything changes; cancelling leaves the role as it was. You can change your own role too, but you cannot give it back to yourself afterwards: another member who may grant it would have to, and the confirmation on your own row says so.organization_member_removeremoves a member (memberUserId). You cannot remove yourself; leave instead.organization_leavetakes you out of the current organisation. You land in another organisation you belong to, or your own.
The same operations on the REST API:
| Tool | REST |
|---|---|
organization_list | GET /api/v1/organizations |
organization_switch | PUT /api/v1/organizations/current with { "organizationId": "…" } |
organization_members | GET /api/v1/organizations/current/members |
organization_invitations | GET /api/v1/organizations/current/invitations |
organization_invite | POST /api/v1/organizations/current/invitations with { "role": "…", "emails": ["…"] } |
organization_invitation_cancel | DELETE /api/v1/organizations/current/invitations/{invitationId} |
organization_member_role | POST /api/v1/organizations/current/members/{memberUserId}/role with { "role": "…" } |
organization_member_remove | DELETE /api/v1/organizations/current/members/{memberUserId} |
organization_leave | DELETE /api/v1/organizations/current/membership |
current is always the organisation your credential is working in; no call
names another organisation to act on it.
If a member's role was changed by someone else between your reading it and
your change, the change is refused with MEMBER_ROLE_CHANGED: list the
members again and retry. A removed member, or one who leaves, keeps their own
account and organisation; what they made in the organisation they left stays
with it.
Limits
Changes to an organisation's members — inviting, cancelling, changing a role,
removing, leaving and switching — are throttled per caller: each person has
their own hourly allowance, and the organisation's API keys share one between
them, as its agent. It is counted across the API, MCP and the dashboard
together, and a change that is refused still counts. Past it a change is
refused as rate-limited (RATE_LIMITED; on the REST API, 429 with
Retry-After). Listing is not throttled.
An organisation may also send only so many invitation messages a day, new and
re-sent invitations alike. Past that, each further address in an invitation is
reported refused with RATE_LIMITED and nothing is recorded for it; the
rest of the invitation is still processed. Invite those addresses again later.
How many addresses one invitation takes, how many members an organisation may hold and how many invitations it may have waiting are all capped. A refusal says which cap it met:
| Refusal | The cap |
|---|---|
a validation error on emails (400 on the REST API) | too many addresses in one invitation |
ORGANIZATION_MEMBER_LIMIT_REACHED | the organisation's members, counting everyone in this invitation |
ORGANIZATION_INVITATION_LIMIT_REACHED | the invitations waiting, counting everyone in this invitation; cancel some, or wait for them to expire |