---
title: "Send a message from a mailbox"
method: POST
path: "/api/mailboxes/{id}/messages"
tags: ["Mailboxes"]
---

# Send a message from a mailbox

`POST /api/mailboxes/{id}/messages`

## Request

- Base URL: `https://api.sendly.now`
- URL: `https://api.sendly.now/api/mailboxes/{id}/messages`
- Auth: one of:
  - HTTP bearer
  - API key in cookie `better-auth.session_token`
  - OAuth 2 (authorization code, authorization URL `https://app.sendly.now/api/auth/oauth2/authorize`, token URL `https://app.sendly.now/api/auth/oauth2/token`, scopes: `mailboxes:send`)

Compose and send a NEW message from a hosted mailbox — a first email to someone, not a reply inside a thread that already exists. It goes out from the mailbox's own address, over its own domain, and the recipient can reply to it.

**The sender is the mailbox in the path.** There is no `from` field: a route that sends under a customer's own identity must not take the identity as an argument.

Supply either `body` (plain text) or `document` (a branded React Email document with images, GIFs, buttons and columns). Sendly renders both HTML and a matching text alternative. Caller HTML, JSX and arbitrary CSS are not accepted.

Bcc recipients are delivered to but appear in no header, which also means the copy filed in the mailbox's Sent folder does not record them.

Refusals worth handling by name:

- `422 RECIPIENT_SUPPRESSED` — one or more recipients are on this project's suppression list. The message names them; remove them or take them off the list.
- `422 CONTENT_REFUSED` — the outbound content scanner refused the message.
- `503 CONTENT_SCAN_UNAVAILABLE` — screening could not reach a verdict for a young project. Nothing was sent; retry shortly.
- `429` — a mailbox may send 60 messages an hour through this endpoint.

The message is stored as a new conversation on the mailbox, so the reply threads onto it.

Requires the `mailboxes:send` scope — Write and send new email from your hosted mailboxes, as that address.

## Path parameters

- `id` string, uuid, required

## Request body

- ComposeMailboxMessage: Body for POST /api/mailboxes/{id}/messages — a new outbound message from a hosted mailbox.
  - `bcc` string[]
  - `body` string
  - `cc` string[]
  - `document` object: Brandable email rendered by React Email. Text is escaped; images/GIFs use public HTTPS URLs. Columns stack on phones. No HTML, scripts, or arbitrary CSS.
    - `blocks` union[], required
      - union
        - object
          - `align` 'left' | 'center' | 'right'
          - `text` string, required
          - `type` 'heading', required
        - object
          - `align` 'left' | 'center' | 'right'
          - `text` string, required
          - `type` 'text', required
        - object
          - `alt` string, required
          - `href` string: Public HTTPS URL
          - `src` string, required: Public HTTPS image or animated GIF URL; no upload or server fetch is performed
          - `type` 'image', required
          - `width` integer
        - object
          - `align` 'left' | 'center' | 'right'
          - `href` string, required: Public HTTPS URL
          - `text` string, required
          - `type` 'button', required
        - object
          - `type` 'divider', required
        - object
          - `columns` array[], required
            - union[]
              - …
          - `type` 'columns', required
    - `brand` object
      - `accentColor` string: Six-digit hex color, e.g. #1454d4
      - `backgroundColor` string: Six-digit hex color, e.g. #1454d4
      - `buttonTextColor` string: Six-digit hex color, e.g. #1454d4
      - `font` 'sans' | 'serif' | 'mono'
      - `logoUrl` string: Public HTTPS URL
      - `name` string, required
      - `surfaceColor` string: Six-digit hex color, e.g. #1454d4
      - `textColor` string: Six-digit hex color, e.g. #1454d4
      - `websiteUrl` string: Public HTTPS URL
    - `footer` string
    - `preview` string: Inbox preview text
  - `subject` string, required
  - `to` string[], required

## Response `201`

Message submitted

- object
  - `data` object, required
    - `conversationId` string, uuid, required: The conversation this send started. Replies thread onto it.
    - `messageId` string, uuid, required: The stored outbound message.
    - `submitted` true, required
  - `success` true, required

## Other responses

- `400`: Validation error
- `401`: Unauthorized — missing or invalid auth
- `403`: Forbidden — insufficient permissions or project disabled
- `404`: Resource not found
- `422`: The mailbox is not active, a recipient is suppressed (`RECIPIENT_SUPPRESSED`), or the content scanner refused the message (`CONTENT_REFUSED`).
- `429`: Rate limit or billing limit exceeded
- `500`: Internal server error
- `502`: The mail server refused the submission. Nothing was sent.
- `503`: Message screening could not reach a verdict. Nothing was sent; retry shortly.

---

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