Teams & access
One install is one organisation. Everyone in it has an org role. Teams group people and projects, so you can grant a whole team access to a set of projects instead of adding people one project at a time.
Org roles
| Role | Can |
|---|---|
| Owner | Everything. One per install: the person who ran the setup wizard. Cannot be demoted. |
| Admin | See every project and team, manage members and invites, create projects and teams, delete issues. |
| Member | See and triage issues in the projects they have access to. |
Teams
Settings → Teams. Org owners and admins create and delete teams. A team has members and projects, and each member is a team member or team admin.
- Team members see every project in the team.
- Team admins can rename the team, add or remove members (existing org users, by email), change team roles, and add or remove projects. They can only add a project they already administer, so a team admin can’t pull in a project they only view.
- Team admins administer the team’s projects too.
How access is computed
A person’s access to a project is the union of:
- Direct grants: they were added to the project itself.
- Team grants: they are in a team that has the project.
They are a project admin if they are an org owner/admin, a direct admin of the project, or an admin of a team that has it. Org owners and admins see everything regardless.
Removing someone from a team removes only what that team gave them. Direct grants and other teams stay.
Invites
Settings → Members → Invite. Pick:
- Org role: admin or member.
- Teams: which teams they join, and as team member or team admin.
- Projects: direct project grants, on top of what their teams give.
With SMTP set up, the invite is emailed. Without it, copy the invite link and send it yourself. The link expires in 7 days. The invitee sets a password when they accept, and gets the role, teams and projects from the invite.
Signup is invite-only. There is no SSO in v1.
Re-inviting an existing member sends no link. It applies the teams and projects in the invite straight away, and it only ever adds or raises:
- New teams and projects are added. Existing ones are kept.
- A team role goes from member to admin, never down.
- The org role goes from member to admin, never down.
To take access away, remove them from the team or project, or change their role in Settings → Members.
API
All under /api/v1, with an API token. Writes need a write token.
| Route | Who |
|---|---|
GET /teams | Anyone. Lists the teams you can see (all of them for org owners/admins): slug, name, member and project counts, your role. |
POST /teams {"name"} | Org owner/admin. Returns {"slug"}. |
GET /teams/{slug} | Team members, org owners/admins. Includes members and projects. |
PATCH /teams/{slug} {"name"} | Team admins. Renames. |
DELETE /teams/{slug} | Org owner/admin. |
POST /teams/{slug}/members {"email", "role"} | Team admins. Adds an existing org user, or raises their team role. |
DELETE /teams/{slug}/members {"email"} | Team admins. |
POST /teams/{slug}/projects {"project"} | Team admins who administer that project. |
DELETE /teams/{slug}/projects {"project"} | Team admins. |
POST /invites | Org owner/admin. See below. |
curl -X POST https://errors.example.com/api/v1/invites \
-H "Authorization: Bearer of_..." -H "Content-Type: application/json" \
-d '{"email":"ada@example.com","role":"member",
"teams":[{"slug":"mobile","role":"admin"}],
"projects":["web"]}'
It returns {"email", "link", "existing"}. For an existing member, link is null, existing is true, and the grants were applied.
MCP
The MCP server has the same tools:
list_teams: teams you can see, with counts and your role.create_team{name}: org owner/admin, write token. Returns the slug.add_to_team{team, email?, role?, project?}: write token, team admins. Adds an existing org member (or raises their role), and/or a project you administer.invite_member{email, role?, teams?: [{slug, role?}], projects?: [slug]}: org owner/admin, write token. Returns the invite link, or applies the grants for an existing member.
Projects
Each project has its own DSN keys, platform, retention (default 90 days), in-app rules and webhooks. Manage them in Settings → Projects. A project can have more than one DSN key, so you can rotate one without downtime.
API tokens
Tokens are personal: a token can do what you can, never more.
Create one in Settings → API tokens:
- Scope:
readorwrite. Read tokens can list and fetch. Write tokens can also resolve, mute, assign, link fixes, change notification prefs and upload source maps. - Project: all your projects, or one. A project-scoped token only sees that project, even if you can see more.
- Label: so you know what to revoke later.
The token (of_…) is shown once. It is stored hashed. Revoke it any time in the same place.
Use it as a bearer token:
curl -H "Authorization: Bearer of_..." https://errors.example.com/api/v1/me
The same token works for the REST API, MCP and source map uploads. The iOS app gets its own write token when you pair it, tied to that device.
Sessions
Browser sessions last 30 days. Login attempts are rate limited per IP: more than 10 in 15 minutes and you have to wait.