Claude
Skills
Sign in
Back

sinch-mailgun

Included with Lifetime
$97 forever

Sends, receives, and tracks email via the Mailgun (Sinch) API. Use when the user wants to send email, manage domains, configure webhooks, query email events/logs, manage templates, handle suppressions (bounces, unsubscribes, complaints), set up inbound routes, manage mailing lists, DKIM keys, or IP warmup using Mailgun.

Backend & APIs

What this skill does


# Mailgun Email API

## Overview

Mailgun (by Sinch) provides REST API and SMTP relay for transactional and bulk email — sending, receiving, tracking, and suppression management.

## Agent Instructions

Before generating code, gather from the user (skip any item already specified in the prompt or context):

1. **Region** — US or EU. Region determines the base URL and cannot be changed after domain creation.
2. **Approach** — SDK or direct API calls (curl/fetch/requests)?
3. **Language** — for SDK: Node.js (`mailgun.js`). For direct API: any language, or curl. Other languages must use direct HTTP — there is no first-party SDK wrapper.
4. Before generating code, check for existing `.env` files or environment variables for `MAILGUN_API_KEY` and `MAILGUN_DOMAIN`.

Product gotchas to apply unconditionally:
- For events, logs, stats, or tags — use the current `/v1/analytics/*` APIs, never the deprecated v3 endpoints.
- For domain CRUD operations, use `/v4/domains` (not v3).

When the user chooses **SDK**, refer to the Node.js SDK reference linked in Links.

When the user chooses **direct API calls**, refer to the API references linked in Links for request/response schemas.

**Security**: See the Security section below for url fetching policy, handling inbound webhook content, and credential handling.

## Getting Started

### Agent Credentials handling

Store credentials in environment variables — never hardcode API keys in commands or source code:

```bash
export MAILGUN_API_KEY="your-private-api-key"
export MAILGUN_DOMAIN="your-sending-domain"
```

### Authentication

Ensure that authentication headers are properly set when making API calls. Mailgun uses HTTP Basic Auth — username `api`, password your Mailgun Private API key:

```bash
--user "api:$MAILGUN_API_KEY"
```

See [sinch-authentication](../sinch-authentication/SKILL.md) for full auth setup. Find your key at Mailgun Dashboard > Account Settings > API Keys.

Two key types:
- **Primary Account API Key** — full access to all endpoints and domains
- **Domain Sending Keys** — restricted to `POST /messages` and `/messages.mime` for one domain

### Base URLs

Always match the base URL to the domain's region. Data never crosses regions.

| Service | US | EU |
|---------|----|----|
| REST API | `api.mailgun.net` | `api.eu.mailgun.net` |
| Outgoing SMTP | `smtp.mailgun.org` | `smtp.eu.mailgun.org` |
| Inbound SMTP | `mxa.mailgun.org`, `mxb.mailgun.org` | `mxa.eu.mailgun.org`, `mxb.eu.mailgun.org` |
| Open/Click Tracking | `mailgun.org` | `eu.mailgun.org` |

### Send an Email

```bash
curl -X POST \
  "https://api.mailgun.net/v3/$MAILGUN_DOMAIN/messages" \
  -s --user "api:$MAILGUN_API_KEY" \
  -F from='Sender <sender@YOUR_DOMAIN>' \
  -F to='[email protected]' \
  -F subject='Hello from Mailgun' \
  -F text='This is a test email.' \
  -F html='<h1>Hello</h1><p>HTML body.</p>'
```

Response: `{"id": "<message-id@YOUR_DOMAIN>", "message": "Queued. Thank you."}`

The Messages API uses `multipart/form-data` — use `-F` flags, not `-d` with JSON.

### Node.js SDK

```bash
npm install mailgun.js form-data
```

```javascript
const Mailgun = require('mailgun.js');
const formData = require('form-data');
const mg = new Mailgun(formData).client({
  username: 'api',
  key: process.env.MAILGUN_API_KEY,
  // For EU: url: 'https://api.eu.mailgun.net'
});

mg.messages.create('YOUR_DOMAIN', {
  from: 'Sender <sender@YOUR_DOMAIN>',
  to: ['[email protected]'],
  subject: 'Hello',
  text: 'Testing Mailgun!',
});
```

