> **Early access.** Send API is available to selected organizations and is not generally available yet. What this page describes may change before it is. To request access, email support@sendops.dev.

The **Send API** lets your application send an email with one HTTPS request: `POST /v1/send` on `https://ingest.sendops.dev`, authenticated with a SendOps API key. SendOps checks the request, then sends it through **your own AWS SES account**, the same account your broadcasts and workflows use. You don't need AWS credentials in your application, and you don't need to build the MIME message yourself.

To turn the Send API on for your organization, use the **Request access** link above.

## When to use it

SendOps has three ways to send. They suit different kinds of mail:

| | Send API | Broadcast | Drip workflow |
|---|---|---|---|
| Who decides to send | Your code, one message at a time | You, from the dashboard or the Public API | SendOps, when a contact meets the trigger |
| Recipients | The addresses in the request | A List or Segment | One contact at a time, as they enrol |
| Typical mail | Password resets, receipts, sign-in links, alerts | Newsletters, announcements | Onboarding, nurture, win-back |
| Consent and topics | Not checked. Your code decides | Enforced for every recipient | Enforced at each send step |

Use the Send API for **transactional** mail: messages one person needs because of something they just did. For mail that goes to an audience, use a [broadcast](/sending-email/broadcasts). For a sequence that reacts to what a contact does over time, use a [drip workflow](/workflows/overview).


  SendOps sends what your request asks for. It doesn't check topics, opt-outs or List membership first, the way a broadcast or a workflow does. Don't send marketing mail through the Send API.


You can also keep sending straight to SES with the AWS SDK. Nothing about that changes, and SendOps reports on that mail as before (see [How email flows](/sending-email/email-flow)). The Send API is an alternative to it, not a replacement.

## Before you start

You need:

- **A connected AWS account.** See [Connecting AWS](/aws-setup/connecting-aws). Without one, every send is refused with "organization has no connected AWS account".
- **A sender SendOps manages.** The `from` address must be on a [domain](/domains/adding-a-domain), or be an [email identity](/domains/email-identities), that is verified in SES **and** managed by SendOps for your organization. A domain covers itself only, not its subdomains: `example.com` lets you send from `billing@example.com`, but not from `billing@mail.example.com`.
- **SES production access**, to send to anyone. While your SES account is in the [sandbox](/sending-email/ses-sandbox), SES only delivers to addresses you have verified.

Send API mail goes out through your organization's **default channel**, so its delivery events and open and click tracking follow that [channel's](/channels/understanding-channels) settings.

## Create an API key that can send

The Send API uses the same [API keys](/api-integrations/api-keys) as the Public API. A key needs the **`api.send`** scope to send. Only the **Owner** and **Org Admin** roles can create API keys.


<Step title="Open Workspace → API Keys">
  Select **Workspace** in the sidebar, then the **API Keys** tab, and click **Create API Key**.
