Mailgun: Guía técnica completa para email transaccional
Por CaptainDNS
Publicado el 21 de enero de 2026

- 📢 Mailgun uses your domain in the Return-Path (
bounce+id@yourdomain.com), enabling native SPF alignment for DMARC from the base plan onwards. - The REST API is the recommended method: up to 1,000 recipients per call, undocumented rate limits (except Domains API: 300 req/min).
- Automatic Sender Security generates 2 DKIM CNAMEs with automatic rotation every 120 days, 2048-bit keys by default.
- Dedicated IP recommended from 1 million emails/month, with automatic warm-up over 15+ days and cost of $59/IP/month additional.
- Flex plan increased to $2.00/1000 emails since December 2025 (doubling of the rate).
Introduction
Mailgun has established itself as one of the most robust transactional email platforms on the market, processing over 600 billion emails per year for more than 100,000 customers. Acquired by Sinch in December 2021 for $1.9 billion USD, the service combines a powerful REST API, a universal SMTP relay, and advanced authentication features that set it apart from competitors.
Mailgun's strength lies in three major technical pillars: a developer-oriented API-first approach, a Domain Verification that uses your own domain for the Return-Path (native SPF alignment for DMARC), and an automatic 2048-bit DKIM key rotation system every 120 days without service interruption.
This guide is aimed at developers, DevOps, and system architects seeking to integrate Mailgun for transactional email with a complete understanding of the infrastructure: DNS configuration, API vs SMTP choice, dedicated IP management, technical limits, and event webhooks.
REST API vs SMTP Relay: architecture and integration choice
Mailgun offers two integration methods for transactional email, both available from the free plan onwards (100 emails/day).

Technical comparison
| Criterion | REST API | SMTP Relay |
|---|---|---|
| Endpoint | https://api.mailgun.net/v3/{domain}/messages (US) | smtp.mailgun.org ports 587/465 |
| Authentication | HTTP Basic Auth (api:YOUR_API_KEY) | SASL/PLAIN (postmaster@ + SMTP password) |
| Rate limit | Undocumented (Domains API: 300 req/min) | Depends on IP and plan |
| Recipients/req | Up to 1,000 (to + cc + bcc combined) | 1 email = 1 SMTP connection |
| Templates | Variables with {{variable}} syntax | Via X-Mailgun-Variables header |
| Scheduling | o:deliverytime (up to 3 days, 7d if 7d+ storage) | Via X-Mailgun-Deliver-By header |
| Tracking | Native (o:tracking, o:track-clicks, o:track-opens) | Via X-Mailgun-Track* headers |
| Compatibility | Requires SDK or HTTP client | Any SMTP-compatible system |
| Ideal use case | Modern apps, batch, advanced personalization | Legacy, CMS plugins, mail servers |
When to choose the REST API?
The REST API is Mailgun's recommended method for any new integration. It's accessible at POST https://api.mailgun.net/v3/{domain}/messages for the US region, or api.eu.mailgun.net for EU.
Key advantages:
- Batch sending: send up to 1,000 recipients in a single request with personalization via recipient variables
- Stored templates: Handlebars syntax with conditions, loops, custom helpers
- Scheduling: schedule sending up to 3 days in advance (7 days if your plan includes 7+ days of storage)
- Rate limit headers:
X-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-Resetfor monitoring
Example of sending with personalization:
curl -s --user 'api:YOUR_API_KEY' \
https://api.mailgun.net/v3/mail.captaindns.com/messages \
-F from='Notifications <no-reply@mail.captaindns.com>' \
-F to='user1@captaindns.com' \
-F to='user2@captaindns.com' \
-F subject='New notification' \
-F text='Hello {{firstname}}, you have {{count}} notifications.' \
-F recipient-variables='{"user1@captaindns.com":{"firstname":"John","count":"3"},"user2@captaindns.com":{"firstname":"Jane","count":"7"}}' \
-F o:tag='notification' \
-F o:tracking='yes'
Official SDKs: Mailgun maintains SDKs for Go, Node.js, PHP, Python, Ruby and Java that encapsulate the REST API and simplify integration.
When to choose the SMTP Relay?
The SMTP Relay is ideal for legacy systems or applications that only support SMTP.
Official configuration:
SMTP server: smtp.mailgun.org (US) or smtp.eu.mailgun.org (EU)
SMTP user: postmaster@mail.captaindns.com (or custom SMTP user)
SMTP password: [domain SMTP password]
Port: 587 (STARTTLS recommended) or 465 (direct TLS) or 2525 (GCE fallback)
Critical point: SMTP authentication uses the domain SMTP password, distinct from the API key. The username is the postmaster@ address of your verified domain (or a custom SMTP user created in the dashboard).
Proprietary X-Mailgun- headers*: allow access to advanced features via SMTP (tags, tracking, templates, scheduling, variables). Complete list:
X-Mailgun-Tag: tag for statistics (multiple possible)X-Mailgun-Track: enable/disable global trackingX-Mailgun-Track-Clicks: click tracking (yes/no/htmlonly)X-Mailgun-Track-Opens: open tracking (yes/no)X-Mailgun-Deliver-By: scheduling (RFC 2822 format or Unix timestamp)X-Mailgun-Template-Name: template name to useX-Mailgun-Variables: template variables (JSON)
Domain Verification: SPF, 2048-bit DKIM and native DMARC alignment
DNS configuration in Mailgun generates the necessary records for SPF, DKIM and DMARC alignment. The process is performed in Sending > Domains > Domain settings > Domain verification.
Architecture with Automatic Sender Security (recommended)
With the Automatic Sender Security option enabled (recommended), Mailgun generates 2 DKIM CNAME records for automatic key rotation:

