---
title: "Send a transactional email"
method: POST
path: "/emails"
tags: ["Emails"]
---

# Send a transactional email

`POST /emails`

## Request

- Base URL: `https://faivelo.com/api/v1`
- URL: `https://faivelo.com/api/v1/emails`
- Auth: HTTP bearer

Sends an email from any address on one of your verified domains — no mailbox needs to exist for the sender. Recipients on your suppression list (previous hard bounces and complaints) are dropped automatically; if none survive, the call fails with 422 and nothing is sent. Set an `Idempotency-Key` header to make retries safe: a repeated key returns the original result instead of sending twice. Counts against the monthly send limit. Requires scope `mail:send`. Delivery events (delivered/bounced/complained) can be pushed to your server as they happen — configure [webhooks](https://faivelo.com/docs/transactional/webhooks/) in the dashboard under Transactional → API.

## Headers

- `Idempotency-Key` string

## Request body

- TransactionalEmailRequest: Provide either `subject` with `html`/`text`, or `templateAlias` (plus `variables`) to send a stored template.
  - `from` string, required: Sender: any address on one of your verified domains, bare or as "Name <address>". No mailbox needs to exist. With no name, the From name is the name of the mailbox at that address, else the domain default.
  - `fromName` string: From display name; wins over a name written into `from`
  - `to` union, required: Recipient address, or an array of up to 50
    - string
    - string[]
  - `cc` union: CC address(es)
    - string
    - string[]
  - `bcc` union: BCC address(es)
    - string
    - string[]
  - `subject` string: Required unless templateAlias is given
  - `html` string: HTML body. With templateAlias, this markup fills the template's API-content block instead — your HTML renders inside the designed template.
  - `text` string: Plain-text body
  - `replyTo` string: Reply-To address
  - `templateAlias` string: Alias of a stored transactional template; supplies subject and body. Combine with `html` to render your own markup inside the template's API-content block.
  - `variables` object: Values for the template's {{variables}}. Strict: a missing variable fails with 422 and nothing is sent.
  - `attachments` object[]: Up to 10 attachments, 10 MB total (base64-encoded)
    - `filename` string, required
    - `content` string, required: Base64-encoded file content
    - `contentType` string

## Response `200`

Email accepted for delivery

- object
  - `success` boolean
  - `data` TransactionalEmail
    - `id` string: The send id — pass to GET /emails/{id}
    - `from` string
    - `to` string[]
    - `subject` string
    - `status` 'sent' | 'delivered' | 'bounced' | 'complained' | 'failed' | 'suppressed': sent = accepted for delivery; later statuses arrive from delivery events
    - `messageId` string: RFC 5322 Message-ID stamped on the email
    - `suppressed` string[]: Recipients dropped because your suppression list holds them
    - `replayed` boolean: True when this response was replayed from an earlier request with the same Idempotency-Key
    - `hint` string: Present when the email went out with no display name, so recipients saw only the address. Says how to set one.

## Other responses

- `401`: Missing or invalid API key
- `402`: The account's plan does not include the API (`plan_required`)
- `403`: The key lacks the required scope
- `429`: Rate limit exceeded

---

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