A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.
The Mailgun API is how an app or AI agent works with an email-sending account: sending messages to recipients, managing sending domains and mailing lists, querying delivery and engagement events, and maintaining the bounce, unsubscribe, and complaint lists. Access is granted through an API key sent as Basic Auth, and a role-based or domain-restricted key limits what that key can reach. Mailgun can also push delivery events to a registered webhook URL when a message is delivered, opened, clicked, or fails.
How an app or AI agent connects to Mailgun determines what it can reach. There is a route for making calls and a route for receiving events, and each is governed by the API key behind it and the role that key carries.
The REST API answers at https://api.mailgun.net for the US region and https://api.eu.mailgun.net for the EU region. Each endpoint carries its own version segment in the path, mostly v3 with newer areas on v4 and v1.
Webhooks deliver delivery and engagement events to a registered HTTPS endpoint, and each payload is signed so the receiver can confirm it came from Mailgun. They are configured per domain and per event type, with account-level webhooks fanning out across all domains.
Mailgun publishes an open-source MCP server that lets an agent call Mailgun through the Model Context Protocol, covering messaging, domains, webhooks, routes, mailing lists, templates, and analytics. It runs locally from the source at github.com/mailgun/mailgun-mcp-server, takes the API key as an environment variable, and there is no hosted version.
A primary account API key authenticates over HTTP Basic Auth, with the literal username 'api' and the key as the password, and reaches all create, read, update, and delete operations across the account's domains.
A role-based key is created with one of four roles that fix its access: Admin for full administrative access, Developer for the technical sending and integration endpoints, Analyst for read-only data and metrics, and Support for read access plus write on specific management endpoints. The role cannot be changed after creation.
A Domain Sending Key is restricted to posting messages for a single domain, reaching only the messages and messages.mime endpoints, so it cannot read data or change configuration.
The Mailgun API is split into areas an agent can act on, like sending mail, managing domains, mailing lists and members, stored templates, delivery events, suppression lists, inbound routes, and webhooks. Each area has its own methods, and a write in some areas sends real email or removes a sending domain.
Send email from standard fields or a built MIME string, retrieve and resend a stored message, and clear the scheduled queue.
List, read, create, and update sending domains, verify their DNS records, and delete a domain.
List, create, read, update, and delete mailing lists, and manage the members on each list.
List, create, read, update, and delete stored templates, and manage their versions.
Query the log of inbound and outbound message events for a domain.
Read and manage the bounce, unsubscribe, and complaint lists that stop Mailgun sending to an address.
List, create, read, update, and delete the routes that handle incoming email.
List, create, read, update, and delete the webhooks that receive a domain's delivery events.
Query filtered sending and usage metrics for an account.
List, create, and delete the API keys an account uses to authenticate.
Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.
| Method | Endpoint | What it does | Access | Permission | Version | |
|---|---|---|---|---|---|---|
MessagesSend email from standard fields or a built MIME string, retrieve and resend a stored message, and clear the scheduled queue.5 | ||||||
| POST | /v3/{domain_name}/messages | Send an email by passing its components: To, From, Subject, HTML and text parts, attachments, and options. | write | Developer | Current | |
A Domain Sending Key restricts a key to this and the MIME endpoint for a single domain. With role-based keys, sending needs the Developer role; Analyst and Support are read-only for this. Acts onmessage Permission (capability) DeveloperVersionAvailable since the API’s base version Webhook event deliveredRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v3/{domain_name}/messages.mime | Send an email by submitting a MIME string built with a MIME library. | write | Developer | Current | |
A Domain Sending Key also covers this endpoint. Role-based keys need the Developer role. Acts onmessage Permission (capability) DeveloperVersionAvailable since the API’s base version Webhook event deliveredRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v3/domains/{domain_name}/messages/{storage_key} | Retrieve a stored message using the storage key from its event. | read | Analyst | Current | |
Stored messages are kept for about 3 days. Any read-capable role can fetch one. Acts onmessage Permission (capability) AnalystVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v3/domains/{domain_name}/messages/{storage_key} | Resend a previously stored message. | write | Developer | Current | |
Resending counts as sending, so the Developer role is needed. Acts onmessage Permission (capability) DeveloperVersionAvailable since the API’s base version Webhook event deliveredRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v3/{domain_name}/envelopes | Delete all scheduled and undelivered mail from the domain queue. | write | Developer | Current | |
This clears queued mail for the whole domain at once. Acts onmessage Permission (capability) DeveloperVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
DomainsList, read, create, and update sending domains, verify their DNS records, and delete a domain.6 | ||||||
| GET | /v4/domains | List the account's domains, filterable by state or authority. | read | Analyst | Current | |
This area sits on v4. Any read-capable role can list domains. Acts ondomain Permission (capability) AnalystVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v4/domains/{name} | Get a domain's state and settings. | read | Analyst | Current | |
Returns DNS and tracking configuration for the domain. Acts ondomain Permission (capability) AnalystVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v4/domains | Create a sending domain. | write | Developer | Current | |
As of 9 May 2025 the smtp_login field is no longer returned on creation; SMTP credentials are made through the Credentials endpoint. Acts ondomain Permission (capability) DeveloperVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /v4/domains/{name} | Update a domain's configuration, such as SMTP credentials, sender security, spam actions, wildcard, or tracking scheme. | write | Developer | Current | |
Changes sending and tracking behaviour for the domain. Acts ondomain Permission (capability) DeveloperVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /v4/domains/{name}/verify | Verify a domain's DNS records, including A, CNAME, SPF, DKIM, and MX. | write | Developer | Current | |
Confirms a domain is ready to send by re-checking its DNS. Acts ondomain Permission (capability) DeveloperVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v3/domains/{name} | Delete a domain. The domain must not be disabled or act as the authority for another domain. | write | Admin | Current | |
Deletion sits on v3 while the rest of the domains area is v4. Removing a domain stops it sending. Acts ondomain Permission (capability) AdminVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Mailing lists & membersList, create, read, update, and delete mailing lists, and manage the members on each list.7 | ||||||
| GET | /v3/lists/pages | Page through the account's mailing lists. | read | Analyst | Current | |
Any read-capable role can list mailing lists. Acts onmailing list Permission (capability) AnalystVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v3/lists | Create a mailing list. | write | Developer | Current | |
A mailing list is addressed by an email alias that fans out to its members. Acts onmailing list Permission (capability) DeveloperVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v3/lists/{address} | Get a mailing list by its address. | read | Analyst | Current | |
Returns the list's settings and member count. Acts onmailing list Permission (capability) AnalystVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v3/lists/{address} | Delete a mailing list. | write | Developer | Current | |
Removes the list and its membership. Acts onmailing list Permission (capability) DeveloperVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v3/lists/{list_address}/members/pages | Page through the members of a mailing list. | read | Analyst | Current | |
Returns recipient email addresses and their stored variables. Acts onlist member Permission (capability) AnalystVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v3/lists/{list_address}/members | Add a member to a mailing list. | write | Developer | Current | |
Bulk variants accept JSON or CSV at members.json and members.csv. Acts onlist member Permission (capability) DeveloperVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v3/lists/{list_address}/members/{member_address} | Remove a member from a mailing list. | write | Developer | Current | |
Takes the member off the list without affecting suppression lists. Acts onlist member Permission (capability) DeveloperVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
TemplatesList, create, read, update, and delete stored templates, and manage their versions.5 | ||||||
| GET | /v4/templates | List the account's stored templates. | read | Analyst | Current | |
Account-level templates sit on v4; a domain-scoped set sits on v3 under the domain path. Acts ontemplate Permission (capability) AnalystVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v4/templates | Create an account template. | write | Developer | Current | |
A template can be referenced by name when sending. Acts ontemplate Permission (capability) DeveloperVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v4/templates/{template_name} | Get a stored template by name. | read | Analyst | Current | |
Returns the template and, on request, its versions. Acts ontemplate Permission (capability) AnalystVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v4/templates/{template_name}/versions | Add a new version to an account template. | write | Developer | Current | |
Versions let a template change without breaking existing sends. Acts ontemplate version Permission (capability) DeveloperVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v4/templates/{template_name} | Delete a stored template. | write | Developer | Current | |
Removes the template and all its versions. Acts ontemplate Permission (capability) DeveloperVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
EventsQuery the log of inbound and outbound message events for a domain.1 | ||||||
| GET | /v3/{domain_name}/events | Query a paginated list of inbound and outbound message events for a domain. | read | Analyst | Current | |
Events are kept for at least 3 days. Mailgun directs new work to the Logs API for fuller event tracking. Acts onevent Permission (capability) AnalystVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
SuppressionsRead and manage the bounce, unsubscribe, and complaint lists that stop Mailgun sending to an address.5 | ||||||
| GET | /v3/{domain_name}/bounces | Page through the bounce list for a domain. | read | Analyst | Current | |
The bounce list holds addresses with permanent delivery failures, like a non-existent mailbox. Acts onbounce Permission (capability) AnalystVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v3/{domain_name}/bounces/{address} | Remove a single address from the bounce list. | write | Developer | Current | |
Removing an address lets Mailgun attempt delivery to it again. Acts onbounce Permission (capability) DeveloperVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v3/{domain_name}/unsubscribes | Page through the unsubscribe list for a domain. | read | Analyst | Current | |
Holds addresses that clicked a Mailgun unsubscribe link. Acts onunsubscribe Permission (capability) AnalystVersionAvailable since the API’s base version Webhook event unsubscribedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v3/{domain_name}/unsubscribes | Add one or more addresses to the unsubscribe list. | write | Developer | Current | |
Accepts up to 1,000 records per request. Acts onunsubscribe Permission (capability) DeveloperVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v3/{domain_name}/complaints | Page through the complaint list for a domain. | read | Analyst | Current | |
Holds addresses that marked a message as spam. Acts oncomplaint Permission (capability) AnalystVersionAvailable since the API’s base version Webhook event complainedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
RoutesList, create, read, update, and delete the routes that handle incoming email.4 | ||||||
| GET | /v3/routes | List the account's inbound routes. | read | Analyst | Current | |
Routes match incoming mail and decide what happens to it. Acts onroute Permission (capability) AnalystVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v3/routes | Create an inbound route. | write | Developer | Current | |
A route can forward matching mail to a URL or address, or store it for about 3 days. Acts onroute Permission (capability) DeveloperVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /v3/routes/{id} | Update an inbound route. | write | Developer | Current | |
Changes the route's match expression or actions. Acts onroute Permission (capability) DeveloperVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v3/routes/{id} | Delete an inbound route. | write | Developer | Current | |
Stops the route from handling further inbound mail. Acts onroute Permission (capability) DeveloperVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
WebhooksList, create, read, update, and delete the webhooks that receive a domain's delivery events.4 | ||||||
| GET | /v3/domains/{domain}/webhooks | List the webhooks configured for a domain. | read | Analyst | Current | |
Webhooks are keyed by event type for a domain. Acts onwebhook Permission (capability) AnalystVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v4/domains/{domain}/webhooks | Create a webhook for a domain. | write | Developer | Current | |
Creation sits on v4; single-webhook reads and updates sit on v3. URLs are deduplicated by event type across account and domain levels. Acts onwebhook Permission (capability) DeveloperVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /v3/domains/{domain_name}/webhooks/{webhook_name} | Update a domain webhook by event name. | write | Developer | Current | |
Changes the receiver URL for an event type. A v4 batch update also exists. Acts onwebhook Permission (capability) DeveloperVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v3/domains/{domain_name}/webhooks/{webhook_name} | Delete a domain webhook by event name. | write | Developer | Current | |
Stops events of that type being delivered to the URL. Acts onwebhook Permission (capability) DeveloperVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Metrics & analyticsQuery filtered sending and usage metrics for an account.2 | ||||||
| POST | /v1/analytics/metrics | Query filtered sending metrics for an account. | read | Analyst | Current | |
Analytics sits on v1. The query is sent in the request body, so this read uses POST. Acts onmetric Permission (capability) AnalystVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v1/analytics/usage/metrics | Query filtered usage metrics for an account. | read | Analyst | Current | |
Returns account usage rather than per-message delivery data. Acts onmetric Permission (capability) AnalystVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
API keysList, create, and delete the API keys an account uses to authenticate.3 | ||||||
| GET | /v1/keys | List the account's API keys. | read | Admin | Current | |
Key management sits on v1 and is an administrative area. Acts onapi key Permission (capability) AdminVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v1/keys | Create an API key with a chosen role. | write | Admin | Current | |
A role-based key takes one of Admin, Analyst, Developer, or Support, and its role cannot be changed after creation. The key value is shown once and cannot be retrieved later. Acts onapi key Permission (capability) AdminVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v1/keys/{key-id} | Delete an API key. | write | Admin | Current | |
Revoking a key immediately stops it authenticating. Acts onapi key Permission (capability) AdminVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Mailgun can notify an app when something happens to a message it sent, like the message being delivered, opened, clicked, or failing to deliver. It posts a signed payload to a registered HTTPS endpoint, so an integration learns about delivery and engagement without polling.
| Event | What it signals | Triggered by |
|---|---|---|
delivered | Fires when Mailgun successfully delivers a message to the recipient's mail server. | /v3/{domain_name}/messages/v3/{domain_name}/messages.mime/v3/domains/{domain_name}/messages/{storage_key} |
permanent_fail / temporary_fail | Fires when a message fails to deliver, either permanently, like a non-existent mailbox, or temporarily before a retry. | /v3/{domain_name}/messages/v3/{domain_name}/messages.mime |
opened | Fires when a recipient opens a message, where open tracking is enabled for the domain. | /v3/{domain_name}/messages/v3/{domain_name}/messages.mime |
clicked | Fires when a recipient clicks a tracked link in a message, where click tracking is enabled. | /v3/{domain_name}/messages/v3/{domain_name}/messages.mime |
unsubscribed | Fires when a recipient clicks a Mailgun unsubscribe link, which also adds them to the unsubscribe list. | /v3/{domain_name}/messages/v3/{domain_name}/messages.mime |
complained | Fires when a recipient marks a message as spam, which also adds them to the complaint list. | /v3/{domain_name}/messages/v3/{domain_name}/messages.mime |
Mailgun limits how fast an app can call, and returns the remaining quota on each response through rate-limit headers so an integration can pace itself. Sending volume is also capped per account and can be raised with Mailgun.
Mailgun rate-limits API calls and reports the state on each response through three headers: X-RateLimit-Limit for the total calls allowed in the current window, X-RateLimit-Remaining for the calls left, and X-RateLimit-Reset for the Unix time when the window resets. The window can vary by API depending on resource usage, and exceeding a limit returns 429. Separately, an account has a sending volume cap, which can be raised by contacting Mailgun. The exact numeric ceilings are not published in the reference, so an integration should read the headers rather than assume a fixed figure.
List endpoints return paging links in the response, and a request can set a limit on how many records come back per page. An integration should follow the next and previous paging URLs Mailgun returns rather than building them by hand. Events are kept for at least 3 days, so a query reaches back over that window.
The maximum message size, including all attachments, headers, and body, is 25MB. Batch sending with recipient variables allows at most 1,000 recipients per request, and the bounce, unsubscribe, and complaint endpoints accept up to 1,000 records per call, with CSV imports up to 25MB.
The status codes an agent should handle, and what to do about each.
| Status | Code | Meaning | What to do |
|---|---|---|---|
| 400 | Bad Request | The request was malformed or missing a required parameter. The response body carries a JSON message key with a human-readable explanation. | Read the message field, correct the named parameter, and resend. |
| 401 | Unauthorized | Authentication failed. The API key is missing, wrong, or not formatted correctly in the Authorization header. | Check the key and that it is sent as HTTP Basic Auth with the username 'api'. |
| 402 | Request Failed | The parameters were valid but the request failed, often a sending or account restriction. | Resolve the account or domain restriction named in the response before retrying. |
| 404 | Not Found | The requested resource does not exist, such as a domain, list, or route that is not on the account. | Confirm the path and that the resource exists on the account and region. |
| 429 | Too Many Requests | A rate limit was exceeded. The X-RateLimit-Remaining header reaches 0 and X-RateLimit-Reset gives the reset time. | Wait until the X-RateLimit-Reset time, then retry. |
| 500 | Server Error | Something went wrong on Mailgun's side. A 5xx range covers internal errors. | Retry after a short delay, and contact Mailgun if it persists. |
Mailgun versions each endpoint in its path rather than across the whole API, so most methods sit on v3 while newer areas like domains, account templates, and webhook updates sit on v4, and API keys and analytics on v1. Changes ship through the Mailgun release notes.
Mailgun versions each endpoint in its own path segment rather than versioning the whole API at once. Most endpoints sit on v3, the longest-standing version, while newer areas were introduced on v4 (domains, account templates, webhook batch updates) and v1 (API keys, analytics). There is no single dated API version; changes are announced through the Mailgun release notes.
Mailgun added a dedicated Forwards API for configuring inbound email forwarding with wildcard match patterns, purpose-built for recipient-based processing at scale, alongside the existing Routes API.
Account-level webhooks were added, firing on events across all domains and subaccounts, with new domain name and account ID fields in the payload so a single receiver can handle the whole account.
New endpoints let an integration enable or disable automated IP warm-up and check the current warm-up stage, moving a previously manual process under the API.
Creating a domain through the Domains API stopped returning the smtp_login field, because SMTP credentials are no longer generated automatically. Credentials are now made through the Credentials endpoint or in the UI.
Different areas carry different version segments; track the release notes for new endpoints and deprecations.
Mailgun release notes ↗Bollard AI sits between a team's AI agents and Mailgun. Grant each agent exactly the access it needs, read or write, area by area, and every call is checked and logged.