---
title: "Create or send an email message"
method: POST
path: "/email_messages"
tags: ["Email Messages"]
---

# Create or send an email message

`POST /email_messages`

Queues, schedules, or sandbox-sends an email message. The legacy `/v2/emails` POST route
is a backward-compatible alias for this operation.

`subject` is required unless `template_id` is supplied. When using `template_id`, do not
also provide `subject`, `html_body`, or `text_body`; the template is rendered with
`template_variables`.

Note: template lookup failures (not found, wrong account) return 400, not 404.

## Headers

- `Idempotency-Key` string

## Request body

- CreateEmailRequest
  - `attachments` AttachmentRequest[]
    - `content` string — Attachment content, typically Base64-encoded. Defaults to empty string when omitted.
    - `content_type` string — MIME content type. Defaults to "application/octet-stream" when omitted.
    - `filename` string — Attachment filename. Defaults to "attachment" when omitted.
  - `bcc` EmailAddressInput[]
    - union
      - string
      - EmailAddress
        - `email` string, required
        - `name` string
  - `cc` EmailAddressInput[]
    - union
      - string
      - EmailAddress
        - `email` string, required
        - `name` string
  - `from` union, required
    - string
    - EmailAddress
      - `email` string, required
      - `name` string
  - `from_name` string — Optional display name for string `from`; overrides `from.name` when provided.
  - `group_id` string, uuid — Optional unsubscribe group ID. Associates the message with an unsubscribe group for group-scoped suppression handling.
  - `headers` object — Custom email headers. Write-only; not returned in responses.
  - `html_body` string — HTML email body. Write-only; not returned in responses.
  - `ignore_suppression` boolean — When true, bypasses suppression checks for overridable blocks. Requires the `email:override` API key scope. Overrides are audited. Non-overridable suppressions (hard bounces, spam complaints, invalid addresses) cannot be bypassed.
  - `inline_css` boolean
  - `metadata` object — Custom metadata. Write-only; not returned in responses.
  - `reply_to` union
    - string
    - EmailAddress
      - `email` string, required
      - `name` string
  - `sandbox_mode` boolean
  - `send_at` string, date-time — Future ISO 8601 time to schedule sending. Invalid or past timestamps are silently ignored and the email is sent immediately.
  - `subject` string — Required unless `template_id` is supplied. When using a template, the template's subject is rendered; if the template has no subject or renders empty, the request returns 400.
  - `tags` string[] — Tags for categorization. Write-only; not returned in responses.
  - `template_id` string, uuid
  - `template_variables` object — Variables for Liquid template rendering. Non-object values may cause a 422 validation error on message creation, but are silently treated as an empty object for template rendering.
  - `text_body` string — Plain text email body. Write-only; not returned in responses.
  - `to` EmailAddressInput[], required
    - union
      - string
      - EmailAddress
        - `email` string, required
        - `name` string

## Response `202`

Message queued, scheduled, or sandbox-created.