For other SDKs: [SDK Reference](https://documentation.mailgun.com/docs/mailgun/sdk/introduction.md)

## Key Concepts

### Domains

- **Sandbox domain** — provided on signup (e.g., `sandboxXXX.mailgun.org`). Only pre-authorized recipients can receive mail.
- **Custom domain** — requires DNS verification (SPF, DKIM, MX). Domain CRUD uses `/v4/domains` (not v3). Only `DELETE` remains on v3. See [Domains API](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/domains/get-v4-domains.md)

### Sending

- **REST API** — `POST /v3/{domain}/messages` with `from`, `to`, `cc`, `bcc`, `subject`, `text`, `html`, `amp-html`, attachments, headers, tags, variables
- **SMTP** — `smtp.mailgun.org` port 587 TLS, credentials per-domain via `/v3/domains/{domain}/credentials`. See [Credentials API](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/credentials/get-v3-domains--domain-name--credentials.md)
- **MIME** — `POST /v3/{domain}/messages.mime`
- **Batch** — up to 1,000 recipients per call using `recipient-variables` for personalization
- **Test mode** — add `o:testmode=yes` to simulate without delivery
- **Scheduling** — `o:deliverytime` (RFC-2822), `o:deliverytime-optimize-period` (STO), `o:time-zone-localize` (TZO)
- **Tracking** — `o:tracking`, `o:tracking-clicks`, `o:tracking-opens` per message; or configure at domain level via `/v3/domains/{name}/tracking`. See [Domain Tracking API](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/domain-tracking/get-v3-domains--name--tracking.md)

Send options (`o:`, `h:`, `v:`, `t:` params) are limited to 16KB total per request.

For full parameters: [Messages API](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/messages/post-v3--domain-name--messages.md)

### Templates

Two levels:
- **Domain** — `/v3/{domain}/templates`. See [Domain Templates API](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/domain-templates/get-v3--domain-name--templates.md)
- **Account** — `/v4/templates` (shared across all domains). See [Account Templates API](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/account-templates/get-v4-templates.md)

Reference by name when sending: `-F template='welcome-template' -F t:variables='{"name":"John"}'`. Each template supports up to 40 versions.

### Webhooks

Real-time HTTP POST notifications for email events.

- **Domain** — `/v3/domains/{domain}/webhooks` (v3) or `/v4/domains/{domain}/webhooks` (v4). See [Domain Webhooks API](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/domain-webhooks/get-v3-domains--domain--webhooks.md)
- **Account** — `/v1/webhooks` (fires across all domains). See [Account Webhooks API](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/account-webhooks/get-v1-webhooks.md)

Event types: `clicked`, `complained`, `delivered`, `failed`, `opened`, `permanent_fail`, `temporary_fail`, `unsubscribed`

### Events and Analytics

- **Logs** — `POST /v1/analytics/logs` for querying event data. The legacy `GET /v3/{domain}/events` is deprecated. See [Logs API](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/logs/post-v1-analytics-logs.md)
- **Metrics** — `POST /v1/analytics/metrics` for aggregated analytics with dimensions, filters, resolutions. Replaces deprecated `/v3/stats`. See [Metrics API](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/metrics/post-v1-analytics-metrics.md)
- **Tags** — `o:tag` when sending; manage via `/v1/analytics/tags`. Legacy `/v3/{domain}/tags` is deprecated. See [Tags API](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/tags-new/post-v1-analytics-tags.md)

Data retention: Logs — at least 3 days (legacy). Metrics — hourly 60 days, daily 1 year, monthly indefinite.

### Inbound Routing

[Routes API](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/routes/get-v3-routes.md) — match incoming messages by recipient pattern or header expression, then forward, store, or webhook. Configure both `mxa` and `mxb` MX records.

### Suppressions and Allowlists

Per-domain suppression lists that Mailgun auto-populates. Sending to suppressed addresses silently drops.
- [Bounces](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/bounces/get-v3--domainid--bounces.md) — `/v3/{domain}/bounces`
- [Unsubscribes](https://docume

Related in Backend & APIs