# MailBlastr Skill

> Teach an AI agent to send single and batch emails through the MailBlastr API with built-in retries and idempotency.

The **MailBlastr skill** packages MailBlastr's official recommendations for sending email so an AI coding agent can wire up reliable sends without guessing at the API. It gives the agent a streamlined recipe for single and batch sends, complete with error handling and retry logic.

A "skill" here is a set of instructions and patterns you drop into your agent's context (for example, a `SKILL.md` file in your repo, or a tool definition your agent reads). When a task involves sending email, the agent follows the skill's recipe instead of inventing its own.

## How to give an agent this skill

This is a skill *pattern*, not a package to install — capture the recipe below as a `SKILL.md` (or equivalent context file) in your repo and load it into your agent's context. It builds on primitives that already exist: the [`mailblastr` Node SDK](https://www.mailblastr.com/docs/resources/sdks), the [`mailblastr-mcp` MCP server](https://www.mailblastr.com/docs/ai/mcp-server), and the plain JSON [Emails API](https://www.mailblastr.com/docs/api/emails-send) over native HTTP.

> **Note:** If you want your agent to send through a managed tool rather than hand-rolled HTTP, point it at the MailBlastr MCP server — `npx -y mailblastr-mcp` — which exposes the send endpoints as tools. See [MCP Server](https://www.mailblastr.com/docs/ai/mcp-server).

## What it gives your agent

- **Single and batch sending** — send one email via [POST /emails](https://www.mailblastr.com/docs/api/emails-send), or up to 100 in a single [POST /emails/batch](https://www.mailblastr.com/docs/api/emails-batch) request.
- **Built-in error handling and retry logic** — retry transient failures (network errors, `5xx`, rate limits) with exponential backoff, and surface validation errors without retrying.
- **Idempotency-key support** — attach an `Idempotency-Key` header so a retried send is processed only once. See [Idempotency keys](https://www.mailblastr.com/docs/emails/idempotency).
- **Works in any language** — the recipe is built on plain HTTP against `https://api.mailblastr.com`, so it applies whether the agent uses the official [`mailblastr` Node SDK](https://www.mailblastr.com/docs/resources/sdks) or raw `fetch`/`curl`/`requests`.
- **Automatic activation** — when a task needs email, the agent reaches for the skill instead of hand-rolling a request.

## The core recipe

At its heart the skill instructs the agent to authenticate with a Bearer API key (the `mb_` key from the [dashboard](https://www.mailblastr.com/docs/api-keys/overview)) and POST a JSON body to the Emails API. In Node, the official [`mailblastr` SDK](https://www.mailblastr.com/docs/resources/sdks) wraps this; in any other language the agent makes the same request over native HTTP. A minimal send the agent would produce looks like this:

**cURL**

```bash
curl -X POST 'https://api.mailblastr.com/emails' \
  -H 'Authorization: Bearer mb_xxxxxxxxx' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 8f3a9c1e-2b4d-4e6f-9a1b-c2d3e4f5a6b7' \
  -d '{
    "from": "Acme <hello@yourdomain.com>",
    "to": ["delivered@example.com"],
    "subject": "Hello from your agent",
    "html": "<p>Sent through the MailBlastr skill.</p>"
  }'
```

**Node.js**

```js
import { MailBlastr } from 'mailblastr';
const mb = new MailBlastr(process.env.MAILBLASTR_API_KEY);

async function sendEmail(body, { retries = 3 } = {}) {
  const idempotencyKey = crypto.randomUUID();
  for (let attempt = 0; ; attempt++) {
    const { data, error } = await mb.emails.send(body, { idempotencyKey });
    if (!error) return data;
    // Retry transient failures only; surface 4xx validation errors immediately.
    const status = error.statusCode ?? 0;
    if (attempt >= retries || (status < 500 && status !== 429)) {
      throw new Error(`send failed: ${status}`);
    }
    await new Promise(r => setTimeout(r, 2 ** attempt * 250));
  }
}
```

**Python**

```python
import os, time, uuid, requests

def send_email(body, retries=3):
    for attempt in range(retries + 1):
        res = requests.post(
            "https://api.mailblastr.com/emails",
            headers={
                "Authorization": f"Bearer {os.environ['MAILBLASTR_API_KEY']}",
                "Idempotency-Key": str(uuid.uuid4()),
            },
            json=body,
        )
        if res.ok:
            return res.json()
        # Retry transient failures only.
        if attempt >= retries or (res.status_code < 500 and res.status_code != 429):
            res.raise_for_status()
        time.sleep(2 ** attempt * 0.25)
```

> **Note:** Give the agent the same idempotency key across retries of one logical send so a network blip can never produce a duplicate email. A fresh key per *new* send.

> **Warning:** Never expose your `mb_` API key in client-side code. The skill should read it from an environment variable or secret store and send only from server-side code.

## Batching

When the agent has many distinct messages to send, the skill prefers `POST /emails/batch` (a JSON array of up to 100 email objects) over a loop of single sends. Every item is validated before any is sent — see [Batch sending](https://www.mailblastr.com/docs/emails/batch).
