---
title: "Create a message from a mailbox"
method: POST
path: "/v1/email/mailboxes/{mailbox_id}/messages"
tags: ["email-threads"]
---

# Create a message from a mailbox

`POST /v1/email/mailboxes/{mailbox_id}/messages`

## Request

- Base URL: `https://us1.platform.bird.com`
- URL: `https://us1.platform.bird.com/v1/email/mailboxes/{mailbox_id}/messages`
- Auth: one of:
  - HTTP bearer
  - API key in cookie `bird_session`

Sends a new message from the mailbox's own address and starts a new conversation with it. The request mirrors the plain send request minus `from`, because the mailbox is who the message comes from. We set the RFC 5322 Message-ID, so later replies from the recipients thread back into the conversation automatically. The send is added to the mailbox's remembered messages and returned as the conversation's first message. A mailbox always sends immediately; scheduled sends are unavailable. A suspended mailbox cannot send and returns `403`.

## Headers

- `Idempotency-Key` string
- `X-Workspace-Id` string
- `X-Organization-Id` string

## Request body

- EmailMailboxComposeRequest: A new message sent from a mailbox, starting a new conversation. Mirrors the plain send request without `from`, because the mailbox is who the message comes from, and without `scheduled_at`, because a mailbox sends immediately. We set the RFC 5322 Message-ID so replies thread back into this conversation. At least one of `html` or `text` must be provided.
  - `to` EmailAddressInput[], required: Primary recipients. Each entry is a plain email string, an RFC 5322 mailbox string (`Jane <jane@acme.com>`), or an object with an optional display name.
    - union: A sender or recipient address. Accepts a plain email string (`jane@acme.com`), an RFC 5322 mailbox string with an embedded display name (`Jane Doe <jane@acme.com>`), or an object carrying the address and an optional display name. All forms can be mixed freely within one request. Responses always return the object form.
      - string: Email address, optionally in RFC 5322 mailbox form with an embedded display name.
      - EmailAddress: An email address with an optional display name.
        - `email` string, email, required: Email address.
        - `name` string: Display name shown alongside the address in mail clients.
  - `cc` EmailAddressInput[]: CC recipients. Each entry is a plain email string, an RFC 5322 mailbox string (`Jane <jane@acme.com>`), or an object with an optional display name.
    - union: A sender or recipient address. Accepts a plain email string (`jane@acme.com`), an RFC 5322 mailbox string with an embedded display name (`Jane Doe <jane@acme.com>`), or an object carrying the address and an optional display name. All forms can be mixed freely within one request. Responses always return the object form.
      - string: Email address, optionally in RFC 5322 mailbox form with an embedded display name.
      - EmailAddress: An email address with an optional display name.
        - `email` string, email, required: Email address.
        - `name` string: Display name shown alongside the address in mail clients.
  - `bcc` EmailAddressInput[]: BCC recipients. Each entry is a plain email string, an RFC 5322 mailbox string (`Jane <jane@acme.com>`), or an object with an optional display name.
    - union: A sender or recipient address. Accepts a plain email string (`jane@acme.com`), an RFC 5322 mailbox string with an embedded display name (`Jane Doe <jane@acme.com>`), or an object carrying the address and an optional display name. All forms can be mixed freely within one request. Responses always return the object form.
      - string: Email address, optionally in RFC 5322 mailbox form with an embedded display name.
      - EmailAddress: An email address with an optional display name.
        - `email` string, email, required: Email address.
        - `name` string: Display name shown alongside the address in mail clients.
  - `subject` string, required: Message subject line.
  - `html` string: HTML body. At least one of html or text must be provided.
  - `text` string: Plain-text body. At least one of html or text must be provided.
  - `reply_to` EmailAddressInput[]: Reply-To addresses. When omitted, the mailbox's `default_reply_to` applies (replies then come back to the mailbox itself).
    - union: A sender or recipient address. Accepts a plain email string (`jane@acme.com`), an RFC 5322 mailbox string with an embedded display name (`Jane Doe <jane@acme.com>`), or an object carrying the address and an optional display name. All forms can be mixed freely within one request. Responses always return the object form.
      - string: Email address, optionally in RFC 5322 mailbox form with an embedded display name.
      - EmailAddress: An email address with an optional display name.
        - `email` string, email, required: Email address.
        - `name` string: Display name shown alongside the address in mail clients.
  - `attachments` EmailAttachment[]: File attachments. The send is rejected when the estimated generated message size exceeds 20 MB (bodies plus all attachments after base64 encoding). Keep total raw attachment content at or below 15 MB for reliable headroom. Attachment metadata stays on the message's `attachment_manifest`, and the bytes are downloadable for the mailbox's retention tier.
    - `filename` string, required: The name the recipient sees on the attachment.
    - `content` string, byte, required: Base64-encoded file bytes. The encoded value and MIME wrapping count toward the 20 MB message limit.
    - `content_type` string: The file's MIME type. If omitted, the API infers it from the extension in `filename`. The API rejects executable and script types based on this value.
    - `content_id` string: An RFC 2392 Content-ID for an inline file. Reference it from the HTML body with `<img src="cid:{content_id}"/>`. Omit it to send a downloadable attachment.
  - `tags` Tag[]: Structured `{name, value}` labels for filtering and analytics on the sent-message log. Cap: 20 tags per send.
    - `name` string, required: Tag name. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 32 characters.
    - `value` string, required: Tag value. ASCII letters, digits, underscore, and hyphen only. Case-sensitive. Maximum 64 characters.
  - `metadata` object: Arbitrary JSON object stored on the send and echoed in webhook payloads. Cap: 2 KB serialized.
  - `category` 'marketing' | 'transactional': Content classification, which controls suppression policy: - `marketing`: Blocks on all suppression reasons. - `transactional`: Allows delivery through complaint and unsubscribe suppressions, for receipts, password resets, and similar operational mail.

