---
name: send-first-email
order: 1
description: "Verify a sending domain and send your first transactional email with Sending. Use this when you need to send a single email, or when a send is refused because the domain is not verified."
---

# Send the first email

You cannot send from an unverified domain: it is a server-side gate, not a warning.
Domain first, then the send.

## 1. Look at the existing domains

```
list_domains
```

Returns the workspace domains with their status. For the ones still `pending` it
includes the **DNS records to set** (SPF, DKIM, MAIL FROM). If the domain you need
is already there and `verified`, skip to step 4.

## 2. Add the domain

There is no MCP tool that creates domains: it happens in the dashboard under
*Communication › Domains*, or over REST.

```http
POST https://sending.dev/api/v1/domains
Authorization: Bearer sk_...
Content-Type: application/json

{ "name": "yourdomain.dev" }
```

The response carries the DNS records to publish.

## 3. Have the records published, then verify

The user publishes the records at their DNS provider. When they say they have:

```
verify_domain { domainId }
```

DNS propagation is not instant: if it still comes back `pending`, wait a few minutes
before trying again rather than calling it in a loop.

## 4. Send the email

```
send_email {
  from: "Acme <hello@yourdomain.dev>",
  to: "sara@acme.io",
  subject: "Welcome",
  html: "<h1>Ready</h1>",
  idempotencyKey: "welcome-sara-001"
}
```

`idempotencyKey` is **required**, at least 8 characters, and it goes in the body:
there is no `Idempotency-Key` header. It is what makes a retry safe: the same key
never sends twice. Use a key that describes the send, not a random value regenerated
on every attempt, or it protects you from nothing.

Every address field takes both `hello@yourdomain.dev` and `Acme <hello@yourdomain.dev>`.
`to`, `cc` and `bcc` also take several recipients at once, as an array or comma
separated inside one string. Each recipient counts as one unit of the monthly quota.

## The name the recipient sees

With `from: "hello@yourdomain.dev"` the mail client shows only "hello". Two ways to
make a name appear:

- **per send**: `from: "Acme <hello@yourdomain.dev>"`;
- **per domain, once**: `set_domain_sender_name { domainId, defaultFromName: "Acme" }`.
  From then on every email of that domain (transactional, campaigns, automations)
  goes out as `Acme <hello@yourdomain.dev>` even when `from` is the bare address.

An explicit name in the send always wins over the domain default. `list_domains`
shows the current value in `defaultFromName`; `defaultFromName: null` removes it.

## Attachments

Upload first, reference after:

```
upload_attachment { filename, content }   → { id }
send_email { ..., attachments: [{ id }] }
```

Limits: 20 attachments, 10 MB each, 25 MB in total. Executable extensions are
blocked, for the sake of the domain reputation. An uploaded attachment stays
reusable in later sends with the same `{ id }`.

## When a send does not go out

- `402`: the month's quota is exceeded. Call `get_usage` and tell the user.
- Domain not verified: back to step 3.
- Recipient on the **suppression list** (earlier bounce or complaint): the send is
  blocked on purpose. Do not work around it.

## Other channels

`send_message` sends on the same shape over WhatsApp or Telegram, if the channel is
configured and the contact has consented for that channel.
