---
title: "Create a mailbox forwarding address"
canonical: "https://bird.com/docs/api/reference/create-mailbox-forwarding-address"
---

# Create a mailbox forwarding address

`POST /v1/email/mailboxes/{mailbox_id}/forwarding-address`

Gives a mailbox on your own domain an address on our receiving domain.
Forward mail for the mailbox's `address` to it from your current email
provider, and the mail lands in this mailbox. We choose the address; the
request takes no body. The response is the mailbox with
`forwarding_address` set.

If the mailbox already has a forwarding address, it is returned
unchanged, so retrying is safe. The address stays the same for the life
of the mailbox, including after a delete and restore. A suspended
mailbox can get one too; it stays suspended. Setting up the address does
not change DNS or your email provider, and does not show that forwarding
works. Add the forwarding rule at your provider, then send a new test
message to `address`.

Returns `422` for a mailbox on the shared inbox.ai domain, which already
receives mail directly. Also returns `422` when the mailbox's domain is
not verified in this workspace or another workspace receives mail for it.

## Servers

- `https://{region}.platform.bird.com`: Regional API endpoint. Use the host for the region your organization is hosted in. Official Bird SDKs and the CLI select it automatically from your API key, so you rarely need to set it by hand.
  - `region`: `us1`, `eu1`. Default: `us1`. The region your organization's data is hosted in.
- `https://platform.bird.com`: Region-independent endpoint for authentication and account administration.
- `http://localhost:8080`: Local development.

## Authentication

Use one authentication option:

- `BearerAuth`: HTTP bearer authentication. Pass the API key as a bearer token in the `Authorization` header. Workspace
keys use `bk_{region}_*`; organization master keys use `bm_{region}_*`.
The prefix identifies the region and selects the
API endpoint. Official Bird SDKs and the CLI derive the region from the key.

- `CookieAuth`: Send `bird_session` in cookie. Session cookie set after signing in to the Bird dashboard. The cookie
value is an opaque session token; no session data is stored in the cookie
itself.

## Code samples

**TypeScript**

```ts
const mailbox =
  await bird.email.mailboxes.forwardingAddress.create("mbx_01abc");
console.log(mailbox.forwarding_address);
```

Examples: [TypeScript](/docs/api/reference/create-mailbox-forwarding-address.ts.md) · [Python](/docs/api/reference/create-mailbox-forwarding-address.py.md) · [Go](/docs/api/reference/create-mailbox-forwarding-address.go.md) · [PHP](/docs/api/reference/create-mailbox-forwarding-address.php.md) · [CLI](/docs/api/reference/create-mailbox-forwarding-address.cli.md) · [MCP](/docs/api/reference/create-mailbox-forwarding-address.mcp.md) · [cURL](/docs/api/reference/create-mailbox-forwarding-address.curl.md)

## Example response `200`

```json
{
  "id": "mbx_01krdgeqcxet5s7t44vh8rt9mg",
  "address": "support@acme.com",
  "forwarding_address": "k7q2mzxw4h6p5ra3@eu1.inbound.bird.com",
  "display_name": "Acme Support",
  "default_reply_to": null,
  "receive_policy": "open",
  "state": "active",
  "channel": "email",
  "owner": {
    "type": "workspace",
    "id": "ws_01krdgeqcxet5s7t44vh8rt9mg"
  },
  "inbound_address_id": "ina_01krdgeqcxet5s7t44vh8rt9mg",
  "retention_tier": "30d",
  "message_count": 142,
  "thread_count": 37,
  "size_bytes": 12500,
  "metadata": {},
  "local_part_generated": false,
  "created_at": "2026-07-08T12:00:00Z",
  "updated_at": "2026-10-28T10:00:00Z",
  "deleted_at": null,
  "next": [
    {
      "kind": "external",
      "description": "Configure forwarding at your email provider, then send a fresh test message to support@acme.com and inspect its delivered_to address."
    }
  ]
}
```

## Path parameters

- `mailbox_id` (string, required): Mailbox ID or email address in this workspace.

## Header parameters

- `Idempotency-Key` (string, optional)

  Client-supplied key. On operations supporting request deduplication, a retained
  response is replayed for duplicate requests with the same key within the
  idempotency window (3 hours by default). This protection requires a workspace,
  organization, or staff-account scope. User-only and unscoped unauthenticated operations,
  streams, and operations with a separate replay contract do not use this
  response replay.

  On a supported operation, if idempotency protection is unavailable before execution, the API returns
  `503 IdempotencyUnavailable` (E01033) without executing this attempt. Retry with
  backoff using the same key and request. An operation that takes effect before
  its response is retained can still execute again on retry.

  Two distinct 409 errors signal misuse:

  - `request_in_progress` (E01004): The same key is currently being
    processed by a concurrent request. Wait briefly and retry. The lock expires within 30 seconds.
  - `idempotency_key_reuse` (E01005): The same key has already completed
    against a different request body or method. Generate a new key.

  Recommended key format is `<event-type>/<entity-id>` (for example `welcome-user/usr_abc123`).
- `X-Workspace-Id` (string, optional): Workspace context for the request. Required for dashboard authentication and master keys. Workspace keys and access tokens already identify their workspace; send that workspace or omit the header. A different one is rejected.
- `X-Organization-Id` (string, optional): Organization context for the request. Required for dashboard authentication. An API key or access token carries its own organization, so send either that organization or no header at all; a different one is rejected.

