# Send email over SMTP

If your application, framework, or off-the-shelf software already speaks SMTP, you can send through Bird by changing three connection settings and nothing else. Rails ActionMailer, Laravel, Django, WordPress, a scan-to-email printer, an ERP: anything that can submit mail to a relay works. For teams migrating from another provider it is a credentials swap, not an integration.

Mail submitted over SMTP goes through the same pipeline as the [email API](/docs/guides/email/sending-email): the same domain verification, IP pools, DKIM signing, suppression handling, tracking, events, and analytics. SMTP is a second door into one system, not a parallel one.

## What you need first

- **A verified sending domain.** The address you put in `MAIL FROM` (and the message `From` header) must belong to a domain you have verified in this workspace. See [Sending domains](/docs/guides/email/sending-domains).
- **An API key with the `emails` scope.** SMTP uses your normal Bird API keys, with no separate SMTP username or password to manage. Create a key with email sending enabled from the [**API keys**](https://bird.com/dashboard/w/api-keys) page. A key without the `emails` scope cannot send, and neither can a `verify`-only key.

## Connection settings

Point your client at the SMTP host for your key's region. The region is the prefix in the key itself: a `bk_eu1_...` key sends through the `eu1` host, a `bk_us1_...` key through `us1`. Authenticating with a key from the other region fails with a `535` reply naming the host to use instead.

| Region | Host                |
| ------ | ------------------- |
| EU     | `eu1.smtp.bird.com` |
| US     | `us1.smtp.bird.com` |

| Port | Encryption           |
| ---- | -------------------- |
| 465  | Implicit TLS (SMTPS) |
| 587  | STARTTLS             |
| 2525 | STARTTLS             |

Use whichever your client supports:

- **Port 465, implicit TLS (SMTPS).** The connection is encrypted from the first byte, before any command is sent. In most libraries this is the "SSL/TLS" or "SMTPS" option.
- **Ports 587 and 2525, STARTTLS.** The connection opens in plaintext and upgrades to TLS with the `STARTTLS` command before authentication. This is the "STARTTLS" option, sometimes labeled plainly "TLS". Pick 2525 if your network blocks 587.

Either way the session is encrypted before your credentials are sent, so they never travel in the clear: on 587 and 2525 Bird refuses `AUTH` until `STARTTLS` has run. Port 25 is not offered for submission.

## Authenticating

Authenticate with `AUTH PLAIN` or `AUTH LOGIN`. The username is the literal string `bird`, and the password is your API key:

```text
Username: bird
Password: bk_eu1_your_api_key
```

The username is a fixed literal; it carries no identity, and the API key in the password field is what authenticates. In most SMTP tools you paste your API key into the password field and set the username to `bird`. Revoking the key cuts off its SMTP sending within seconds, mid-connection included.

## What the message carries, and what the key's config carries

Everything with a natural place in a MIME message comes from the message itself: the `From`, `To`, `Cc`, and `Reply-To` headers, the subject, the HTML and text bodies, and attachments and inline images. Recipients are taken from the SMTP envelope (`RCPT TO`). An address in `RCPT TO` that isn't in a visible `To` or `Cc` header is treated as a `Bcc`. A message can have at most 50 recipients across to, cc, and bcc, and the total message size is capped at 20 MB.

The send options that have no place in a MIME message (which IP pool to send from, the content category, tags, and open/click tracking) come from a per-key **SMTP configuration**. A key with no configuration sends with sensible defaults: your organization's default pool, the `transactional` category, and tracking on. To customize them, open the [**SMTP**](https://bird.com/dashboard/w/email/smtp-configs) page and configure the key, or call the [SMTP config API](/docs/api/reference/update-email-smtp-config). Because the defaults live on the key, you can give each application its own key: a `wordpress-prod` key on the marketing pool with a `source=wordpress` tag, an `erp` key on a dedicated pool, each with no per-message configuration. Editing a key's configuration takes effect on new messages within seconds; you do not need to reconnect or restart your client.

## A full session

On port 465 the client opens the TLS connection first, then runs the whole SMTP dialogue inside it:

```text
   ... TLS handshake ...
S: 220 eu1.smtp.bird.com ESMTP Service Ready
C: EHLO myapp
S: 250-Hello myapp
   250-PIPELINING
   250-8BITMIME
   250-ENHANCEDSTATUSCODES
   250-CHUNKING
   250-AUTH PLAIN LOGIN
   250-SIZE 20971520
   250 LIMITS RCPTMAX=50
C: AUTH PLAIN <base64 of bird + key>
S: 235 2.0.0 Authentication succeeded
C: MAIL FROM:<news@acme.com>
C: RCPT TO:<alice@example.com>
C: DATA
   ... your MIME message ...
C: .
S: 250 2.0.0 Ok: queued as em_01ky7ma8y2es1s2akzk53tmjn0
```

On port 587 or 2525 the client connects in plaintext, issues `STARTTLS` to upgrade the connection, then runs the same dialogue inside TLS. `AUTH` is not offered until the upgrade completes:

```text
S: 220 eu1.smtp.bird.com ESMTP Service Ready
C: EHLO myapp
S: 250-Hello myapp
   250-PIPELINING
   250-8BITMIME
   250-ENHANCEDSTATUSCODES
   250-CHUNKING
   250-STARTTLS
   250-SIZE 20971520
   250 LIMITS RCPTMAX=50
C: STARTTLS
S: 220 2.0.0 Ready to start TLS
   ... TLS handshake ...
C: EHLO myapp
S: 250-Hello myapp
   250-PIPELINING
   250-8BITMIME
   250-ENHANCEDSTATUSCODES
   250-CHUNKING
   250-AUTH PLAIN LOGIN
   250-SIZE 20971520
   250 LIMITS RCPTMAX=50
C: AUTH PLAIN <base64 of bird + key>
S: 235 2.0.0 Authentication succeeded
C: MAIL FROM:<news@acme.com>
C: RCPT TO:<alice@example.com>
C: DATA
   ... your MIME message ...
C: .
S: 250 2.0.0 Ok: queued as em_01ky7ma8y2es1s2akzk53tmjn0
```

The final `250` returns the queued message's ID, the same `em_...` ID you would get from the API. You can look the message up by that ID in the [Email log](/docs/guides/email/email-log) or through `GET /v1/email/messages/{message_id}`.

## Retrying safely

The pipeline accepts a message and delivers it asynchronously, and SMTP clients retry aggressively when a connection drops. To make a retry safe, add an `X-Bird-Idempotency-Key` header to the message: a repeat within the [retention window](/docs/guides/idempotency) returns the ID of the message that was already queued instead of sending a second copy. Use a value that is stable for the logical message, like an order ID or a notification ID, not a random one per attempt.

## Connection limits

Each organization can hold up to 10 concurrent authenticated SMTP connections by default; the limit can be raised for your organization on request. A connection counts from the moment it authenticates until it closes, across every server and API key in the organization. When you are already at the limit, a further connection is refused with a transient `421` reply once it authenticates: reduce the number of simultaneous connections your senders open, or reuse a connection for several messages, and retry. This is a concurrency limit on open connections, not a cap on how many messages you can send: one connection can submit many messages in sequence. The dashboard [SMTP page](https://bird.com/dashboard/w/email/smtp-configs) shows the organization's live connections against the limit.

## What comes back

SMTP rejects synchronously everything the API rejects. An unverified sending domain, a recipient on a reserved domain, an unusable IP pool, a blocked attachment type, or a malformed message each come back as a permanent `550` reply at the point the problem is detected, so a misconfigured send fails fast rather than disappearing. An exceeded send quota returns a transient `452`, telling well-behaved clients to retry later. Suppressed recipients are the one exception: as with every provider, the message is accepted and the suppressed recipient is dropped downstream, visible in the [Email log](/docs/guides/email/email-log) and [events](/docs/guides/email/events) rather than as an SMTP error.

## Next steps

- [Sending domains](/docs/guides/email/sending-domains): verify the domain you'll send from.
- [Dedicated IPs & pools](/docs/guides/email/dedicated-ips-and-pools): choose which pool a key sends from.
- [Suppressions](/docs/guides/email/suppressions): why an accepted recipient might not receive a message.
- [Email log](/docs/guides/email/email-log): find a message by the ID SMTP returned.