Required records (example for mail.captaindns.com):
| Type | Name/Host | Value | Purpose |
|---|---|---|---|
| TXT | mail.captaindns.com | v=spf1 include:mailgun.org ~all | SPF |
| CNAME | pdk1._domainkey.mail.captaindns.com | pdk1._domainkey.XXXX.dkim1.mailgun.com | DKIM rotation (selector 1) |
| CNAME | pdk2._domainkey.mail.captaindns.com | pdk2._domainkey.XXXX.dkim1.mailgun.com | DKIM rotation (selector 2) |
| MX | mail.captaindns.com | mxa.mailgun.org (priority 10) | Bounces/Inbound |
| MX | mail.captaindns.com | mxb.mailgun.org (priority 10) | Bounces/Inbound |
EU region note: For EU, MX records use mxa.eu.mailgun.org and mxb.eu.mailgun.org.
Advantages of this architecture:
- Automatic DKIM key rotation: the two selectors (
pdk1andpdk2) allow Mailgun to change keys every 120 days without service interruption - 2048-bit DKIM keys by default (manual TXT configurations can use 1024 bits, but 2048 recommended)
- No tracking CNAME record required by default: Mailgun uses
mailgun.org(oreu.mailgun.orgfor EU) - DKIM selectors:
pdk1andpdk2for Automatic Security, ormxfor manual TXT configuration
Return-Path and SPF alignment: a major advantage
The Return-Path (Envelope From) is crucial for DMARC alignment. Mailgun automatically uses your domain for the Return-Path in the format bounce+UNIQUEID@mail.captaindns.com:
- SPF passes automatically because the
include:mailgun.orgrecord authorizes Mailgun IPs to send for your domain - SPF alignment works in relaxed mode (the Return-Path
bounce+id@mail.captaindns.commatches the parent domainmail.captaindns.com) - No separate configuration needed: unlike other providers, Mailgun doesn't require a dedicated subdomain for the bounce domain
Difference with competitors:
- SendGrid: uses a customizable subdomain (
em1234.captaindns.com) - Amazon SES: requires Custom MAIL FROM for SPF alignment
- Mailgun: directly uses your verified domain
For a strict DMARC policy (aspf=s), SPF alignment will fail if you send from a subdomain different from the Return-Path. The solution is to rely on DKIM for DMARC alignment, which supports strict mode (adkim=s).
Tracking domain (link branding)
The tracking domain replaces Mailgun domains in tracked links with your own domain. By default, Mailgun uses email.mail.captaindns.com pointing to mailgun.org (US) or eu.mailgun.org (EU) via CNAME.
Optional HTTPS configuration: Mailgun automatically generates a Let's Encrypt certificate once the CNAME is verified.
Migration to 2048-bit DKIM
To migrate a manual TXT configuration (1024-bit keys) to Automatic Sender Security (2048 bits), simply enable Automatic Sender Security in the dashboard then create the 2 new DKIM CNAMEs. The transition is smooth thanks to the two selectors.
Email authentication flow: from API to deliverability

