Agent Skill

Let an AI agent send its first email

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.

Skill send-first-email · the same bytes agents read at /.well-known/agent-skills/send-first-email/SKILL.md

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.

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 <[email protected]>",
  to: "[email protected]",
  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 [email protected] and Acme <[email protected]>. 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: "[email protected]" the mail client shows only "hello". Two ways to make a name appear:

  • per send: from: "Acme <[email protected]>";
  • 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 <[email protected]> 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.

Use it

Point your agent at the file, or paste it into a system prompt. The tools it names live on our MCP server, so an agent needs to be connected first and needs the scopes for what it is about to do.

Connect over MCP · Documentation · Raw markdown

The other skills

Start with Sending

Give your agent something worth sending.

3,000 messages a month, free. No card. The MCP endpoint is on every plan, including this one.