Sending domains
Before we can deliver email from your domain, you have to prove you own it and publish the DNS records that let mailbox providers authenticate your mail. A sending domain is the workspace-scoped resource (dom_...) that tracks that setup: which records to publish, what has verified, and whether the domain is ready to send.
Sharing a domain across organizations
The same domain can be registered by more than one organization without anyone stepping on anyone else. Each organization proves ownership with its own DKIM key, so:
- Another organization on the same domain can never see your verification state or change your configuration.
- Each region (us1, eu1) is independent: the same domain in two regions is two separate registrations with their own DNS records. Register it in each region you send from.
Register a domain
Create the domain with POST /v1/email/domains. The call is workspace-scoped and takes the sending domain plus optional labels for the return-path and tracking hostnames. Pass only the label (send, links), and we compose the full hostname under your sending domain. Omitted values default to send and links.
Use a dedicated subdomain (mail.acme.com) rather than your registered domain, so your sending reputation stays separate from everything else on the domain.
const domain = await bird.domains.create({ domain: "mail.acme.com" });
console.log(domain.id, domain.status); // "dom_…", "pending"domain = client.domains.create(domain="mail.acme.com")
print(domain.id, domain.status)domain, err := client.Domains.Create(context.Background(), bird.DomainCreateParams{
Domain: "mail.acme.com",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(domain.Id, *domain.Status)$domain = $bird->domains->create(
(new DomainCreate())->setDomain('mail.acme.com'),
);
echo $domain->getId(), ' ', $domain->getStatus(); // "dom_…", "pending"bird email domains create mail.acme.comcurl -s https://eu1.platform.bird.com/v1/email/domains \
-H "Authorization: Bearer $BIRD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"domain": "mail.acme.com",
"return_path": { "name": "send" },
"tracking": { "name": "links" }
}'The response includes status: pending, the DKIM selector assigned to your organization, and the dns_records to publish. An existing workspace registration returns 409. Exceeding your organization's domain quota returns 422. Replace eu1 with us1 for a US workspace. API keys use the same regional prefixes: bk_eu1_... and bk_us1_.... You can also manage domains in Email > Domains.

Publish the DNS records
The dns_records array gives you copy-pasteable name, host, and value for each record. Some providers reject a long DKIM TXT value as a single string; the DNS record splitter breaks it into the quoted strings those providers expect. What you publish:
| Record | Type | Required for sending | What it does |
|---|---|---|---|
| DKIM | TXT | Yes | Proves ownership and signs your mail with your org's key |
| Return-path CNAME | CNAME | Yes | Routes bounces back to us and covers SPF; the SPF lookup follows the CNAME, so no SPF record on your domain apex is needed |
| DMARC | TXT | Yes | Any valid v=DMARC1 policy covering the sending domain, on the domain itself or on its registered (organizational) domain. A minimal p=none policy is enough. |
| Tracking CNAME | CNAME | No | Enables branded open/click tracking hostnames; tracked links are served over HTTPS once it verifies |
For each record's purpose and values, see DKIM, SPF, and DMARC. If you enable receiving, its MX records join dns_records with purpose: inbound_mx. For DNS-provider setup steps, see the Cloudflare, Route 53, or generic registrar guides.
The dashboard detects supported DNS providers from your domain's nameservers and links to their DNS settings. Open Email > Domains, then select a domain to view its records. If someone else manages your DNS, POST /v1/email/domains/{domain_id}/dns-records/share emails them the records to publish.

Verification lifecycle
A new domain starts as pending. You never have to poll because we check your records automatically. Checks start immediately at registration and back off from every couple of minutes to hourly over the first three days. They then run daily for every active domain. Publishing your records and waiting is enough; most domains verify within minutes of DNS propagation. If you want an immediate check (for example right after editing DNS), call POST /v1/email/domains/{domain_id}/verify: it runs a fresh check and returns the updated domain. A 200 with records still pending is not a failure; it means the records were not found yet, which is normal while DNS propagates (minutes to hours). The call is safe to repeat while you wait.
A domain that remains unverified for about 14 days is removed. We email the workspace a reminder a few days before removal so you can finish the setup.
The domain's top-level status reflects ownership, proven by the DKIM record:
- pending: the DKIM record has not been published yet.
- verified: the DKIM record is in place; ownership is confirmed.
- failed: a DKIM record exists but does not match the expected value, or a previously verified record was removed. Correct the record to recover.
- temporary_failure: DNS resolution failed transiently; verification is retried automatically.
- rejected: the domain was refused for policy reasons; contact support.
Readiness to send is reported separately under capabilities. The send gate is capabilities.sending, which verifies only when DKIM, the return-path CNAME, and a DMARC policy are all in place; SPF at the domain apex is not required. Tracking readiness (capabilities.tracking) is independent of the send gate: it controls whether branded open/click tracking can be used, never whether the domain may send.
When a verified record breaks
Verification never stops: the daily re-check keeps verified domains honest, so if your DNS later breaks, we notice. To avoid flapping on transient DNS blips, a verified record that starts failing its re-checks is held verified in a warning state and re-checked hourly, and we notify the affected workspaces. Only after the record has kept failing for a full 24 hours is the domain downgraded; any passing check inside that window clears the warning. Downgrades take effect on the next send, and a downgraded domain re-verifies automatically once the records are fixed, on the next automatic check or a manual verify.
Managing domains
Regions. Domain state is regional. If you send from both us1 and eu1, register the domain in each region; each registration gets its own DKIM selector and verifies independently.
Changing return-path or tracking hostnames. These are per-workspace choices on your assignment. A hostname that has already verified is never replaced by an unverified one: changes are staged, verified alongside your active configuration, and promoted only once the new records check out.
Open/click tracking. The settings toggles are also per workspace. You can turn them on as soon as a tracking domain is configured. Enabling one without a tracking domain returns a 409. The toggles affect sends only after that tracking domain verifies, so verification is enforced per send. One workspace's tracking choices never affect another workspace sending from the same domain.
Deletion. DELETE /v1/email/domains/{domain_id} removes only your workspace's assignment. It does not affect another workspace or organization that uses the domain.
Next steps
- DKIM, SPF, and DMARC: what each record does and how to pick values.
- Per-provider DNS walkthroughs: setup steps for Cloudflare, Route 53, GoDaddy, and more.
- Domains API reference: full request/response schemas for every endpoint.