</Step>
<Step title="Name the key and choose an environment">
  Give it a name that says where it runs, such as "checkout-service". Choose **Live** to send to real recipients. Choose **Test** for a key that can only send to test addresses (see [Test keys](#test-keys) below).
</Step>
<Step title="Tick the send scope">
  In **Scopes**, find the **Send API** group and tick **`api.send`** (*Send email*). It carries a **Send API** badge because it works on `ingest.sendops.dev` and nowhere else. You can type `send` in **Search scopes...** to find it.

  If the key only sends mail, `api.send` is the only scope it needs.
</Step>
<Step title="Review and create">
  Click **Review**, check the summary, then **Create key**. You might be asked to confirm with your second factor.
</Step>
<Step title="Copy the secret">
  The secret is shown **once**. It starts with `sk_live_` (or `sk_test_` for a test key). Put it straight into your secrets manager.
</Step>


You can also add `api.send` to an existing key by editing its scopes. The change takes effect immediately.


  The `api.send` scope only appears for organizations with Send API access. Request access using the link at the top of this page.


## Your first send

Store the key in an environment variable, then send a message:

```bash
curl https://ingest.sendops.dev/v1/send \
  -H "Authorization: Bearer $SENDOPS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6f1c2a9e-4b7d-4e2a-9c3f-1d8e5b0a7c42" \
  -d '{
    "from": "Acme <billing@acme.com>",
    "to": ["customer@example.com"],
    "subject": "Your receipt",
    "html": "Thanks for your order.",
    "text": "Thanks for your order."
  }'
```

Replace `billing@acme.com` with an address on your own managed domain. When SES accepts the message, you get `200`:

```json
{
  "status": "sent",
  "message_id": "0100018f...",
  "request_id": "req_..."
}
```

`message_id` is the SES message ID. You can search for it in Reports. `request_id` identifies your request to SendOps.

Instead of `html` and `text`, you can send one of your stored [templates](/templates/template-management) by name or ID, with `variables` to fill it in. The template must be deployed to your SES account. You can also add attachments, or post a complete raw MIME message. The [developer reference](https://developers.sendops.dev/api-reference/send-api) covers every field.

### Send each message once

Send an `Idempotency-Key` header with every request, using a value that is unique to the message (a UUID works well), and **reuse the same key if you retry**. If SendOps has already sent a message under that key, it returns the original response again instead of sending a second copy. Keys are remembered for at least 7 days.

### If the response isn't 200

- **`202 queued`**: SendOps has stored the request and will send it shortly. This happens when SendOps can't send it at once. The body has a `request_id`. Look it up with `GET /v1/messages/{request_id}` to see when it's sent.
- **`400`**: something in the request needs fixing, such as a `from` address SendOps doesn't manage. The response names the field. Retrying unchanged won't help.
- **`429` or `503`**: wait for the number of seconds in the `Retry-After` header, then retry with the same `Idempotency-Key`. A `429` with code `send_quota_exceeded` means your organization has reached its monthly ceiling (see [Usage and the fair-use ceiling](#usage-and-the-fair-use-ceiling)).

The [developer reference](https://developers.sendops.dev/api-reference/send-api) lists every status and error code.

## Test keys

A **Test** (`sk_test_`) key sends real email, but only to two kinds of address:

- SES mailbox simulator addresses (anything `@simulator.amazonses.com`), which let you try out deliveries, bounces and complaints safely;
- addresses on your organization's own verified, managed domains and email identities.

Any other recipient is refused with `403` and nothing is sent. Test sends don't count toward your monthly ceiling. Live and test requests are kept apart, so a test key can't look up a request a live key made.

## Where to see what was sent

Send API messages appear in **Reports → Messages** alongside everything else SendOps reports on. Their **Source** column reads **API · req_…**, with the request ID from the send. Search by the `message_id` or the recipient to find a message, and click it for the full delivery timeline. Bounces, complaints, opens and clicks are tracked as for any other mail through that channel, and they count in your [deliverability](/reports/deliverability-reports) and [engagement](/reports/engagement-metrics) reports.


  The **Source** filter on the Messages tab doesn't have an option for Send API messages yet. Use search to find them.


To check one request from your code, call `GET /v1/messages/{request_id}` with the same key environment. It answers `sent` (with the `message_id`), `queued`, `in_flight` or `failed` (with the reason).

## Usage and the fair-use ceiling

The Send API has **no per-email charge**. Each plan has a monthly **fair-use ceiling** on live API sends, which keeps SendOps' costs predictable.

On the **Billing** page, the **API sends** card shows:

- how many live API sends your organization has made this billing period, out of its ceiling;
- when the count resets (**Resets** *date*), or **Unlimited** if your plan has no ceiling;
- a progress bar that turns amber at 80% and red at the ceiling.

Only live sends count. Test-key sends don't count, and nor do requests SendOps refuses before sending. A request SendOps has already accepted as `202 queued` is always sent, and it counts.

When your organization passes **80%** of the ceiling, everyone who can see the Billing page (Owners, Org Admins and the Financial role) sees an amber banner at the top of the dashboard, and SendOps sends a **Plan limit approaching** [notification](/notifications/notification-types). At **100%**, the banner turns red and a **Plan limit reached** notification follows. Each is sent once per billing period.

At the ceiling, API sends are **paused until the period resets**. `POST /v1/send` answers `429 send_quota_exceeded`, with the limit, the count used and the reset time, and nothing is sent. The idempotency key isn't used up, so you can send the same request again once the period resets. Your broadcasts and workflows are not affected. If you need a higher ceiling, contact [support@sendops.dev](mailto:support@sendops.dev).

## Delivery tiers

Your plan sets your organization's **delivery tier**, which every send response reports in the `X-SendOps-Tier` header:

| Plan | Tier |
|---|---|
| Business | `critical` |
| Team | `standard` |
| Free | `bulk` |

The tier only matters when SendOps has to queue requests (the `202 queued` case above). Queued mail is then sent in tier order: `critical` first, then `standard`, then `bulk`.

## Everything else

The [Send API reference](https://developers.sendops.dev/api-reference/send-api) on the developer site covers the request and response formats, templates and attachments, raw MIME messages, size limits, every error code and the retry rules.