Documentation
Sign inGet started

Users, teams & roles

Access for people in Bird is role-based: a user holds a role on your workspace, and each role is a fixed set of permissions. Nothing else needs configuring; pick the right role and the permissions follow.
Roles govern what people can do in the dashboard. What services can do is governed by API key scopes: the same permission vocabulary, granted per key instead of per role.

Workspace roles

The roles you work with day to day live on the workspace (see Workspaces): admin, developer, and analyst. Manage them in the dashboard under Settings → Team.
Every permission is a {scope, level} pair, where level is read or write (write includes read). A role is a named, fixed set of these pairs:
ScopeWhat write meansadmindeveloperanalyst
workspaceEdit workspace settings (name, notifications)writereadread
api_keysCreate and revoke API keyswritewritenone
emailsSend emailwritewriteread
email_managementManage suppressions and email configurationwritewriteread
email_marketingManage contacts, audiences, and broadcastswritewriteread
domainsAdd, verify, and remove sending domainswritewriteread
webhooksConfigure webhook endpointswritewriteread
smsSend SMSwritewriteread
verifySend and check verification codeswritewriteread
verify_managementConfigure verification senders and countrieswritewriteread
whatsapp_messagesSend WhatsApp messageswritereadread
whatsapp_managementManage WhatsApp templates and settingsreadreadread
ip_poolsView the organization's IP pools (read-only)readreadread
membersManage the workspace team and invitationswritereadread
analyticsView reports and deliverability analyticsreadnoneread
auditView the audit logreadnoneread
request_logsView the request log (read-only)readreadread
In practice: admin runs the workspace (team, settings, and everything a developer can do), developer builds the integration (send email with emails:write, manage domains with domains:write, configure webhooks with webhooks:write, mint API keys), and analyst is read-only everywhere. Two rows deserve a second look. ip_pools is read-only even for admins: purchasing dedicated IPs and managing pools is an organization-level operation (org:ip_pools:write), because pools are owned by the organization and shared across workspaces. And WhatsApp template management is currently an owner operation, so workspace roles hold read only. Other products add their own scopes as they ship; all follow the same {scope, level} model.
A 403 from any endpoint means the authenticated principal lacks the {scope, level} that endpoint requires. The fix is a role change (for a person) or a new key with the right scopes (for a service).

Organization roles

Behind your workspace sits an organization that owns billing and the overall member list. Two roles manage that layer:
  • owner: everything. Full read and write across all organization operations and every workspace, present and future, with no workspace role needed. An organization can (and should) have multiple owners. The person who created the account starts as owner.
  • billing_admin: billing and organization settings (org:billing:write, org:settings:write) plus read on members and workspaces (org:members:read, org:workspaces:read). No access to workspace operations.
These rarely come up day to day: most teammates only need a workspace role.

Members and the team

Membership is implicit: a user is "in" your organization if they hold any role, whether an organization role or a workspace role on any workspace. No separate membership record exists to manage.
You manage the people on your workspace in the dashboard under Settings → Team, gated by the workspace members scope; a workspace admin manages their own team here without any organization-level role. Behind it, the cross-workspace view of everyone in the organization (with their org role and all workspace roles) is served by GET /v1/organization/members, gated by org:members. Team management is something people do, so API keys cannot hold the members scope (see Authentication).
The workspace Team settings in the Bird dashboard, listing members with their role and the invite-members action
Removing someone from a workspace removes only that workspace role; they remain an organization member if they have roles elsewhere. Removing someone from the organization (DELETE /v1/organization/members/{member_id}) revokes everything at once: their organization role and all their workspace roles. API keys they created keep working either way, because keys belong to the workspace, not the person.

Invitations

Inviting is workspace-first: from Settings → Team you invite an email address with a role, and Bird figures out the rest. Behind the button, POST /v1/invitations is a smart invitation: the same request handles both colleagues who are already in your organization and people who have never heard of Bird.
  • Already an organization member: they are added to the workspace immediately with the given role. No email, no waiting; the response is a member object.
  • Not yet a member: Bird creates an invitation, emails them a signup link, and the response is an invitation object with a pending status. The link is valid for 7 days; after that the invitation expires and you invite them again.
The response's type field (team_member or invitation) tells you which happened. A second pending invitation for the same email returns 409 rather than creating a duplicate, and you can withdraw a pending invitation at any time from the same page.
Organization-level invitations (POST /v1/organization/invitations) are the multi-workspace variant: one invitation can carry an organization role (owner or billing_admin), workspace roles on several workspaces, or both. Creating them requires org:members:write, which only owners hold, so only an owner can make another owner.

Guardrails

Two invariants are enforced on every role change, regardless of who asks:
  • The last owner is immovable. Demoting or removing an organization's only owner returns 409: an organization can never end up ownerless. Promote a second owner first.
  • You cannot change your own access. Changing your own role or removing yourself returns 403. This prevents both accidental self-lockout and quiet self-promotion; another admin or owner has to make the change.

How context is selected

Member and team endpoints exist at two levels, and which organization or workspace a request targets depends on how it authenticates:
  • Session auth (the dashboard, or tools acting as you) selects context explicitly per request: X-Organization-Id on organization-scoped endpoints, X-Workspace-Id on workspace-scoped ones.
  • API keys carry their context implicitly. A key belongs to exactly one workspace, which also pins the organization; no headers are needed, and a context header that contradicts the key is rejected as malformed (400).
See Workspaces for the full context-resolution model.

Next steps