## Response `202`

Message accepted for asynchronous delivery and recorded as the first message of a new conversation.

- EmailThreadMessage: A message in a mailbox conversation, either direction. Message metadata, extracted text, and attachment bytes stay readable for the mailbox's retention tier. The body and raw MIME are available through the body and raw endpoints for 30 days after the message occurred.
  - `id` string, required: Message ID. Received messages have a `rem_` ID, sent messages an `em_` ID: the same IDs used by the received-message and sent-message logs.
  - `direction` 'inbound' | 'outbound', required: Which way the message went. `inbound` means you received it, `outbound` means you sent it.
  - `channel` string, required: Channel this message lives on. Always `email`.
  - `thread_id` string, required
  - `from` string, email, required: Sender address.
  - `to` string[], required: Recipient addresses on the To line.
  - `cc` string[], required: Recipient addresses on the Cc line. Empty when the message had none.
  - `delivered_to` string, email, nullable, required: Address the message was actually delivered to, when it differs from the mailbox address (for example mail routed in from another address). Null for sent messages and for mail addressed directly to the mailbox.
  - `subject` string, nullable, required: Message subject. Null when the message had no subject.
  - `preview` string, nullable, required: Short plain-text preview of the message body.
  - `extracted_text` string, nullable: Plain-text content of the message with quoted history stripped. Readable for the mailbox's full retention tier, in both directions. Always present when fetching a single message. On list endpoints it is included only when the request sets `include=extracted_text`. Null when no text could be extracted.
  - `labels` string[], required: Labels on this message. A received message always has exactly one placement label: - `inbox`: Accepted mail. - `archive`: The message's conversation was filed away. - `spam`: The message is filed in Spam. - `blocked`: The message was rejected by the mailbox's receive policy or rules. A received message also has `unread` until it is read. `trash` marks a message in the trash, in either direction. Custom labels share the same list, and a message has at most 20 labels in total.
  - `status` string, nullable, required: Aggregate delivery status of a sent message: - `accepted`: Accepted for sending. - `sent`: Handed off to the provider. - `delivered`: All attempted recipients delivered. - `failed`: Terminal failure. Null for received messages.
  - `recipients` EmailThreadMessageRecipient[], nullable, required: Terminal per-recipient delivery outcomes of a sent message, filled in as each one becomes known and kept for the mailbox's full retention tier. Null for received messages and before any recipient reaches a terminal state. Per-recipient event detail lives on the sent-message log (`source`) for 30 days.
    - `address` string, email, required: Recipient address.
    - `status` 'delivered' | 'failed', required: Terminal outcome: `delivered`, or `failed` (bounce or provider rejection).
  - `authentication` 'pass' | 'fail' | 'unknown' | 'null', nullable, required: DMARC result for the domain in the received message's `From` header. - `pass`: SPF or DKIM passed and aligned with that domain. - `fail`: DMARC was evaluated and did not pass. - `unknown`: no trustworthy verdict is available. This follows `dmarc_pass` and does not verify a particular person. The receiving provider currently supplies no DMARC result, so received messages report `unknown`. Null for sent messages. This field is readable for the mailbox's full retention tier, so the verdict is still available after the 30-day received-message log has expired.
  - `spf_pass` boolean, nullable, required: Whether the receiving provider reports that SPF authorized the envelope sender for the sending server. A soft failure is `false`. Missing, neutral and inconclusive results are `null`. Sent messages have `null` results. Kept for the mailbox retention tier.
  - `dkim_pass` boolean, nullable, required: Whether the receiving provider verified a DKIM signature. A passing signature makes this `true` even when another signature fails. Missing signatures and inconclusive verification results are `null`. Sent messages have `null` results. Kept for the mailbox retention tier.
  - `dmarc_pass` boolean, nullable, required: Whether SPF or DKIM passed and aligned with the domain in the message's `From` header. The receiving provider currently supplies no DMARC result, so this is `null`. Sent messages have `null` results. Kept for the mailbox retention tier.
  - `purge_at` string, date-time, required: Scheduled permanent-deletion time. This is the end of the mailbox's retention tier, moved to no more than 30 days in the future while the message is in the trash. Restore a trashed message before then with `PATCH {"labels": {"remove": ["trash"]}}`.
  - `attachment_count` integer, required: Number of attachments on the message.
  - `attachment_manifest` EmailThreadMessageAttachment[], required: Attachment metadata (filename, content type, size). Both the metadata and the attachment bytes stay available for the mailbox's retention tier.
    - `id` string, required: Attachment ID, used to download the attachment bytes.
    - `filename` string, nullable, required: Original filename, or null when the attachment had none.
    - `content_type` string, nullable, required: MIME content type, or null when it could not be determined.
    - `size` integer, required: Attachment size in bytes.
  - `reference_ids` string[], required: RFC 5322 References header entries used to thread the conversation.
  - `contact_id` string, required
  - `source` EmailThreadMessageSource, required: Link to the message's entry in the received-message or sent-message log, which has delivery analytics such as per-recipient events. Log entries expire 30 days after the message occurred.
    - `resource` string, required: API path of the log entry for this message.
    - `available_until` string, date-time, required: When the log entry (and the message's body and raw MIME) expires.
  - `occurred_at` string, date-time, required: When the message was received or accepted for sending.

## Other responses

- `400`: Bad request
- `401`: Authentication required
- `402`: Insufficient balance
- `403`: Insufficient permissions
- `404`: Resource not found
- `409`: Resource conflict
- `422`: The request has invalid field values, violates a business rule, or carries a query parameter the endpoint does not declare. Field validation errors use `type: validation_error` and include the affected fields in `details`. Business-rule errors identify the failed rule in `type`.
- `429`: Rate limit exceeded
- `500`: Internal server error
- `503`: The service is temporarily unavailable. If `Retry-After` is present, wait for that delay before retrying; otherwise, retry with exponential backoff. Reuse the same idempotency key and request when retrying a mutation.

---

[API](https://skmtc.dev/messagebird/apis/bird-api.md) · [All operations](https://skmtc.dev/messagebird/apis/bird-api/llms.txt) · [OpenAPI document](https://skmtc.dev/messagebird/apis/bird-api/revisions/6dfce1179799?raw)