- EmailMessageResponse
  - `data` EmailMessage, required
    - `attachments` AttachmentResponse[], required
      - `content_type` string, required
      - `filename` string, required
    - `bcc` EmailAddress[], required
      - `email` string, required
      - `name` string
    - `cc` EmailAddress[], required
      - `email` string, required
      - `name` string
    - `events` MessageEvent[], required
      - `occurred_at` string, date-time, required
      - `payload` object
      - `type` 'queued' | 'deferred' | 'scheduled' | 'cancelled' | 'sandbox' | 'sending' | 'sent' | 'failed' | 'delivered' | 'bounced' | 'complained' | 'rejected' | 'opened' | 'clicked' | 'unsubscribed', required
    - `from` EmailAddress, required
      - `email` string, required
      - `name` string
    - `id` string, uuid, required
    - `inline_css` boolean — Present when true in the immediate create response. Not persisted; absent on subsequent GET requests.
    - `inserted_at` string, date-time, required
    - `record_type` 'email_message', required
    - `reply_to` string, nullable, required
    - `sandbox` boolean — Present when sandbox mode was used.
    - `send_at` string, date-time — Present when a send_at value was stored. Persists even after the scheduled send has been processed or cancelled.
    - `status` 'queued' | 'scheduled' | 'cancelled' | 'sandbox' | 'sending' | 'sent' | 'failed' | 'deferred' | 'delivered' | 'bounced' | 'complained' | 'rejected' | 'opened' | 'clicked' | 'unsubscribed', required — Current status of an email message. Lifecycle statuses (queued, scheduled, etc.) are set on creation. Delivery statuses (delivered, bounced, etc.) are updated by delivery event consumers.
    - `subject` string, required
    - `suppressed` object[] — Present when one or more recipients were suppressed at send time. Each entry lists the suppressed recipient, reason, scope, and whether the block was overridable.
      - `override_allowed` boolean
      - `reason` string
      - `scope` string
      - `to` string, email
    - `template_id` string, uuid, nullable, required
    - `template_variables` object, required
    - `to` EmailAddress[], required
      - `email` string, required
      - `name` string
  - `suppressed` SuppressedRecipient[] — Recipients removed by suppression checks when at least one recipient remains and the message is accepted.
    - `override_allowed` boolean, required — Whether an authorized send may override this suppression.
    - `reason` string, required — Suppression reason returned by the recipient suppression service.
    - `scope` string, required — Scope at which the suppression applies.
    - `to` string, email, required — Suppressed recipient email address.

## Other responses

- `400` — Bad Request / Validation Failed (10015). Invalid, duplicate, empty, malformed, or overlong Idempotency-Key headers are rejected by Edge with HTTP 400 and error code 10015.
- `401` — Not authorized (10006).
- `403` — Forbidden (10007), such as domain not verified, suspended, degraded, or missing DKIM.
- `404` — Resource not found (10001).
- `409` — A request with the same Idempotency-Key is still being processed (10036). Retry later with the same key and request.
- `413` — Request body exceeds the 8,000,000-byte limit for this endpoint.
- `422` — Validation failed, send-time template rendering failed, or all recipients suppressed (code `recipient_suppressed`, includes top-level `suppressed` array). Reusing an Idempotency-Key with a different request also returns 422 (10027).
- `429` — Sending suspended — domain reputation band is 'poor'.
- `503` — Service unavailable (10016), including an unavailable upstream dependency or unavailable Edge idempotency protection for a keyed request.

## Changes

- **2026-07-21** `80833e66e010` — 1 breaking
  - added `#/components/schemas/RenderErrorResponse` to the response body `oneOf` list for the response status `422`
- **2026-07-16** `2fb3b617430a` — 16 warning, 9 info
  - added the new `recipient_suppressed` enum value to the `errors/items/code` response property for the response status `400`
  - added the new `recipient_suppressed` enum value to the `errors/items/code` response property for the response status `401`
  - added the new `recipient_suppressed` enum value to the `errors/items/code` response property for the response status `403`
  - added the new `recipient_suppressed` enum value to the `errors/items/code` response property for the response status `404`
  - …21 more
- **2026-07-14** `021f0faf96df` — 1 breaking, 1 warning
  - for the `header` request parameter `Idempotency-Key`, the maxLength was decreased from `512` to `255`
  - changed the pattern of the `header` request parameter `Idempotency-Key` from `^(?:[A-Za-z0-9_-]{1,255}|"(?:[\x20-\x21\x23-\x5B\x5D-\x7E]|\\["\\]){1,255}")$` to `^[A-Za-z0-9_-]{1,255}$`
- **2026-07-12** `b3c5aebde44c` — 2 breaking, 13 warning, 3 info
  - removed the required property `data/idempotency_key` from the response with the `202` status
  - removed the success response with the status `200`
  - removed the request property `idempotency_key`
  - added the new `10027` enum value to the `errors/items/code` response property for the response status `400`
  - …14 more
- …earlier changes not shown

[Full history](https://skmtc.dev/team-telnyx/apis/telnyx-api-2/changes/email_messages/post.md)

---

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