Agent Skill · Sinch

sinch-mailgun

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.

Provider: Sinch Path in repo: skills/sinch-mailgun/SKILL.md

Skill body

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:

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:

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:

--user "api:$MAILGUN_API_KEY"

See sinch-authentication for full auth setup. Find your key at Mailgun Dashboard > Account Settings > API Keys.

Two key types:

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

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='recipient@example.com' \
  -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

npm install mailgun.js form-data
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: ['recipient@example.com'],
  subject: 'Hello',
  text: 'Testing Mailgun!',
});

For other SDKs: SDK Reference

Key Concepts

Domains

Sending

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

For full parameters: Messages API

Templates

Two levels:

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.

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

Events and Analytics

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

Inbound Routing

Routes API — 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.

Mailing Lists

Mailing Lists API/v3/lists to create/manage lists, /v3/lists/{address}/members for members. Bulk upload via .json or .csv endpoints.

Stored Messages

Retrieve: GET /v3/domains/{domain}/messages/{storage_key}. Resend: POST to same path. See Messages API

Infrastructure Management

For IPs, IP Pools, IP Warmup, DKIM Keys, and Subaccounts — see references/infrastructure.md.

Common Patterns

Batch send with personalization

Add recipient-variables as JSON mapping each recipient address to their variables. Use %recipient.variable_name% in subject/body. Max 1,000 recipients per call. See Batch Sending

Set up domain webhooks

  1. Create webhook via POST /v3/domains/{domain}/webhooks with id (event type) and url fields
  2. Verify HMAC signature on incoming webhooks using your webhook signing key (SHA256). See Securing Webhooks
  3. Return 2xx or Mailgun retries with exponential backoff for ~8 hours

Schedule and cancel delivery

Configure inbound email

  1. Add MX records pointing to mxa.mailgun.org and mxb.mailgun.org (priority 10)
  2. Create route via POST /v3/routes with expression (match pattern) and action (forward/store/webhook). See Routes Guide

Gotchas

Security

References

Skill frontmatter

metadata: {"author" => "Sinch", "version" => "1.0.4", "category" => "Email", "tags" => "email, mailgun, smtp, webhooks, templates, domains, suppressions", "uses" => ["sinch-authentication"]}