Authentication & API keys
Every programmatic request to the Bird API authenticates with an API key passed as a bearer token. Keys belong to a workspace, carry permissions chosen at creation, and are shown in full exactly once.
How requests authenticate
Pass your key in the Authorization header on every request. The SDKs and the CLI take the key once and set the header for you:
import { BirdClient } from "@messagebird/sdk";
const bird = new BirdClient({ apiKey: process.env.BIRD_API_KEY! });
await bird.email.send({
from: "hello@yourdomain.com",
to: ["delivered@messagebird.dev"],
subject: "Hi",
text: "Hello.",
});import os
from bird import Bird
client = Bird(api_key=os.environ["BIRD_API_KEY"])
client.email.send(
from_="hello@yourdomain.com",
to=["delivered@messagebird.dev"],
subject="Hi",
text="Hello.",
)client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
if err != nil {
log.Fatal(err)
}
_, err = client.Email.Send(context.Background(), bird.EmailSendParams{
From: "hello@yourdomain.com",
To: []string{"delivered@messagebird.dev"},
Subject: "Hi",
Text: "Hello.",
})use MessageBird\Bird;
$bird = new Bird(getenv('BIRD_API_KEY') ?: '');
$bird->email->send(
from: 'hello@yourdomain.com',
to: ['delivered@messagebird.dev'],
subject: 'Hi',
text: 'Hello.',
);export BIRD_API_KEY="bk_us1_..."
bird email send \
--from hello@yourdomain.com \
--to delivered@messagebird.dev \
--subject Hi \
--text Hello.curl -X POST https://us1.platform.bird.com/v1/email/messages \
-H "Authorization: Bearer $BIRD_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "from": "hello@yourdomain.com", "to": ["delivered@messagebird.dev"], "subject": "Hi", "text": "Hello." }'The region in the key prefix tells you which host to call: bk_us1_... keys go to https://us1.platform.bird.com, bk_eu1_... keys to https://eu1.platform.bird.com. Official Bird SDKs and the CLI read the region from the key and select the host for you. A key sent to the wrong regional host returns 421 (type misdirected_error); see Regions.
A missing or invalid key returns 401. A valid key that lacks the permission an endpoint requires returns 403. Header semantics and error responses live in the authentication reference.
Anatomy of a key
Exemplo de código
bk_us1_Ab3xKq9mP2wR5tY8uI1oL4nJ2kQ9m
└┬┘└┬┘ └──────────┬──────────┘└─┬──┘
│ │ payload checksum
│ └ region (routes the request)
└ Bird key prefix- Prefix: bk_{region}_ names the credential type and its region. The fixed, distinctive prefix is what lets secret scanners recognize a Bird key in code, and the region segment routes your request to the right host.
- Payload: 23 random characters carrying 136 bits of entropy.
- Checksum: the last 6 characters are a checksum of the rest of the key, so an SDK or the API can reject a mistyped or truncated key immediately, before it is ever looked up.
The full key is returned once, in the response that creates it. You cannot retrieve the plaintext later. Subsequent responses include the first 15 characters as key_prefix, for example bk_us1_Ab3xKq9m. They also include a stable 12-character fingerprint for matching a key in logs and support conversations without exposing its value.
If you lose a key, you don't recover it: you revoke it and create a new one.
Creating a key
Create keys in the dashboard under Developers > API keys. A key is created with a name, one or more scopes, and an optional expiry. The response that creates it is the only one that ever carries the token field (the full key): store it in your secret manager immediately.

