Organizations, projects and team members
Your personal organization, projects, the five roles and what each can do, access per project, invitations, leaving and transferring, the audit list, and how limits are shared by an organization's projects.
An organization is your team. It holds the plan, the limits, the members and the projects. A project holds the work: API keys, sessions, credentials, browser profiles and the rest. A member is a person in the organization, with a role.
Your SDKs, the CLI and the MCP server do not change. An API key still belongs to one project and works as it always did. This page is about who can do what in the console, and how the limits are shared.
| Level | What it holds |
|---|---|
| Organization | Its plan, limits and features. Its members and their roles. Its projects (up to 20). A suspension, if there is one. |
| Project | API keys, sessions, credentials, browser profiles, extensions, tasks, webhooks, model keys and the project settings. |
| Member | A role, and access to all projects or to chosen ones. |
Your personal organization
When you sign up, Boxline makes a personal organization on the Free plan, with a first project and a first API key. You are its owner. Accounts that existed before got a personal organization too. It holds the project they already had, with the same plan.
You cannot create more organizations yet. You join someone else’s organization when its owner or an admin invites you (see Invitations).
Where to manage it
Everything on this page is done in the console, signed in with your email and password:
- The switcher in the console header picks the organization and the project you work in. Switching checks your membership every time.
- Projects creates, renames, limits and deletes projects.
- Settings, Organization has the members, the invitations, ownership, leaving, and the audit list.
These actions need a console login. An API key has no role and is not a member, so it cannot manage an organization: the call gets 403 console_login_required.
Projects
Each project keeps its own API keys, sessions, credentials, browser profiles, extensions, tasks and webhooks. Owners and admins create, rename, limit and delete projects.
| Rule | Detail |
|---|---|
| Name | 1 to 100 characters, no control characters. |
| Sessions at once (optional) | A cap of 1 to 10,000 running sessions for this project, or none. See Limits. |
| How many | At most 20 projects in an organization. The 21st gets 409 limit_reached. |
| API keys | A new project has no API key. Switch to it and create one. |
Deleting a project
A project with running sessions cannot be deleted: the answer is 409 project_has_sessions. Stop or delete them first. Then deleting does this:
- Its API keys are revoked at once, so every program that uses them stops working.
- Its webhook endpoints are switched off.
- Its task schedules are switched off, and queued runs are canceled.
- Its credentials, model keys, browser profiles and extensions are deleted, with the files stored for them. They cannot be brought back.
- Members lose it from their chosen projects. A console login that was in it has no current project until the person picks another.
What stays: the history and usage of its sessions, because they count for the month they happened in. What a stopped session saved, and its recordings and logs, go with your plan’s retention, as for any stopped session. A session being created in the project at that moment is not started (404 not_found).
Deleting a project frees one of the 20 places. It does not give back any allowance: its usage still counts in its month.
Roles
A role says what a member can do. There are five: owner, admin, developer, viewer and billing. Roles are checked on every request.
| Action | Owner | Admin | Developer | Viewer | Billing |
|---|---|---|---|---|---|
| See the organization (its plan and limits), its members and its projects | Yes | Yes | Yes | Yes | Yes |
| Rename the organization | Yes | Yes | No | No | No |
| Delete the organization (only without projects), transfer ownership | Yes | No | No | No | No |
| Invite, change and remove admins, developers and viewers | Yes | Yes | No | No | No |
| Invite, change and remove owners and billing members | Yes | No | No | No | No |
| See the organization's credit, usage and spending limits | Yes | Yes | Yes | Yes | Yes |
| Set the spending limits of the organization and its projects | Yes | Yes | No | No | Yes |
| Create, rename, limit and delete projects, and read the audit list | Yes | Yes | No | No | No |
| Change the project settings (the Trajectories choice too) and model keys | Yes | Yes | No | No | No |
| Everything else in the projects they reach: sessions, agent runs, tasks, credentials, profiles, extensions, webhooks, API keys, the quick APIs, search and usage | Yes | Yes | Yes | Read only | No |
- Admins manage admins, developers and viewers. Only owners touch owners and billing members, or give those two roles. An admin who tries gets
403 role_forbidden; the message names the role. - Viewers only read. They cannot write anything. Session objects they get have
connectUrl,liveUrlandterminalUrlset tonull, because each of those controls the machine. They cannot open the live view or read a session’s files. - Billing members see the organization, its plan and limits, its members and the names of its projects. They also see its credit, its spend by project, and its spending limits, and they can set the limits. They see no project data, and their console login has no current project. See Credit and spending limits.
- An organization always has at least one owner. The last owner cannot leave, be removed or get another role: the answer is
409 last_owner. Make someone else an owner first.
Access per project
A member reaches all projects, or only chosen ones. This is the member’s projectAccess.
| Value | Who | What it means |
|---|---|---|
all | Owners and admins always. Developers and viewers if you choose it. | Every project of the organization, now and the ones made later. |
chosen | Developers and viewers only. | Only the 1 to 100 projects you pick. A project made later is not included. A project that is deleted leaves the list. |
none | Billing members. | No project. |
Someone who does not reach a project cannot switch to it: it answers as if it did not exist (404 not_found). A console login without a current project gets 409 no_project on project calls.
Invitations
Owners and admins invite people by email. You give the email, a role and the access (all projects or chosen ones). An admin can invite admins, developers and viewers. Only an owner can invite an owner or a billing member.
| Rule | Detail |
|---|---|
| The link | It is emailed to the invited address and never shown anywhere else. It opens the console’s invitation page, which shows the organization, the role and who invited them. |
| Valid for | 7 days, and it works once. |
| The invited email | The person has to sign up or sign in with that exact email. Another email gets 403 invite_email_mismatch. |
| The inviter | Needs a confirmed email. Without it the answer is 403 email_unconfirmed. |
| One at a time | One pending invitation per email in an organization (409 invite_pending; an expired one is replaced), and at most 50 pending (409 limit_reached). Someone who is a member already gets 409 already_member. |
| Withdraw | An owner or admin can withdraw a pending invitation (within the roles they manage). The link then gives 410 invite_withdrawn. |
| Rate limit | 20 invitations per hour for each organization and for each inviter. See Rate limits. |
A person who is new signs up with the invitation. A person who has an account signs in with the invited email and accepts. Either way they become a member with the invitation’s role and projects. A project deleted since is left out.
Sign-up with an invitation still makes the person a personal organization of their own. Their console login starts in the organization that invited them.
Accepting confirms the email, because the link was mailed to that address. The person does not need the 6-digit code.
When a link does not work
| Answer | Why |
|---|---|
404 invite_not_found | The link is not one of ours. |
410 invite_expired | It is older than 7 days. Ask for a new one. |
410 invite_used | It was used already. |
410 invite_withdrawn | Someone withdrew it, or its inviter can no longer give it (see below). |
403 invite_email_mismatch | The signed-in or signing-up email is not the invited one. |
An invitation lives only as long as the person who sent it may give it. When the inviter leaves, is removed, or gets a role that cannot give that role (an admin made developer, or an owner who transferred the organization, for owner and billing invitations), their pending invitations are withdrawn.
Leaving, removing and transferring
Leaving
Any member can leave. The last owner cannot (409 last_owner): hand the organization to another member first. After you leave, your other console logins for it end, and this one moves to your personal organization. Invitations you sent that were still pending are withdrawn.
Removing a member
Owners and admins remove members, within the roles they manage. The member’s console logins for the organization end at once, and invitations they sent that were still pending are withdrawn. Removing yourself is the same as leaving.
Transferring ownership
An owner can hand the organization to a member. That member becomes an owner, and you become an admin. Your pending invitations for owners and billing members are withdrawn, and your email has to be confirmed. There is always at least one owner.
Deleting the organization
Only an owner can, and only when it has no projects (409 organization_not_empty otherwise). Its members’ console logins for it end, and pending invitations are withdrawn.
The audit list
Owners and admins can read the audit list under Settings, Organization. It is newest first. Each entry has the time, the action, who did it, and what it was about (projectId, targetType, targetId and details). It never holds an API key or a token.
| Action | What happened |
|---|---|
organization.renamed | The organization got a new name. |
organization.deleted | The organization was deleted. |
organization.ownership_transferred | An owner handed ownership to another member. |
member.joined | Someone accepted an invitation. |
member.role_changed | A member got another role. |
member.access_changed | A member's projects changed. |
member.removed | A member was removed. |
member.left | A member left. |
invite.created | An invitation was sent. |
invite.withdrawn | An invitation was withdrawn. |
project.created | A project was created. |
project.renamed | A project got a new name. |
project.cap_changed | A project's concurrency cap changed. |
project.deleted | A project was deleted. |
api_key.created | An API key was created. |
api_key.revoked | An API key was revoked. |
account.recovered | A password reset recovered an account whose email was never confirmed. |
billing.limit_changed | A spending limit of the organization or of a project changed. It has the old and the new limit. |
billing.alert | A spending or credit alert was sent: 50%, 80% or 100% of a limit, low credit, or credit used up. |
credit.granted | We granted credit to the organization. It has the amount and the expiry. |
credit.adjusted | We corrected the organization's credit, up or down. It has the amount. |
plan.private_set | We gave the organization a custom plan, or changed it. |
plan.private_removed | The organization's custom plan was removed. |
via says how: console (a person signed in), api_key (an API key, with its id), support (Boxline’s staff, acting as the user to help with a problem or changing your credit or plan, never named) or system (Boxline itself, for alerts).
API keys
API keys stay per project. A key reaches only its own project, and the organization it can see is that project’s. Anyone who reaches a project as a developer, admin or owner can create a key in it. Viewers cannot.
Each key shows who made it, in createdBy: via (console, api_key or support), the user’s id and email, and the id of the key, when a key made it. It is null for keys made before this was recorded. A new key is shown once.
# The organization and project of the key (role is null: a key is not a member)curl https://api.boxline.dev/v1/auth/me \ -H "x-api-key: $BOXLINE_API_KEY" \ | jq '{organization: {id: .organization.id, name: .organization.name, plan: .organization.plan}, project: {id: .project.id, orgId: .project.orgId, concurrencyCap: .project.concurrencyCap}}'# Who created each keycurl https://api.boxline.dev/v1/project/api-keys \ -H "x-api-key: $BOXLINE_API_KEY" \ | jq '.data[] | {name, prefix, createdAt, lastUsedAt, createdBy}'{ "organization": { "id": "org_Hk2Lq8Zx0Vb5Nm1C", "name": "Acme", "plan": "free" }, "project": { "id": "prj_Hk2Lq8Zx0Vb5Nm1C", "orgId": "org_Hk2Lq8Zx0Vb5Nm1C", "concurrencyCap": null }}{ "name": "ci", "prefix": "bxl_ab12cd34", "createdAt": "2026-10-03T09:30:00.000Z", "lastUsedAt": null, "createdBy": { "via": "console", "userId": "usr_Q2x9L0aPz7NmK3Jb", "email": "dev@acme.example", "apiKeyId": null }}The key list is in List API keys, and the current user, organization and project has the whole GET /v1/auth/me answer. A new sign-up cannot create a key until it has entered its code: see Confirm your email.
Limits are shared
The plan belongs to the organization, and every project in it runs on that plan. Usage is added up across the organization’s projects, so more projects never give you more allowance.
| Limit | Counted over |
|---|---|
Running sessions (limits.concurrency) | Every running session of every project in the organization. |
| Model spend, proxy data, CAPTCHA solves and web searches, each per month | All the organization’s projects together, deleted ones included for the month they were used. Refusals say “this organization”. |
| Credentials, browser profiles, extensions, webhook endpoints, tasks and schedules | Each project on its own. |
| Credit and spending limits | One credit balance and one monthly spending limit for the whole organization, and an optional spending limit for each project. |
| Projects | At most 20 per organization. |
See Plans and features for each limit and what happens when you reach it. Money has its own page: Credit and spending limits says who can set a limit, and what happens at one.
A cap for one project
A project can have its own concurrencyCap, lower than the organization’s limit: 1 to 10,000, or none. Use it to stop one project, such as a test job, from taking every session the organization has. When the project’s running sessions reach the cap, a new one gets 429 concurrency_limit, with the message “this project allows N sessions at the same time”. The project’s cap does not raise the organization’s limit: a session starts only when neither is reached.
Both limits are checked when the request arrives, and again as the session is recorded (also when it is resumed). Sessions created at the same moment never pass a limit together: the later one gets the 429. The concurrencyCap of the key’s project is in project.concurrencyCap in GET /v1/auth/me.
Suspension
A suspension belongs to the organization, so it stops every project in it. See Suspended projects. The organization’s own pages in the console answer 403 organization_suspended, except reading it and leaving it.
Confirm your email
When you sign up, Boxline emails you a 6-digit code. Enter it in the console to confirm your email. Until you do, the new account can sign in only to confirm it. Signing in never asks for a code. The API reference has the details: how long a code lasts, the tries you get, and what an unconfirmed account cannot do.
A confirmed email is also what lets you invite people and transfer an organization. If your account is older than the code, it is never held back, but you need to confirm the email before you do either. You can confirm it whenever you like. A password reset, or accepting an invitation, confirms it too.
More
- Plans and features: the limits and feature switches of the organization’s plan.
- Credit and spending limits: the organization’s credit, monthly spending limits, and alerts.
- Errors and request ids: every code on this page.
- Changelog: when this arrived.
These docs describe a beta API. Endpoints, fields and SDK methods may change before general availability; breaking changes will be listed in the changelog.