When you send via Mailgun:
- Your application calls the REST API or uses SMTP
- Mailgun signs the message with your DKIM key (domain
d=mail.captaindns.com) - Mailgun uses your domain in the Return-Path (
bounce+id@mail.captaindns.com) - The recipient server verifies SPF (sending IP), DKIM (signature), then DMARC (alignment)
- SPF passes:
include:mailgun.orgauthorizes Mailgun IPs, Return-Path uses your domain - DKIM passes: signature
d=mail.captaindns.commatches the From header - DMARC passes: at least SPF AND DKIM are aligned (double validation)
DMARC alignment: configuration for p=reject
What works (and what breaks)
DKIM alignment:
| Configuration | Aligned? | DMARC via DKIM? |
|---|---|---|
| Domain with DKIM enabled (TXT or CNAME) | Yes | Yes |
SPF alignment:
| Configuration | Aligned? | DMARC via SPF? |
|---|---|---|
| Return-Path uses your domain (native) | Yes | Yes |
| aspf=r (relaxed, default) | Yes | Yes |
| aspf=s (strict) + sending from subdomain | No | No (subdomain mismatch) |
Recommended DMARC record
_dmarc.captaindns.com TXT "v=DMARC1;p=reject;adkim=r;aspf=r;rua=mailto:dmarc@captaindns.com"
Key points:
adkim=randaspf=r: relaxed alignment (allows subdomains)- Progress from
p=none→p=quarantine→p=reject - Monitor
ruareports before tightening - Mailgun advantage: native double alignment (SPF + DKIM), better protection than with DKIM alone
Complete DNS summary table
| Type | Host/Name | Value | Required | Notes |
|---|---|---|---|---|
| TXT | mail.captaindns.com | v=spf1 include:mailgun.org ~all | ✅ Yes | SPF identical US/EU |
| CNAME | pdk1._domainkey.mail.captaindns.com | pdk1._domainkey.XXXX.dkim1.mailgun.com | ✅ Yes | DKIM auto rotation |
| CNAME | pdk2._domainkey.mail.captaindns.com | pdk2._domainkey.XXXX.dkim1.mailgun.com | ✅ Yes | DKIM auto rotation |
| MX | mail.captaindns.com | mxa.mailgun.org (priority 10) | ✅ Yes | Bounces/Inbound |
| MX | mail.captaindns.com | mxb.mailgun.org (priority 10) | ✅ Yes | Bounces/Inbound |
| TXT | _dmarc.captaindns.com | v=DMARC1;p=reject;adkim=r;aspf=r;... | Recommended | DMARC policy |
| CNAME | email.mail.captaindns.com | mailgun.org or eu.mailgun.org | Optional | Tracking domain |
Dedicated IP vs shared IP: deliverability strategy
Mailgun officially recommends a dedicated IP from 1 million emails per month. Below that, shared IP generally offers better deliverability.
Shared IP (Free, Foundation, base Growth plans)
Advantages:
- No warm-up required
- Reputation maintained by Mailgun
- Ideal for low or irregular volumes
- Better initial deliverability than on cold dedicated IP
Disadvantages:
- Exposure to reputation risks related to other senders in the pool (rare at Mailgun thanks to strict controls)
Dedicated IP (Foundation 100k+, Growth, Scale, Enterprise)
The Foundation 100k plan includes 1 dedicated IP (from $75/month). Each additional IP costs $59/IP/month.
Official recommendation: 1 dedicated IP for approximately 1 million emails per month minimum.
Advantages:
- Isolated and controllable reputation
- Automatic IP Warmup function over 15 steps (~15+ days)
- Ability to separate flows (transactional vs marketing) via IP Pools
Automatic IP Warmup: Mailgun offers a 15-step progressive warm-up:
| Step | Daily limit | Hourly limit | Duration |
|---|---|---|---|
| 1 | 1,000 | 100 | 24h |
| 2 | 2,500 | ~100 | 24h |
| 3 | 5,000 | Progressive | 24h |
| ... | Progressive | Progressive | ... |
| 15 | Full capacity | Unlimited | Reached D15+ |
The system advances one step every 24 hours if limits are reached. Excess traffic is automatically routed to shared IPs or other available dedicated IPs.
IP Pools: Available on Scale and higher plans. Allow to:
- Separate transactional vs marketing emails
- Different clients/brands (multi-tenant)
- Dynamic IP Pools: automatic assignment based on reputation health
Important note: Dedicated IPs are region-bound (US or EU). A region migration requires a new IP and a new warm-up.
When to choose a dedicated IP?
You need a dedicated IP if:
- Regular volume > 1 million emails/month
- Need to separate transactional vs marketing reputation
- Client whitelisting requirements or regulatory compliance
- Volume > 2.5 million emails/month: multiple dedicated IPs recommended
Stay on shared IP if:
- Volume < 1 million emails/month
- Irregular or sporadic sending
- Starting business without history
- Purely transactional low volume
2026 pricing and recent evolution
Send plans (January 2026)
| Plan | Price/month | Emails included | Overage (/1000) | Log retention | Dedicated IP |
|---|---|---|---|---|---|
| Free | $0 | 100/day | N/A | 1 day | No |
| Flex | Pay-per-use | 1,000 free/month | $2.00 ⚠️ | 5 days | No |
| Foundation 50k | $35 | 50,000 | ~$1.30 | 5 days | No |
| Foundation 100k | $75 | 100,000 | ~$1.30 | 5 days | 1 included |
| Growth | $80-650 | 100k-1M | Variable | 15 days | 1 included |
| Scale 100k | $90 | 100,000 | ~$0.80-1.10 | 30 days | 1 included |
| Scale (max) | $1,250 | 2.5M | Variable | 30 days | 1 included |
| Enterprise | Quote | 2.5M+ | Negotiated | 30 days | Multiple |
Recent pricing evolution
⚠️ Major change (December 1, 2025): The Flex plan went from $1.00 to $2.00 per 1,000 emails - a 100% increase. This significant hike makes Foundation plans much more attractive for volumes > 25,000 emails/month.
Economic analysis:
- Flex plan: 50,000 emails = 49,000 paid × $0.002 = $98
- Foundation 50k plan: 50,000 emails = $35 (saving $63)
- Break-even point: the Foundation plan becomes profitable from ~18,000 emails/month
Optimize plans (deliverability tools)
| Plan | Price/month | Validations | Inbox tests | Previews |
|---|---|---|---|---|
| Pilot | $49 | 2,500 | 25 | 500 |
| Starter | $99 | 5,000 | 50 | 1,000 |
| Contract | Quote | Custom | Custom | Custom |
Annual discounts
Not publicly documented. Enterprise customers report negotiable discounts of 10%+.
US vs EU pricing
Pricing is standardized globally in USD. No documented regional difference between US and EU.
Technical limits and quotas
| Limit | Value | Notes |
|---|---|---|
| Max email size | 25 MB | Body + attachments + headers |
| Recipients/message | 1,000 | To + Cc + Bcc combined |
| Send options parameters | 16 KB | Parameters o:, h:, v:, t: |
| Templates/domain | 100 | Strict limit |
| Versions/template | 10 | - |
| Domains (Free) | 5 | - |
| Domains (paid) | 1,000 | - |
| Sandbox recipients | 5 | Must be verified |
| Domains API rate limit | 300 req/min | Only documented endpoint |
| Send rate limit (new accounts) | 100 messages/hour | Before business verification |
| Scheduling max | 3 days | 7 days if plan with 7d+ storage |
Data retention
| Data | Retention |
|---|---|
| Event logs (Free) | 1 day |
| Event logs (Foundation) | 5 days |
| Event logs (Growth) | 15 days |
| Event logs (Scale) | 30 days (max) |
| Message content | 1-7 days (configurable) |
| Hourly stats | 60 days |
| Daily stats | 1 year |
| Monthly stats | Indefinite |
| Critical security logs | 365 days |
Bounce and suppression management
Hard bounce (permanent failure)
| Behavior | Detail |
|---|---|
| Action | Address added to suppression list |
| Block duration | Indefinite (until manual removal) |
| Error returned | "Not delivering to previously bounced address" |
Soft bounce (temporary failure)
| Behavior | Detail |
|---|---|
| Retry | Automatic for immediate soft bounces |
| Duration | Until success or permanent classification |
| Conversion | After multiple failures, added to bounce list |
Spam complaints (FBL)
Mailgun automatically subscribes to Feedback Loops of major ISPs. Complaints trigger:
- Automatic addition to Complaints list
complainedwebhook sent- Blocking of future sends to this address
Supported ISPs: Yahoo, Microsoft/Outlook, Comcast, Cox, Fastmail, and others via Universal Feedback Loop. Note: Gmail doesn't provide traditional FBL.
Automatic unsubscribe
Mailgun automatically adds:
List-UnsubscribeheaderList-Unsubscribe-Post: List-Unsubscribe=One-Clickheader
RFC 8058 compliant and meets Gmail/Yahoo requirements for bulk senders (5000+ messages/day).
Suppression lists API
| List | Endpoint |
|---|---|
| Bounces | GET/POST/DELETE /v3/{domain}/bounces |
| Complaints | GET/POST/DELETE /v3/{domain}/complaints |
| Unsubscribes | GET/POST/DELETE /v3/{domain}/unsubscribes |
| Allowlist | GET/POST/DELETE /v3/{domain}/allowlist |
The Allowlist prevents addresses from being added to the bounces list but does not override Complaints or Unsubscribes.
Event Webhook and real-time tracking
The event webhook allows real-time notifications of delivery, engagement and compliance.
Available events
- Delivery:
accepted,delivered,temporary_fail,permanent_fail - Engagement:
opened,clicked - Compliance:
complained,unsubscribed
JSON payload format
{
"signature": {
"timestamp": "1529006854",
"token": "a8ce0edb2dd8301dee6c2405235584e45aa91d1e9f979f3de0",
"signature": "d2271d12299f6592d9d44cd9d250f0704e4674c30d79d07c47a66f95ce71cf55"
},
"event-data": {
"event": "delivered",
"timestamp": 1529006854.329574,
"id": "DACSsAdVSeGpLid7TN03WA",
"recipient": "recipient@captaindns.com",
"tags": [],
"message": {
"headers": {
"message-id": "20180618211821.captaindns.com"
}
}
}
}
Retry policy
| Response code | Action |
|---|---|
| 200 | Success, no retry |
| 406 | Rejected, no retry |
| Other | Retry according to schedule |
Retry schedule: 5min → 10min → 15min → 1h → 2h → 4h (total: 8 hours)
Security (HMAC signature)
| Element | Value |
|---|---|
| Algorithm | HMAC-SHA256 |
| Key | Webhook Signing Key (Control Panel → Account Security) |
| Calculation | HMAC-SHA256(timestamp + token, signingKey) |
Python example:
import hmac, hashlib
def verify(api_key, token, timestamp, signature):
expected = hmac.new(api_key.encode(), f"{timestamp}{token}".encode(),
hashlib.sha256).hexdigest()
return signature == expected
Configuration
- Up to 3 URLs per event type per domain
- Configuration at domain level (not account)
- API:
POST /v3/domains/{domain}/webhooks
Handlebars templates
Mailgun uses Handlebars (custom version) for stored templates.
Variable syntax
| Context | Syntax |
|---|---|
| Stored templates | {{variable}} |
| Inline batch sending (API) | %recipient.variable% |
Conditions and loops
{{#if condition}}
Content if true
{{else if otherCondition}}
Alternative content
{{else}}
Default content
{{/if}}
{{#unless condition}}
Content if false
{{/unless}}
{{#equal variable "value"}}
Content if equal
{{/equal}}
{{#each array}}
<li>{{this.property}}</li>
{{/each}}
{{#with object}}
{{nestedProperty}}
{{/with}}
Template limits
| Limit | Value |
|---|---|
| Templates per domain | 100 |
| Versions per template | 10 |
| Template size | Undocumented |
| Partials (import) | Not supported |
Additional features
Email Validation API
| Attribute | Value |
|---|---|
| Single endpoint | GET /v4/address/validate?address=... |
| Bulk endpoint | POST /v4/address/validate/bulk/{list_id} |
| Database | 450+ billion emails |
| Foundation rate | $1.20/100 validations |
| Scale rate | 5,000 included, then $0.80/100 |
Validations performed: RFC syntax, MX records, mailbox existence, Mailgun network bounces, risky addresses, role-based addresses, disposable emails, domain typos, catch-all domains.
Inbound Parse (Routes)
Allows receiving emails and forwarding them to a webhook URL:
Filters: match_recipient(), match_header(), catch_all()
Actions: forward("https://url"), forward("email@"), store(), stop()
Inbound retry: up to 8 hours (10min, 15min, 30min, 1h, 2h, 4h) Stored message retention: 3 days
Attachments
| Limit | Value |
|---|---|
| Total message size | 25 MB (body + attachments + headers) |
| File types | No documented restriction |
| Inline (CID) | Supported via inline parameter |
AMP for Email
Supported since 2019 via the amp-html parameter. Requires:
- Registration as AMP sender with Google
- SPF, DKIM, DMARC configured
- Mandatory HTML fallback
Security and compliance
Certifications
| Certification | Status |
|---|---|
| ISO 27001 | ✅ Certified |
| ISO 27701 | ✅ Certified (privacy) |
| SOC 2 Type I | ✅ Certified |
| SOC 2 Type II | ✅ Certified |
| SOC 1 (SSAE-16) | ✅ Certified |
| PCI-DSS | ✅ Compliant (SAQ-A) |
| CSA Star Level 1 | ✅ Compliant |
GDPR
| Element | Detail |
|---|---|
| DPA | Available: mailgun.com/legal/dpa/ |
| EU data location | Germany |
| EU endpoints | api.eu.mailgun.net, smtp.eu.mailgun.org |
| Data residency | Messages never transferred outside region |
| DPO | Dedicated, EU-based |
HIPAA
| Element | Detail |
|---|---|
| Status | ✅ Compliant |
| BAA | Available: mailgun.com/legal/hipaa-baa/ |
| Prerequisites | Client-side encryption configuration, patient consent, signed BAA |
TLS encryption
| Version | Status |
|---|---|
| TLS 1.0 | ❌ Deprecated (March 2021) |
| TLS 1.1 | ❌ Deprecated (March 2021) |
| TLS 1.2 | ✅ Supported |
| TLS 1.3 | ✅ Supported |
Encryption at rest: AES-256
Advanced authentication
| Feature | Availability |
|---|---|
| 2FA | ✅ All plans |
| SSO | ✅ Scale and Enterprise |
| SAML 2.0 | ✅ Scale and Enterprise |
| Supported IdP | Okta, Auth0, OneLogin, Azure AD, ADFS, AWS IAM |
| RBAC | ✅ Scale and Enterprise (Admin, Developer, Analyst, Support) |
Action plan: 6-step configuration
1. Create account and configure domain
- Create a Mailgun account at mailgun.com/signup
- Choose region (US or EU according to your GDPR needs)
- A sandbox domain is automatically created (100 emails/day)
2. Verify domain (Domain Verification)
- Go to Sending > Domains > Add New Domain
- Enter your sending domain (e.g.,
mail.captaindns.com) - Enable Automatic Sender Security (recommended)
- Create DNS records at your registrar:
- SPF TXT:
v=spf1 include:mailgun.org ~all - DKIM CNAME pdk1:
pdk1._domainkey.mail.captaindns.com - DKIM CNAME pdk2:
pdk2._domainkey.mail.captaindns.com - MX mxa:
mxa.mailgun.org(priority 10) - MX mxb:
mxb.mailgun.org(priority 10)
- SPF TXT:
- Verify DNS propagation (24-48h)
3. Publish DMARC record
Create the DMARC record on your main domain:
_dmarc.captaindns.com TXT "v=DMARC1;p=none;rua=mailto:dmarc@captaindns.com;aspf=r;adkim=r"
Start with p=none for monitoring, then move to p=quarantine then p=reject once reports are validated.
4. Choose and configure sending method
Option A: REST API
- Generate an API key in Settings > API Keys
- Choose permissions (Full Access or Domain sending keys for limited scope)
- Implement the
POST /v3/{domain}/messagesendpoint - Create templates in Sending > Templates if needed
Option B: SMTP Relay
- Get the domain SMTP password in Sending > Domains > Domain settings > SMTP credentials
- Configure your app/plugin/mail server:
- Host:
smtp.mailgun.org(US) orsmtp.eu.mailgun.org(EU) - Port:
587(STARTTLS recommended) - User:
postmaster@mail.captaindns.com - Password: the domain SMTP password
- Host:
5. Configure webhooks
- Go to Sending > Webhooks
- Define your endpoint URL (HTTPS recommended)
- Select events (delivered, bounced, opened, clicked, etc.)
- Get the Webhook Signing Key to validate HMAC signatures
6. Test and monitor
- Send a test email via API or SMTP
- Verify in Sending > Logs that the email is delivered
- Check webhook events on your endpoint
- Monitor statistics (deliverability, open rate, bounce rate)
- To go into production, exit sandbox mode by contacting Mailgun support (business verification)
Guias tecnicas: otras plataformas de email transaccional
Descubre nuestras guias completas para otras soluciones de email transaccional:
- Postmark: configuracion DKIM y API REST - Especialista en entregabilidad, DKIM 1024 bits, Message Streams
- SendGrid: autenticacion de dominio y Web API v3 - DKIM 2048 bits con rotacion, IP dedicada desde 50k/mes
- Amazon SES: Easy DKIM y Custom MAIL FROM - $0.10/1000 emails, 7 regiones EU
- Mailjet: API v3.1 y configuracion DKIM - DKIM 2048/4096 bits, adquisicion Sinch
- Mandrill: integracion Mailchimp transaccional - Requisito Mailchimp Standard, bloques de 25k emails
- Brevo: configuracion DKIM y SPF - 300 emails/dia gratis, DKIM TXT o CNAME
FAQ
What's the difference between primary API key and Domain Sending Keys?
The primary API key (Primary Account API Key) gives full CRUD access to all account APIs. Domain Sending Keys are limited to sending only (POST /messages) for a specific domain. Use Domain Sending Keys in your apps to limit the attack surface in case of compromise.
Why does Mailgun generate two DKIM selectors (pdk1 and pdk2)?
The two selectors allow automatic DKIM key rotation every 120 days without service interruption. When Mailgun wants to renew keys for security reasons, it generates a new key on pdk2 while pdk1 is still active, then progressively switches traffic. This avoids any deliverability interruption during key change.
Do I need to configure a Custom MAIL FROM like with Amazon SES?
No, unlike Amazon SES which requires Custom MAIL FROM for SPF alignment, Mailgun automatically uses your verified domain in the Return-Path (bounce+id@mail.captaindns.com). SPF DMARC alignment works natively from domain configuration, without separate setup.
How does test mode work without consuming credits?
Use the o:testmode=yes parameter (API) or the X-Mailgun-Drop-Message: yes header (SMTP). Messages are accepted but not delivered, generating a delivered event with code 650. Ideal for testing request structure and payload format without actually sending emails.
What's the real limit of recipients per API call?
1,000 recipients maximum per call (to + cc + bcc combined). Beyond that, split into multiple calls. To send to 10,000 people, you need 10 API calls. Use recipient variables to personalize each recipient's content in the same batch.
Is the Flex plan suitable for production at variable volume?
Since the rate doubling ($2.00/1000 emails in December 2025), the Flex plan has become less competitive. For more than 18,000 emails/month, the Foundation 50k plan ($35/month) is more cost-effective. Flex remains interesting for very low and irregular volumes (< 10,000/month) or to test before committing.
Should I get a dedicated IP for my project?
Probably not. A dedicated IP requires a minimum volume of 1 million emails per month, with regular sending. It requires a 15+ day warm-up and costs $59/IP/month additional (or included from Foundation 100k). If your volume is lower or if your sending is irregular, stay on shared IP. Mailgun's reputation on shared IP is excellent.
Are API rate limits documented?
No, Mailgun doesn't publicly document specific rate limits per endpoint, except for the Domains API (300 req/min). New accounts may be limited to 100 messages/hour before business verification. The X-RateLimit-* headers in responses indicate your real-time quota. In case of 429, implement exponential backoff.
Glossary
-
REST API: Mailgun's HTTP API for sending transactional emails. Main endpoint:
POST /v3/{domain}/messages. Authentication: HTTP Basic Auth (api:YOUR_API_KEY). Recommended method for any new integration. -
SMTP Relay: Mailgun's SMTP server (
smtp.mailgun.org) allowing sending via standard SMTP protocol. Authentication: SASL/PLAIN (postmaster@ + SMTP password). Available ports: 587 (STARTTLS), 465 (direct TLS), 2525 (GCE fallback). -
Domain Verification: DNS configuration to authenticate your domain with Mailgun. Generates SPF, DKIM, MX records. With Automatic Sender Security: 2 DKIM CNAMEs (pdk1 and pdk2) for automatic rotation every 120 days, 2048-bit keys by default.
-
Return-Path (Envelope From): Technical address used for SMTP routing and bounces. Mailgun automatically uses your domain (
bounce+id@mail.captaindns.com), enabling relaxed SPF alignment for DMARC without separate configuration. Major difference with SendGrid (subdomainem1234) and Amazon SES (Custom MAIL FROM required). -
Automatic Sender Security: Recommended option for Domain Verification. Generates 2 DKIM CNAMEs instead of TXT, enables automatic DKIM key rotation every 120 days, and uses 2048-bit keys by default.
-
Recipient Variables: Mechanism to personalize each recipient's content in a batch send. Syntax:
%recipient.variable%in the message, with a JSON mapping each email to its variables. Allows sending up to 1,000 personalized versions in a single API call. -
IP Warmup: Automatic ramp-up process for a new dedicated IP. Schedule over 15 steps: from 1,000 emails/day (D1) to full capacity (D15+). The system advances one step every 24h if limits are reached. Excess traffic is routed to shared IPs.
-
IP Pools: Groups of dedicated IPs assignable to different flows (transactional vs marketing, per client, per brand). Available on Scale and Enterprise plans. Allow separating reputation. Dynamic IP Pools: automatic assignment based on reputation health.
-
Event Webhook: HTTP endpoint called by Mailgun on events (accepted, delivered, opened, clicked, bounced, complained, unsubscribed). Configuration: up to 3 URLs per event type. Retry for 8h on failure. Security: HMAC-SHA256 signature.
-
Handlebars: Templating language used by Mailgun for stored templates. Supports variables
{{variable}}, conditions{{#if}}, loops{{#each}}, helpers{{#equal}}. Limit: 100 templates per domain, 10 versions per template. No partials support. -
Sandbox Mode: Test mode that validates request format without actually sending email. Activate via
o:testmode=yes(API) orX-Mailgun-Drop-Message: yes(SMTP). Generates adeliveredevent with code 650. Doesn't consume credits. Limit: 5 verified recipients. -
Suppressions: Blocking lists automatically maintained by Mailgun (Bounces, Complaints, Unsubscribes). Addresses are suppressed indefinitely by default. Management via API:
GET/POST/DELETE /v3/{domain}/{bounces|complaints|unsubscribes}. Allowlist: prevents addition to Bounces but doesn't override Complaints/Unsubscribes. -
Domain Sending Keys: API keys limited to sending only (POST /messages) for a specific domain. Unlike the primary API key (full CRUD access), they reduce the attack surface. Recommended for production apps.
-
RBAC API Keys (Scale+): API keys with predefined roles: Admin (full read/write), Developer (full technical access), Analyst (metrics read-only), Support (read + suppression management). Available on Scale and Enterprise plans only.