Three properties are fixed the moment the key exists:
- The scope set is immutable. Scopes cannot be added or removed on an existing key. To change what a key can do, create a new key with the right scopes and revoke the old one; every key's permissions stay exactly what they were when it was issued and audited.
- Expiry is immutable too. Set expires_at when a key should stop working at a known time (a contractor's engagement, a migration window). Past that moment the key returns 401; a key without an expiry lives until revoked.
- Key management stays with people. Creating and revoking keys requires the api_keys:write permission, held by the workspace admin and developer roles (see Users, teams & roles) and never grantable to an API key itself. A leaked key cannot mint more keys.
The API keys page lists every key with its key_prefix, scopes, and last_used_on date (day precision), so you can spot stale keys at a glance. Revoked keys stay out of the listing unless you choose to show them.
Scopes & levels
Each scope on a key is a {scope, level} pair, where level is read or write (write includes read). API keys hold data-plane scopes:
| Scope | read | write |
|---|---|---|
| emails | Read sent messages and delivery status | Send email |
| email_management | Read suppressions, email configuration, and templates | Manage suppressions, email configuration, and templates |
| email_marketing | Read contacts, audiences, and broadcasts | Manage contacts, audiences, and broadcasts |
| domains | Read sending domains and their DNS records | Add, verify, and manage sending domains |
| sms | Read sent SMS and delivery status | Send SMS |
| sms_management | Read senders, registrations, suppressions, keyword replies, destinations, and templates | Manage senders, registrations, suppressions, keyword replies, destinations, and templates |
| Read sent WhatsApp messages and status | Send WhatsApp messages | |
| whatsapp_management | Read WhatsApp templates and settings | Manage WhatsApp templates and settings |
| verify | Read verification status | Send and check verification codes |
| realtime | Read Realtime apps, channels, and channel members | Create apps and publish events |
| voice | Read call logs, numbers, and usage stats | Manage numbers, trunks, caller IDs, and session credentials |
| mailbox | Read mailboxes, threads, and messages | Send and reply to mailbox messages |
| mailbox_management | Read receive rules and mailbox configuration | Create, update, and delete mailboxes and receive rules |
| assets | Read assets and folders | Upload, update, and delete assets and folders |
| lookup | Not available | Look up phone numbers, email addresses, and identity matches |
Control-plane operations (workspace members, settings, key issuance, IP pools) are deliberately not grantable to API keys; they remain dashboard-only. Grant the narrowest set that works: a key that only sends email should hold emails:write and nothing else.
lookup has no read-level operations: every lookup endpoint, including fetching an existing result, requires write.
Revoking a key
Revoke a key from its row under Developers > API keys. Revocation is permanent: a revoked key cannot be reactivated, and its record is preserved for audit with revoked_at set.
Revocation propagates fast but not instantly. Key validation runs through a short-lived cache, so a freshly revoked key can keep working for a few seconds (five at most) before every request with it returns 401.
Bird has no rotate operation. To rotate a key with zero downtime, overlap two keys:
- Create a new key with the same scopes.
- Deploy the new key to your services.
- Watch the old key's last_used_on until traffic has moved.
- Revoke the old key.
Keys belong to the workspace
An API key is bound to exactly one workspace and authenticates with that workspace's authority. The creator's personal permissions do not affect it. That has two practical consequences:
- Keys survive departures. When an employee leaves and their user account is removed, the keys they created keep working. You never have a production outage because the person who clicked "create" left the company. (Their departure is still a good prompt to rotate keys they had access to.)
- The key's reach stops at the workspace. It can never perform organization-level operations: billing, org members, org settings.
Because the key pins the workspace, requests with a key need no extra context; see Workspaces for how the workspace and the organization above it divide up what you can reach.
The delegated path: OAuth tokens for the CLI and MCP server
API keys are for services. The Bird CLI and Bird MCP server use OAuth when a person signs in. You log in through the browser, choose a workspace, and grant a subset of your permissions. The tool then receives a short-lived bt_{region}_... user token.
Each token is limited to permissions you hold. You can revoke access for each tool under Profile > Connected apps. The tools manage these tokens for you, so do not copy them or store them in a secret manager. Use API keys for server workloads.
Next steps
- Authentication reference: request header semantics and error responses
- Regions: regional hosts and routing
- Users, teams & roles: who can manage keys
- Workspaces: the workspace a key binds to