## Response body

- `id` (string, required): Mailbox ID.
- `address` (string, required): The mailbox's email address. Immutable once created.
- `forwarding_address` (nullable string, required): An address we generate on our receiving domain, either when the mailbox is created on a domain not set up for receiving with us or later, when you set up forwarding for the mailbox. Forward mail for `address` here from your current email provider, and it lands in this mailbox. Replies still go out from `address`. Immutable once set. It stops receiving while the mailbox is deleted, works again with the same value after a restore, and keeps working if you later enable or disable receiving on the domain. `null` until set up; always `null` on the shared domain, which receives directly.
- `display_name` (nullable string, required): Display name used as the sender name on mail from this mailbox. `null` when unset.
- `default_reply_to` (nullable string, required): Default `Reply-To` address stamped on mail sent from this mailbox. `null` when unset.
- `receive_policy` (string, required)

  Which inbound mail the mailbox accepts:

  - `open`: Accepts everything not blocked by a rule.
  - `replies_only`: Accepts only replies to messages this mailbox has
    sent. A reply must match a message the mailbox sent. Landing in an
    existing thread by itself does not count.
  - `allowlist`: Accepts only senders matching an allow rule. Replies to
    prior outbound mail are always admitted unless blocked.
  - `drop`: Stores nothing.

  Possible values: `open`, `replies_only`, `allowlist`, `drop`
- `state` (string, required)

  Lifecycle state. `active` means the mailbox can send, receive, and expose conversations. `suspended` pauses sending, conversation reads, and events; inbound mail is retained with the `blocked` label until you resume it.

  Possible values: `active`, `suspended`
- `channel` (string, required)

  The channel this mailbox receives on. Always `email`.

  Possible values: `email`
- `owner` (object, required): The principal that owns the mailbox. Always the workspace.
- `owner.type` (string, required)

  Owner principal type.

  Possible values: `workspace`
- `owner.id` (string, required): Owner principal ID.
- `inbound_address_id` (string, required): The underlying inbound address that receives this mailbox's mail.
- `retention_tier` (string, required)

  How long message metadata, extracted text, and attachments are kept. Original bodies and inbound raw MIME are limited to 30 days on every tier.

  Possible values: `30d`, `90d`, `1y`
- `message_count` (integer, required): Number of retained messages across all threads.
- `thread_count` (integer, required): Number of retained threads.
- `size_bytes` (integer, required): Stored bytes across the mailbox's retained messages: subject, preview, extracted text, and attachment bytes. Message bodies and raw MIME expire after 30 days and do not count. Maintained with each message written or deleted, so the value is current; messages stored before the counter existed are not counted.
- `unread_thread_count` (nullable integer): Number of threads with unread messages in this mailbox, excluding trash. `null` on create/update responses.
- `metadata` (object, required): Your own key/value data attached to the mailbox. Up to 2 KB. Keys starting with `__bird` are reserved.
- `local_part_generated` (boolean, required): Whether we generated the local part of the address. `false` means a custom handle was chosen at creation. On the shared `inbox.ai` domain a custom handle counts against your plan's custom-handle allowance.
- `created_at` (string, required): When the mailbox was created.
- `updated_at` (string, required): When the mailbox was last updated.
- `deleted_at` (nullable string): When the mailbox was deleted, or `null` if active. Deletion stops receiving; restore is available for 30 days unless permanent erasure has started.
- `next` (array of object): What to do next with this mailbox. The response that creates it suggests subscribing to the mail it receives. Forwarding-address setup suggests configuring the email provider. Other reads of one mailbox return an empty list, and lists omit it.
- `next.kind` (string, required)

  What you do about this step.

  - `operation`: call the operation named in `operation`, then
    read again.
  - `external`: act somewhere this API does not reach, then read
    again.
  - `wait`: nothing is asked of you, so read again later.
  - `terminal`: nothing you do resolves this, so stop retrying.

  Tolerate a value you do not recognize: show the `description` and
  offer no action.

  Possible values (may grow over time): `operation`, `external`, `wait`, `terminal`
- `next.description` (string, required): A short, human-readable label for the step, suitable for display.
- `next.operation` (string): The operationId to call. Present only when `kind` is `operation`. The operation's own schema says how to call it; this says only which one, and what to address it with.
- `next.params` (object): The parameters that address the operation, by name: `{"sender_id": "…"}` for an operation on `/v1/sms/senders/{sender_id}/requirements`. A parameter the operation takes in its query string is given the same way, so an operation addressed as `?subject_id=` carries `{"subject_id": "…"}`. Every parameter the call needs is here, whether its value came from the thing you were acting on or is fixed for this step, so you can make the call from this object alone. Present only when `kind` is `operation` and the operation names a subject. A request body, when the operation takes one, is described by the operation's own schema and never appears here.
- `next.url` (string): A URL to open. Present only when `kind` is `external`, and only when the step has one. An external step whose `description` says to go and do something with no URL to open is normal.

## Related resources

- [Should I use a Bird SDK or call the API directly?](/explained/platform/should-i-use-an-sdk-or-call-the-api-directly) (answer)
- [Build your first integration](/learn/paths/integration) (course)
- [Send your first email](/docs/get-started/send-your-first-email) (docs)

[Get an implementation brief](/learn/workspace?topic=api-basics)
