Invite your team

Access is per organization, with four roles. Invite people from the dashboard and pick the role that fits.

Invite from the dashboard

Go to Organization → Members and choose Invite. Enter the teammate's email address, pick a role, and create the invitation. The invitation link appears once, so copy it then and pass it along however you like, by your own email, Slack, or a message. The invitee opens the link and accepts, which creates their account along the way if they need one.

  • Already have an account? Use Add member to attach an existing account to the organization straight away, with no invitation step.
  • Change a role at any time from the role column on the Members table. Remove a member, or revoke a pending invitation, from the same row.
  • Inviting and managing members takes the admin or owner role. The last owner stays an owner: you can remove or demote them only once another owner exists.

What each role can do

Roles run viewer, member, admin, owner, and each is a superset of the one before it.

RoleCan
viewerRead everything: messages, stats, settings
memberOperate servers: send-side resources, templates, suppressions, webhooks
adminManage members, invitations and organization settings
ownerEverything, including deleting the organization; the last owner stays an owner

Global admins (created with make-user --admin or the users API) sit above every organization. Reserve them for operations rather than daily work.

Two-factor and SSO

  • Two-factor. TOTP enrollment is self-service under Account → Security, and passkeys are supported for sign-in too. Ask your team to turn it on.
  • SSO. With OIDC or SAML, users are provisioned on first login when oidc.auto_provision is on. See Set up SSO. Their role in the org still comes from membership, so assign it as above.

Sensible defaults

  • Default to member; promote deliberately.
  • Give auditors and read-only dashboards the viewer role.
  • Keep at least two owners, because vacations happen.

Same thing over the API

To script invitations, post to the management API. The response carries the invitation token once, the same token the dashboard shows you. The invitee accepts at {frontend_url}/invitations/accept?token={token}, and invitations expire after auth.invitation_expiry_days (default 7).

POST /api/v2/admin/organizations/{org}/invitations
   { "email_address": "ada@acme.com", "role": "member" }
TOTP and passkey enrollment, sessions, and the accept flow are in the accounts API.