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

RoleCan
OwnerEverything. One per install: the person who ran the setup wizard. Cannot be demoted.
AdminSee every project and team, manage members and invites, create projects and teams, delete issues.
MemberSee 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.

How access is computed

A person’s access to a project is the union of:

  1. Direct grants: they were added to the project itself.
  2. 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:

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:

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.

RouteWho
GET /teamsAnyone. 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 /invitesOrg 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:

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:

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.