# Mailgun > This section describes our RESTful API for alert configuration for Mailgun Optimize. --- # Source: https://documentation.mailgun.com/docs/inboxready/alerts-ir.md # Alerts This section describes our RESTful API for alert configuration for Mailgun Optimize. ## Events & Channel Our alerting solution is centered around two concepts: Events and Channels. Every configured alert consists of an event type / channel pair. This level of granularity allows alerting to be configured to your exact preference. ### Events The occurrence of an event can be configured to trigger an alert. The current list of events that you can chose to receive alerts for are: - `ip_listed`: A monitored IP has been added to a blocklist. - `ip_delisted`: A monitored IP has been removed from a blocklist. - `validation_job`: A bulk email verification job has completed. - `validation_preview`: A bulk email verification preview job has completed. - `domain_listed`: A monitored domain has been added to a blocklist. - `domain_delisted`: A monitored domain has been removed from a blocklist. ### Channels A channel describes the delivery method for an alert. The current supported delivery channels include emails and webhooks. ## Webhooks This section covers details around consuming Mailgun Optimize deliverability alerts via webhooks. If you are familiar with Mailgun Send webhooks, there is a lot of overlapping similarity, however, there are also a few minor nuances to account for. Securing Webhooks [HMAC](https://en.wikipedia.org/wiki/HMAC) is used to verified to integrity as well as the authenticity of received webhooks. To verify the origin of a webhook: 1. Encode the webhook's entire POST request body with the HMAC algorithm (using your webhook signing key and SHA256 digest mode) 2. Compare the resulting hexdigest to the signature provided in the POST request's `X-Sign` header. Below is a Ruby code example for verifying a webhook signature: ```JSON require"json" require"openssl" defverify(signing\_key,webhook\_payload,signature) data=JSON.generate(webhook\_payload) signature==OpenSSL::HMAC.hexdigest("SHA256",signing\_key,data) end ``` *NOTE: If you're comsuming Mailgun webhooks, please note that your Mailgun webhook signing key differs from your Optimize alerts webhook signing key. Your Optimize alerts webhook signing key is available within the Optimize UI.* ## Webhook URL Validation When adding or updating a webhook URL for alerts, we will ensure the endpoint is reachable by sending a GET request to the provided URL. If a 200 response is not returned from your endpoint, the request will be rejected and your alert setting will not be saved. We intentionally chose to send a GET request instead of a POST when validating URLs so that your webhook endpoint does not have to account for test requests. Additionally, when a POST request is sent to your webhook URL, if a 2xx is not returned, we will attempt retries via an exponential backoff strategy for up to ~8 hours. If the max retry count is reached, the alert will be disabled and the related alert settings record's `disabled_at` field will be populated. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/alerts_mg/alerts-send.md # Send Alerts ## Overview Get instant notifications on the sending metrics that matter most, configured specifically for your unique business needs and assets. Route these alerts to the channels your team relies on. Stay on top of sending performance without the need to manually monitor. Info Alerts are configured by region (Mailgun [US](https://app.mailgun.com/settings/optimize/alerts) or Mailgun [EU](https://app.eu.mailgun.com/settings/optimize/alerts)). Alerts can operate on both regions concurrently, but for each region, you will need to perform the steps configuring notification channels and setting up alerts ### How Send Alerts Work Alerts trigger when the metric break the threshold you set. To keep things simple, we use 1 hour periods to measure your metrics used in alert analysis. The alert will indicate the specific dimension that has broken the alert threshold (e.g. sending domain, IP pool, or subaccount). An alert will trigger once when the threshold is broken. Should the metric go back under threshold and then breach in the next calculated period, another alert will trigger. Alerts are independent for each filter so if an alert is tracking your sending domains and two sending domains breach threshold you will receive two separate alerts indicating the domains that have broken your alert threshold. ## Metrics, Rates, and Filters ### Metrics to Track - Complaint rate - Delivery rate - Hard bounce rate - Temporary fail rate ### Thresholds and Filters Set conditions for the metrics your business cares about. Customize the threshold rate that makes the most sense for your use case and implement up to 10 filters to get really tactical on what you want Mailgun to monitor and alert. To get started easily, our default threshold rates are presented in the UI setup based on feedback from our won deliverability experts. ### Filters - Sending Domains - Dedicated IPs - IP Pools - Subaccounts: Track Primary and all subaccounts, any subaccount, or specific subaccounts. - Mailbox Providers --- # Source: https://documentation.mailgun.com/docs/validate/api-overview.md # Source: https://documentation.mailgun.com/docs/inboxready/api-reference/api-overview.md # Source: https://documentation.mailgun.com/docs/mailgun/api-reference/api-overview.md # API Overview ## Base URL All API calls referenced in our documentation start with a base URL. Mailgun allows the ability to send and receive email in both US and EU regions. Be sure to use the appropriate base URL based on which region you have created for your domain. It is also important to note that Mailgun uses URI versioning for our API endpoints, and some endpoints may have different versions than others. Please reference the version stated in the URL for each endpoint. For domains created in our US region the base URL is: ``` https://api.mailgun.net/ ``` For domains created in our EU region the base URL is: ``` https://api.eu.mailgun.net/ ``` ### Date Format Mailgun returns JSON for all API calls. JSON does not have a built-in date type; dates are passed as strings encoded according to [RFC-2822](https://tools.ietf.org/html/rfc2822.html#page-14). This format is native to JavaScript and is also supported by most programming languages out of the box ```JSON 'Thu, 13 Oct 2011 18:02:00 +0000' ``` Warning! Abbreviated time zones like (EST, CET, IST, HLC) may not result in the correct offset due to ambiguous nature. Use numerical offset (+0500) or GMT/UTC instead. ## API Response Codes All of Mailgun's HTTP response codes follow standard HTTP definitions. | Code | Description | Troubleshooting | | --- | --- | --- | | **400** | Bad Request | Response typically contains a JSON "message" key with human-readable error details | | **401** | Unauthorized | Invalid or missing API key. Check that your API key is correct and properly formatted in the Authorization header | | **403** | Forbidden | Valid credentials but access denied. Ensure you have permissions for the requested resource | | **404** | Not Found | Resource not found. May be temporal due to eventually-consistent system. Missing JSON response usually indicates incorrect endpoint | | **429** | Rate Limited | Rate limits exceeded. Retry as defined in response headers defined below. Contact support if limits need adjustment | | **500** | Internal Error | Mailgun server error. Retry with exponential backoff. Contact support if issue persists | ### Rate Limit Headers Mailgun APIs include the following headers to indicate rate limiting state for the current API being called: | Header | Description | | --- | --- | | **X-RateLimit-Limit** | Total calls that can be made in each time window | | **X-RateLimit-Remaining** | Calls remaining in the given time window | | **X-RateLimit-Reset** | Unix milliseconds (UTC) until the limit resets. Used for back-off logic on a HTTP 429 response | Time windows may vary by API depending on resource usage. ## Mailgun Regions Using a single account and billing plan, you can choose to provision new sending domains in the EU environment. It is important to note that message data never leaves the region in which it is processed. Only a limited amount of account data is replicated globally, giving you a single account from which to manage domains in both the US and the EU. Here are the specifics on the type of data that is replicated globally versus what is region-bound: | **Global** | **Region-Bound (US / EU)** | | --- | --- | | Account Information, User Accounts, Billing Details (invoices/plan information), API Keys, Domain Names | Domain Metadata (e.g., SMTP credentials), Messages, Event Logs, Suppressions, Mailing Lists, Tags, Statistics, Routes, IP Addresses | Below are the endpoints you will use for sending/receiving/tracking messages in the EU: | **Service** | **US Endpoint** | **EU Endpoint** | | --- | --- | --- | | REST API | api.mailgun.net | api.eu.mailgun.net | | Outgoing SMTP Server | smtp.mailgun.org | smtp.eu.mailgun.org | | Inbound SMTP Server (Routes) | mxa.mailgun.org | mxa.eu.mailgun.org | | Inbound SMTP Server (Routes) | mxb.mailgun.org | mxb.eu.mailgun.org | | Open/Click Tracking Endpoint | mailgun.org | eu.mailgun.org | --- # Source: https://documentation.mailgun.com/docs/mailgun/email-best-practices/auth_bestpractice.md # Authentication It is very important that you are using the appropriate authentication methods with your email. If you are not authenticating your email properly, ESPs will assume you are spamming and will filter or just drop your email. The common types of authentication are: - [SPF](http://www.openspf.org) - [DKIM](http://www.dkim.org) - [DomainKeys](http://domainkeys.sourceforge.net) - [SenderID](https://docs.microsoft.com/en-us/exchange/antispam-and-antimalware/antispam-protection/sender-id?view=exchserver-2019) Mailgun uses all of these types of authentication. When you sign up for Mailgun, we provide the appropriate records for you to include at your DNS registrar. We also provide a verification button you can use to make sure that your records are set up correctly. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/sending-messages/batch-sending.md # Batch Sending Mailgun supports the ability to send to a group of recipients through a single API call, or SMTP session. This is achieved by: - Using Batch Sending by specifying multiple recipient email addresses as `to` parameters and using Recipient Variables. - Using Mailing Lists with the Template Variables Warning! When using Batch Sending, it is important to also use Recipient Variables. This will ensure that Mailgun will send an individual to each recipient in the **to** field. If this is not done, the email will show all recipients emails in the **to** field for all recipients ### Recipient Variables **Recipient Variables** are custom variables that you define to allow the ability to send a custom message to each recipient while using a single API call (or SMTP session). To access a Recipient Variable within your email, simply reference %recipient.yourkey%. For example, consider the following JSON: ```JSON { "user1@example.com" : {"unique_id": "ABC123456789"}, "user2@example.com" : {"unique_id": "ZXY987654321"} } ``` To reference the above variable within your email, use %recipient.unique_id% Recipient Variables allow to: - Submit a message template - Include multiple recipients - Include a set of key value pairs with unique data for each recipient ```bash curl -s --user 'api:YOUR_API_KEY' \ https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \ -F from='Excited User ' \ -F to=alice@example.com \ -F to=bob@example.com \ -F subject="Hey %recipient.name%" \ -F text='If you wish to unsubscribe, click ' \ -F recipient-variables='{"alice@example.com": {"name":"Alice", "id":1}, "bob@example.com": {"name":"Bob", "id":2}}' \ ``` The example above: Alice and Bob both will get personalized subject lines, "Hey, Alice", and "Hey, Bob", as well as unique unsubscribe links. Info - The maximum number of recipients allowed for batch is 1,000 - Recipient variables should be set as a valid JSON-encoded dictionary where key is a plain recipient address, and value is a dictionary with variables. When sent via SMTP, recipient variables can be included by adding the following header to your email: `X-Mailgun-Recipient-Variables: {"user1@example.com": {"unique\_id": "ABC123456789"}}` Example: ```MIME X-Mailgun-Recipient-Variables: {"bob@example.com": {"first":"Bob", "id":1}, "alice@example.com": {"first":"Alice", "id": 2}} From: me@example.com To: %recipient% Date: 29 Mar 2016 00:23:35 -0700 Subject: Hello, %recipient.first%! Message-Id: <20160329071939.35138.9413.6915422C@example.com> Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Hi, %recipient.first%, =20 Please review your profile at example.com/orders/%recipient.id%. =20 Thanks, Example.com Team ``` Info - The value of the "X-Mailgun-Recipient-Variables" header should be a valid JSON string, otherwise Mailgun won't be able to parse it. - If your "X-Mailgun-Recipient-Variables" header exceeds 998 characters, you should use folding to spread the variables over multiple lines. They can also be supplied through a special construct called a Variable Container. To contain variables, create the following MIME construct: ```MIME multipart/mailgun-variables --application/json (base64 encoded) --message/rfc822 ----original-message ``` In this construct, JSON will be Base64 encoded, and will be stored inside the part of the body which will handle recipient variables containing special characters. Example: ```JSON Content-Type: multipart/mailgun-variables; boundary="8686cc907910484e9d21c54776cd791c" Mime-Version: 1.0 From: me@example.com Date: Thu, 26 Jul 2012 15:43:07 +0000 Message-Id: <20120726154307.29852.44460@definebox.com> Sender: bob=bob-mg@definebox.com --8686cc907910484e9d21c54776cd791c Mime-Version: 1.0 Content-Type: application/json Content-Transfer-Encoding: base64 eyJkZXNjcmlwdGlvbiI6ICJrbGl6aGVudGFzIn0= --8686cc907910484e9d21c54776cd791c Content-Type: message/rfc822 Mime-Version: 1.0 Date: Thu, 26 Jul 2012 19:42:55 +0400 To: %recipient.description% From: me@example.com Subject: (rackspace) Hello MSK 2012 support@mailgunhq.com %recipient.description% Message-Id: <20120726154302.29322.40670@definebox.com> support@mailgunhq.com %recipient.description% --8686cc907910484e9d21c54776cd791c-- ``` Info Mailgun recommends only placing recipient variables in one of the supported locations described. If you feel you MUST use multiple locations, see the Recipient Variable Precedence section below to understand how we merge recipient variables together. ### Recipient Variable Precedence If Recipient variables are found in multiple supported locations, they are merged together with the following precedence, in order of top-to-bottom, highest-to-lowest priority: `multipart/mailgun-variables`: Variable Container mentioned above (highest priority) `X-Mailgun-Recipient-Variables`: Headers within the main MIME `message/rfc822` body container `recipient-variables API parameter`: API parameter (lowest-priority) --- # Source: https://documentation.mailgun.com/docs/mailgun/email-best-practices/best_practices.md # Email Best Practices 📧 After managing email servers for thousands of customers, both sending and recieiving, we have learned these best practices for sending email. In this section, rather than looking at the content for email messages, we will be focusing on the infrastructure and monitoring of email. This will help you understand what works and what doesn't work for sending emails; Giving you insight for what and how to resolve your email sending woes. We hope these best practices help you through your email journey. If you still have questions, we're happy to help. --- # Source: https://documentation.mailgun.com/docs/mailgun/email-best-practices/bounce_esp.md # Bounce and MBP Feedback Handling A big part of maintaining your email reputation is processing bounces properly. While most major MBPs (Mailbox Providers) give bounce replies "on the wire" during the SMTP session, there are some that send bounce messages via email. In order to receive these emailed bounce messages, you must have the appropriate return path header included with your email so that recipients know where to reply with bounce information. You must also process this bounce data and act accordingly. In addition, many MBPs will soft bounce your initial attempts at delivery. This is also called grey-listing or throttling. If you continue to send emails to bad addresses or you do not listen to MBPs feedback, you will get filtered and eventually your emails will just get dropped. Mailgun automatically processes bounce information and reacts accordingly. A good portion of Mailgun's technology is devoted to the parsing of this feedback and adjusting your sending in accordance with this feedback so that you maintain a good reputation. If we receive a hard bounce, we will stop sending to that address immediately and will not attempt future deliveries to that address. We will stop sending to an address after multiple soft bounces, according to the MBPs' guidelines. It is possible to remove addresses from the flagged list in your Control Panel or through the API, in case it was a temporary issue. --- # Source: https://documentation.mailgun.com/docs/validate/bulk-valid-ir.md # Bulk Validation Note: Note Bulk Validation allows for the validation of a list of email addresses. Given a list name and an uploaded file of email addresses, a backend processing job will be run to verify the list. Once the validations have all been completed, the results will be provided with download links. Note: Note It’s important to upload as multi-part/form-data where the file is defined by file. Currently only raw csv and gzip are supported. While there is no limit on the number of email addresses that can be provided, the file size cannot exceed 25MB. The column header for emails needs to be either email or email_address Warning! Warning Lists must comply to either UTF-8 or ASCII encoding and not have a ‘@’ in the name. ``` GET /v4/address/validate/bulk ``` Get list of all bulk validation jobs. ``` POST /v4/address/validate/bulk/ ``` Create a bulk validation job. The `list_id` is an arbitrary unique identifier provided by the API caller. Please note that the max number of validation jobs that can be processed in parallel is 5. If this number is exceeded, a 400 response will be returned. ``` GET /v4/address/validate/bulk/ ``` Check the current status of a bulk validation job. ``` DELETE /v4/address/validate/bulk/ ``` This endpoint can be used to cancel an in-progress bulk validation job or delete results for a completed bulk validation job. When this endpoint is called for an “uploaded” job, associated result files will be deleted and the job’s status will be set to “deleted”. Get the status of a bulk validation job: ```JSON curl -s --user 'api:YOUR_API_KEY' -G \ https://api.mailgun.net/v4/address/validate/bulk/LIST_NAME ``` Sample Response: ```JSON { "created_at": "Tue, 26 Feb 2019 21:30:03 GMT", "download_url": { "csv": "", "json": "" }, "id": "bulk_validations_sandbox_mailgun_org", "quantity": 207665, "records_processed": 207665, "status": "uploaded", "summary": { "result": { "deliverable": 181854, "do_not_send": 5647, "undeliverable": 12116, "catch_all" : 2345, "unknown": 5613 }, "risk": { "high": 17763, "low": 142547, "medium": 41652, "unknown": 5613 } } } ``` ## Field Explanation: | Parameter | Type | Description | | --- | --- | --- | | created_at | string | Date/Time that the request was initiated | | download_url | array | csv and json representation of the download link for the results of the bulk validation | | id | string | list_id name given when the list was initially created} | | quantity | integer | number of total items in the list to be verified | | records_processed | integer | de-duplicated total of verified email addresses | | status | string | current state of the list validation request. (created, processing, completed, uploading, uploaded, and failed) | | summary | collection | summary of the validations in the list provided | | result | array | nested results count. (catch_all, deliverable, do_not_send, undeliverable, and unknown) | | risk | array | nested risk assessment count (high, low, medium or unknown) | Get a list of bulk validation jobs: This request will return a list of validation jobs in descending order by time created. ```JSON curl -s --user 'api:YOUR_API_KEY' -G \ https://api.mailgun.net/v4/address/validate/bulk ``` | Parameter | Type | Description | | --- | --- | --- | | limit | integer | Number of entries to return. Default: 500. | Sample Response: ```JSON { "jobs":[ { "created_at": "Tue, 26 Feb 2019 21:30:03 GMT", "download_url": { "csv": "", "json": "" } "id": "bulk_validations_sandbox2_mailgun_org", "quantity": 207665, "records_processed": 207665, "status": "uploaded", "summary": { "result": { "deliverable": 181854, "do_not_send": 5647, "undeliverable": 12116, "catch_all" : 2345, "unknown": 5613}, "risk": { "high": 17763, "low": 142547, "medium": 41652, "unknown": 5613} } }, { "created_at": "Tue, 23 Feb 2019 21:30:03 GMT", "download_url": { "csv": "", "json": "" } "id": "bulk_validations_sandbox_mailgun_org", "quantity": 207, "records_processed": 207, "status": "uploaded", "summary": { "result": { "deliverable": 181854, "do_not_send": 5647, "undeliverable": 12116, "catch_all" : 2345, "unknown": 5613}, "risk": { "high": 17763, "low": 142547, "medium": 41652, "unknown": 5613} } }], "total":3, "paging": { "next": "https://url_to_next_page", "previous": "https://url_to_previous_page", "first": "https://url_to_first_page", "last": "https://url_to_last_page" }, } ``` Results Fields Explanation: | Field | Description | | --- | --- | | Deliverable | The collection of validation jobs requested for. | | Undeliverable | The total number of validation jobs. | | Do Not Send | A collection of pagination links for traversing the validation jobs. | | Catch All | The total number of domain associated with result is considered a catch_all domain | Create a bulk validation job: ```JSON curl -s --user 'api:YOUR_API_KEY' \ https://api.mailgun.net/v4/address/validate/bulk/LIST_NAME \ -F 'file=@/path/to/file' \ ``` Sample Response: ```JSON { "id": "myemails", "message": "The validation job was submitted." } ``` Cancel a bulk validation job: ``` curl -s --user 'api:YOUR_API_KEY' -X DELETE \ https://api.mailgun.net/v4/address/validate/bulk/LIST_NAME ``` Sample Response: ```JSON { "message": "Validation job canceled." } ``` --- # Source: https://documentation.mailgun.com/docs/validate/bulk_valid_preview.md ## List Health Preview List Health Preview performs a free analysis of a list of email addresses allowing you to make an informed decision to run a complete bulk validation or not. Given a preview name and an uploaded file of email addresses, a preliminary validation run will be preformed. The results of the preview will be, on average, an estimate of the deliverability and risk of the emails provide. This evaluation is based on a statistical sampling of the list provided Info It's important to upload as *multi-part/form-data* where the file is defined by *file*. Currently only raw *csv* and *gzip* are supported. While there is no limit on the number of email addresses that can be provided, the file size cannot exceed 25MB. The column header for emails needs to be either *email* or *email_address* Warning! Lists must comply to either UTF-8 or ASCII encoding and not have a '@' in the name. ``` GET /v4/address/validate/preview ``` ### Get list of all health previews. ``` POST /v4/address/validate/preview/\ ``` ### Create a list Health Preview . The `list_id` is an arbitrary unique identifier provided by the API caller. Please note that the max number of validation previews that can be processed in parallel is 10. If this number is exceeded, a 400 response will be returned. ``` GET /v4/address/validate/preview/\ ``` ### Check the current status of list Health Preview. ``` DELETE /v4/address/validate/preview/\ ``` ### Delete a list Health Preview. ``` PUT /v4/address/validate/preview/\ ``` ### Get the results of the list health preview: ```JSON curl -s --user 'api:YOUR_API_KEY' -G \ https://api.mailgun.net/v4/address/validate/preview/LIST_NAME ``` Sample Response: ```JSON { "preview": { "id": "test_500", "valid": true, "status": "preview_complete", "quantity": 8, "created_at": 1590080191, "summary": { "result": { "deliverable": 37.5, "undeliverable": 19, "catch_all" : 6, "unknown": 37.5 }, "risk": { "high": 25, "low": 25, "medium": 12.5, "unknown": 37.5 } } } } ``` Field Explanation: | Field | Type | Description | | --- | --- | --- | | id | string | list_id name given when the list was initially created | | created_at | string | Date/Time that the request was initiated | | quantity | integer | number of total items in the list to be previewed | | status | string | current state of the list validation request. (preview_processing, preview_complete) | | valid | bool | a boolean to represent if the list is valid | | summary | collection | summary of the verifications in the list provided | | result | array | nested results averaged. (deliverable, undeliverable, catch_all and unknown) | | risk | array | nested risk assessment count (high, low, medium or unknown) | ### Get a list: This request will return a list health check. ```JSON curl -s --user 'api:YOUR_API_KEY' -G \ https://api.mailgun.net/v4/address/validate/preview ``` Sample Response: ```JSON { "previews": [ { "id": "test_500", "valid": true, "status": "preview_complete", "quantity": 8, "created_at": 1590080191, "summary": { "result": { "deliverable": 37.5, "do_not_send": 0, "undeliverable": 23, "catch_all": 2, "unknown": 37.5 }, "risk": { "high": 25, "low": 25, "medium": 12.5, "unknown": 37.5 } } }, { "id": "test_501", "valid": true, "status": "preview_complete", "quantity": 8, "created_at": 1590155015, "summary": { "result": { "deliverable": 37.5, "do_not_send": 0, "undeliverable": 23, "catch_all": 2, "unknown": 37.5 }, "risk": { "high": 25, "low": 25, "medium": 12.5, "unknown": 37.5 } } } ] } ``` ### Response Fields Explanation: | Field | Type | Description | | --- | --- | --- | | previews | collection | A collection of bulk validation previews. | ## List Health Preview: ```JSON curl -s --user 'api:YOUR_API_KEY' \ https://api.mailgun.net/v4/address/validate/preview/LIST_NAME \ -F 'file=@/path/to/file' \ ``` Sample Response: ```JSON { "id": "test_501", "message": "The bulk preview was submitted." } ``` ### Delete a list health check preview: ```JSON curl -s --user 'api:YOUR_API_KEY' -X DELETE \ https://api.mailgun.net/v4/address/validate/preview/LIST_NAME ``` --- # Source: https://documentation.mailgun.com/docs/mailgun/faq/deliver-rep.md # FAQ: Deliverability / Reputation ### If I'm just starting to send mail, how do I build a good reputation? The way to think about your email reputation is much like your credit score. When you haven't sent any email, you don't have a bad reputation but you don't have a good one, either. Also, no ESP is going to allow you to send a million emails to their mailboxes, much like no one is going to give you a credit card with a huge credit limit when you graduate from college. There needs to be a history of performance for you to create a reputation. We use algorithms for our new senders that automatically queues your email and sends them at rates that makes the ESPs happy, increasing those rates as your sending reputation grows. Some of the factors that help you build a good reputation faster and increase deliverability are: - Limited spam complaints and bounces. - Including the ability for recipients to unsubscribe. - Recipients interacting with your emails in a good way: reading, replying, forwarding and adding your addresses to their contacts. - Following ESPs' guidelines on sending rates. - Paying attention to ESPs' feedback to slow or stop sending for a period of time. - Having good content (see below for more guidance on content). Also, consider letting your users to reply to your emails. Having a meaningful email conversations with your audience will do wonders for your reputation as a member of email community. Finally, there are certification and white label services that can help (although, you still need some history of sending). We have a partnership with [Return Path](http://www.returnpath.com) and can help get you signed up for their [Email Certification Program](http://www.returnpath.com/solution-content/certification/). They have already audited our infrastructure so we can get you a discount off of their list pricing. ### Does the content of my email matter for deliverability? Absolutely. Ideally, you send email that people want. That's over half the battle. In addition, you should make your content interesting and relevant to the recipient. There are a few things to keep in mind about your email content. First, we suggest setting up a test mailbox at [http://www.mail-tester.com](http://www.mail-tester.com). Mail-Tester will provide you with a full analysis of your email for free. Here are some other things to consider: - Personalize your emails. Make sure to include the recipient's address in the "To:" field and include his/her name in the greeting. - It is best to send multi-part emails using both text and HTML or text only. Sending HTML only email is not well received by ESPs. Also, remember that ESPs generally block images by default so HTML only will not look very good unless users are proactive about enabling images. - Test how your html email looks across all email clients and browsers. [Litmus](http://litmus.com/) and [Return Path](http://www.returnpath.com) have tools to do this. - Make your content relevant and targeted to the recipient. There are even tools like [Movable Ink](http://movableink.com/) that let you dynamically update your content after it is delivered. - The higher the text to link and text to image ratios, the better. Too many links and images trigger spam flags at ESPs. - Misspellings, spammy words (buy now!, Free!) are big spam flags, as are ALL CAPS AND EXCLAMATION MARKS!!!!!!!!!!!!! - The from field in your emails should match the domain you are sending from. Hotmail is particularly focused on this. - Make sure you are using unsubscribe links and headers in your emails. Many ESPs (particularly Hotmail) pay attention to this and if they are not there, you are likely to get filtered. You can always use Mailgun's auto unsubscribe handling if you don't want to deal with this on your end. - Include your physical mailing address. CAN-SPAM requires an unsubscribe link and a physical mailing list. It is also a good idea to provide a link to your privacy policy. - Gmail pays particularly close attention to Message ID and Received headers. Message IDs that are formed incorrectly (without brackets <> and with wrong domain after @) can make Gmail think you are a spammer. The simplest way to create the right Message ID is to not set Message ID at all. Then Mailgun will create a perfect Message ID for you. Also, if you use the HTTP API, Mailgun will deal with all of this for you. - Links should include the domain that is sending the email. Also, popular url shorteners can be a bad idea because they are frequently used by spammers. - Long links may cause bounces. Some ESPs will block emails with links (or any consecutive text) longer than 99 characters. - A/B test your emails to optimize recipient engagement. Subject lines are particularly important. You can use Mailgun's tagging and tracking statistics in order to measure A/B testing and improve your content. ### Should I use my primary corporate domain name to send email? You can, but remember that your reputation is tied to your domain name as well as the IP address. If you are in danger of being classified as a 'bad' sender of email, you will be affecting your domain reputation, which is very hard to recover from. It may be safer to use a completely separate domain (not a subdomain of your primary corporate domain) for sending marketing or even transactional email if you are worried about issues with domain reputation. ### Why does the amount of email I send matter? Rate limiting allows ESPs proper time to process and filter spam and ensure that transactional email doesn't get backed up. Without rate limiting in place, ESPs would be even more overwhelmed than they already are. The ESPs all have different sending limits on a per hour, per day basis. Once you hit thresholds with the rate limits, send too much spam, or have any number of other issues, the ISP may start returning error messages. Some ESPs will want you to slow down the sending, stop sending for a period of time, or change your habits (due to bad engagement, bad reputation, etc). We automatically adjust your sending rates according to the feedback from these ESPs to keep you in their good graces. Generally, these rate limits are on a per IP address basis. [Contact our Support Team](https://app.mailgun.com/app/support) if you wish to purchase additional dedicated IP addresses for your account. ### Does the amount of email I send from my IP affect my deliverability? Yes. Generally speaking, you don't want too few IPs, in case you experience more volume than you expect and you don't want so many IPs that you look suspicious or spread out your volume over too many IPs. There has to be a balance of volume to IP/domain. Sending too much volume from an IP, sending from too many IPs or sending too little from a range of IPs can all lead to deliverability issues. ### Where can I learn more about Deliverability and Email? One of the best resources is the blog [Word to the Wise](http://blog.wordtothewise.com/). Also, [Return Path](http://www.returnpath.com) is a service that enhances deliverability and they publish a lot of great information through their blog and white papers. Below is are some best practices from the major ESPs. - [Y Sender Hub/AOL Best Practices](https://postmaster.aol.com/best-practices) - [Gmail Best Practices](https://support.google.com/mail/answer/81126?hl=en) - [Outlook Best Practices](http://mail.live.com/mail/policies.aspx) - [Yahoo Best Practices](https://help.yahoo.com/kb/postmaster/practices-senders-sln3435.html) --- # Source: https://documentation.mailgun.com/docs/mailgun/api-reference/developer-tools.md ## Developer Tools ### Postman Collection Import all Mailgun APIs into Postman for easy testing and integration. Our public workspace includes organized collections with examples, environment variables, and ready-to-use requests. div a img Open in Postman span → Fork to your workspace and start testing What's included: - Complete Mailgun API collection organized by feature including variables for quick use - Collection variables for quick setup ### SDKs, Libraries and Integrations Use our official SDKs for seamless integration with your preferred programming language. Visit our [Integrations Page](https://www.mailgun.com/integrations/) for more. ### Full OpenAPI spec Import our complete OpenAPI specification into your favorite tools using the download button found [here](/docs/mailgun/api-reference/send/mailgun) --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/reporting/dimensions.md # Dimensions | Dimension | API Variable Name | Example Values | Description | | --- | --- | --- | --- | | Bot | bot | Apple GenericGmail None | Identifies bot engagement with your emails. Bot engagement is classified as Apple, Gmail, Generic, or None. | | Country | country | US GB AU CA NL DE FR IN Unknown | Country identifies the country of origin for engagement data IPs. Only engagement data will display per country, all other data will show under the value “Unknown”. Country codes use ISO 3166 country codes. | | Domain | domain | mailgun.net yourdomain.com mg.yourdomain.com | Your sending domains. | | IP Pool | ip_pool | Transactional IP PoolMarketing IP Pools | IP Pools enable you to group your dedicated IPs into customized "pools" to help manage your sending reputation for different mail-sending streams. | | Sending IP | ip | 192.237.158.61159.135.234.21 166.78.71.1 69.72.42.3 | Your sending IPs. These may be dedicated or shared IPs. | | Recipient Domain | recipient_domain | gmail.com outlook.com hotmail.com yahoo.com Other | The recipient domains you’ve sent to, like Gmail.com, Outlook.com, and Yahoo.com. | | Recipient Provider | recipient_provider | GmailGoogle WorkspaceOutlook 365Outlook USProtonYahoo USAppleChinese Outlook EUFrenchGermanOther EUCanadianUKOther USItalianOther | The recipient providers that you’ve sent to. Recipient domains are aggregated to providers like Gmail, Google Workspace, or Outlook 365.[Click here](https://help.mailgun.com/hc/en-us/articles/23687761220635-Events-Logs-Recipient-Mailbox-Providers) to see the full list of Recipient Providers. | | Subaccount | subaccount | Subaccount 1 Subaccount 2 | If you’ve created subaccounts, you can use this dimension to view individual subaccount performance. | | Tag | tag | Transactional Marketing Untagged | Tags are labels you attach to a message to identify or categorize your sending.By assigning a tag, you’re able to organize your email analytics so you have access to more precise and detailed insights. | | Time | time | Mon, 19 Aug 2024 20:00:00+0000 Wed, 15 May 2024 19:00:00+0000 | The time that your events occured. The timezone in your account settings will be used for hourly data, but daily and monthly data will be aggregated using UTC time. Time uses the RFC 2822 format. | --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/domains/dkim_security.md # DKIM Security DKIM (DomainKeys Identified Mail) security involves regularly updating the cryptographic keys used for signing emails to maintain security and protect against key compromise. Like passwords, your DKIM key is vulnerable to compromise. Best practices recommend rotating your DKIM key at least every 6 months and immediately if your key is compromised. When you set up an authenticated domain, Mailgun provides two methods for key rotation: - **Automatic rotation** using Mailgun's Automatic Sender Security feature - **Manual rotation** on your preferred schedule ## Automatic Sender Security Mailgun's Automatic Sender Security feature simplifies email authentication by handling the technical setup and configuration automatically. This eliminates the need for manual key generation and DNS record adjustments, reducing errors and ensuring proper email authentication. ### How CNAME Records Enable Automated Key Management The feature works by adding two CNAME records to your domain's DNS settings. A CNAME (Canonical Name) record creates an alias that points from your domain to another location. Instead of storing the actual DKIM public key directly in your DNS as a TXT record, the CNAME records point to Mailgun's infrastructure where the keys are hosted. This delegation is what enables Mailgun to manage your DKIM keys automatically. When an email provider needs to verify your email signature, it queries your domain's DNS for the DKIM public key. The CNAME record redirects this query to Mailgun's servers, which return the current active public key. Because the key is hosted on Mailgun's infrastructure rather than directly in your DNS, Mailgun can update and rotate the keys without requiring any action from you. When rotation occurs, Mailgun generates a new key pair and updates the public key on their servers. Because your DNS simply points to Mailgun's location via the CNAME record, the change takes effect immediately without any DNS updates on your end. This seamless process ensures continuous email authentication while maintaining the highest security standards through regular key rotation. ### DNS Configuration The host or name you provide to your DNS provider will look similar to `pdk1._domainkey.my.domain.com` and `pdk2._domainkey.my.domain.com`, while the target pointing back to Mailgun will resemble `pdk1._domainkey.9d876.dkim1.mailgun.com` and `pdk2._domainkey.9d876.dkim1.mailgun.com`. Two CNAME records are used to enable smooth key transitions during rotation. This dual key approach allows Mailgun to introduce a new key while the old key remains active, ensuring there's no interruption in email authentication. Email providers may cache DNS records, so having both keys active during the transition period ensures that emails are successfully verified regardless of which key information a receiving server has cached. Once the new key is fully propagated and the old key is no longer needed, the system maintains two active keys ready for the next rotation cycle. Automatic Sender Security generates two 2048 bit DKIM selector records via TXT records, which are automatically rotated every 120 days by default. You can adjust the rotation period as needed. The minimum interval for rotation is 5 days. ### New Sending Domains When adding a new domain, you will have the option to enable Automatic Sender Security during the setup process. ### Existing Sending Domains If you have an existing sending domain currently utilizing DKIM via a TXT record and wish to switch to Automatic Sender Security, you can do so from the DNS records page in the Mailgun application. ## Manual DKIM Rotation You have the option to manually rotate your DKIM keys on your own schedule. Mailgun supports signing messages with up to 3 DKIM keys. When multiple active keys are present on a sending domain, we use a round robin method to determine which key signs each message. There are two methods for adding a new DKIM key. In both cases, you must choose a unique selector (unique to the sending domain): - **Allow Mailgun to generate a DKIM key** (most common method) - **Import an existing key** via a valid PEM file (advanced method) ### Allowing Mailgun to Generate the DKIM Key You can choose to allow Mailgun to generate the DKIM key. Most users select this method. You can choose the DKIM key length: either 1024 bit or 2048 bit. The 2048 bit option is more secure but can be more complex to set up because the record length is significantly longer, and some DNS providers require you to split the record into two parts. When rotating keys or upgrading from a 1024 bit key to a 2048 bit key, we recommend sending a test message to yourself to verify that messages are being signed with the new key. You may need to send several test messages before confirming. Once verified, you can delete the old key. ## Additional Resources Learn more about [DKIM key rotation](https://help.mailgun.com/hc/en-us/articles/16956951504539) View our [Domain Security API documentation](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/dkim-security) View our [Domain Keys API documentation](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/domain-keys) --- # Source: https://documentation.mailgun.com/docs/mailgun/email-best-practices/dns.md # DNS Your email reputation is not only tied to your IP, but your domain name as well. You should keep this in mind as you set up your email infrastructure. For the same reasons, it is a good idea to have separate domains or subdomains for your marketing, transactional and corporate mail. We suggest that you use your top level domain for your corporate mail and using different domains or subdomains for your marketing and transactional mail. While it is not required to use the same domain in the From field of the message as the actual domain sending the message, it is highly recommended. Outlook/Hotmail is especially finicky about this requirement and has a higher propensity to filter your messages to junk if the two domains do not match. You should also make sure that you are using a well regarded DNS provider and that you publish all of your contact information in the WHOIS record. If you are hiding your contact information through a proxy, MBPs (Mailbox Providers) may take that as a signal that you are spamming. Also, make sure you include the appropriate records from your DNS provider for authentication. While it's not required to point mx records to the same domain as you are sending from, it is recommended. There are mailbox providers (albeit, a minority) that will check if mx records for the domain are valid before accepting email. Mailgun gives you the ability to create multiple domains or subdomains very easily. You are free to create multiple domains and subdomains for each of your transactional, marketing and corporate email. Each domain has an isolated queue, so your transactional emails won't get held up by your bulk mailings. --- # Source: https://documentation.mailgun.com/docs/inboxready/domain-blocklist-ir.md # Domain Blocklist Monitoring [Blocklist Monitoring](https://www.mailgun.com/products/inbox/deliverability/blocklist-monitoring-service/) enables you to keep an eye on your reputation. Monitor your domains against our curated list of blocklist providers to make sure you aren't being blocked. Some of the monitored blocklists include: - Spamhaus DBL - URIBL - SURBL For more on Blocklist Monitoring, see the article, How to Setup Blocklist Monitoring. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/domains/domains-custom.md # Custom Domains Creating custom domains in Mailgun enables you to send emails through your own domain instead of relying on the default sandbox domain. To use Mailgun for production, you must create and verify your custom domain(s) with Mailgun to ensure proper authentication and deliverability. Once you've acquired a domain through a DNS provider, follow these steps to set it up with Mailgun. #### Add your domain: 1. Go to the **Mailgun Control Panel** 2. On the left side control panel, click **'Send'** then **'Sending'** to expand the sidebar, then click **'Domains'** 3. **Click** the **Add new domain** button from the upper right corner 4. **Enter** your domain name in the **Domain name** field 5. Select **Domain region** 6. **Choose** your **IP assignment option** 7. **Click** the **Add Domain** button Once a domain has been added, you will receive an email that you will need to respond to so that it can be verified. --- # Source: https://documentation.mailgun.com/docs/inboxready/domains-ir.md # Domains This section describes domain management for Sinch Optimize products. Use these APIs to register domains for domain-based reputation monitoring tools such as [Spam Trap Monitoring](/docs/inboxready/spam-trap-ir) and [Domain Blocklist Monitoring](/docs/inboxready/domain-blocklist-ir). ## Add Domain This endpoint allows domains to be registered for reputation monitoring. ``` POST /v1/inboxready/domains ``` The available request fields are as follows: | Field | Description | | --- | --- | | `domain` | Required. The domain or subdomain that you wish to add. | Example 200 response: ```JSON { "domain": { "ID": "", "created_at": 123456789, "name": "example.com", "verified": { "verified_at": 0, "status": "inbox_ready" }, "services": { "spam_trap_monitoring": true, "domain_blocklist_monitoring": true, }, "txt_record": "" } } ``` ## Get Domains This endpoint returns a list of domains. ``` GET /v1/inboxready/domains ``` Example 200 response: ```JSON { "items": [ { "ID": "", "created_at": 123456789, "name": "example.com", "verified": { "verified_at": 123456789, "status": "inbox_ready" }, "services": { "spam_trap_monitoring": true, "domain_blocklist_monitoring": true }, "txt_record": "" }, ... ], "paging": { "previous": "", "first": "", "next": "", "last": "" } } ``` ## Remove Domain This endpoint can be used to remove a domain from reputation monitoring. ``` DELETE /v1/inboxready/domains ``` The available request fields are as follows: | Field | Description | | --- | --- | | `domain` | Required. The domain or subdomain that you wish to remove. | Example 200 response: ```JSON { "message": "example.com has been removed from InboxReady" } ``` --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/domains/domains-sandbox.md # Sandbox Domain Want to immediately send email from your account without setting up your own Domain? Each new Mailgun account is automatically provisioned with a sandbox domain, sandbox `@mailgun.org`. This is for testing purposes only. Sandbox domains can only send to authorized recipients. Your Sandbox Domain allows: - Sending messages to lists with up to 5 [authorized participants](https://help.mailgun.com/hc/en-us/articles/217531258-Authorized-Recipients) - Receiving Messages (limited to one Route) - Tracking Messages Info Sending limitations are also in effect for Routes that are triggered by message addresses to the sandbox domain and mailing lists created under that domain. #### To use your Sandbox Domain: 1. Log in to your Mailgun account 2. Go to the Mailgun Control Panel 3. On the left side control panel, click 'Send' to expand the sidebar, then click 'Domains' 4. Click on the sandbox domain 5. From the Setup tab in Domain Settings, add authorized recipients and view code examples to send email using your sandbox domain --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/domains/domains-verify.md # Domain Verification ![verifydomain](/assets/mailgunsendverify.4a4aa76ee8b52d005794cf5f4392627c00f8ad17c205a7fdb850171cde0eb732.05e97c23.png) ### Five reasons why you need to verify your domain: - To prove you are an authorized sender for the domain - Verified domains are not subject to a sending limit of 300 emails per day - No more "sent via Mailgun.org" message in your emails - Establishes a positive email reputation for your own domain - Mailgun is less suspicious of traffic that is being sent on verified domains and that reduces the likelihood of being disabled The basic steps to verify a domain are: 1. Get the DNS records (Via [API](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/domains/get-v4-domains--name-) or Control Panel) 2. Open your DNS provider and add the provided DNS records: | Type | Required | Purpose | Value | | --- | --- | --- | --- | | TXT | ✅ | SPF (Sender Policy Framework): Sending server IP validation. This is used by most email providers. | v=spf1 include:mailgun.org ~all | | TXT | ✅ | DKIM (DomainKeys Identified Email): Like SPF, but uses cryptographic validation. | *Find this record in the "Domain Verification & DNS" section of the Mailgun control panel for your domain.* | | CNAME | ✅ | Required for Mailgun to track clicks, opens, and unsubscribes. | mailgun.org | | MX | ✅ | Required for Mailgun to receive and route/store messages addressed to the domain. | 10 mxa.mailgun.org 10 mxb.mailgun.org | Once you've added the supplied records, and they've propagated over the internet (can take 24-48 hours for DNS changes to fully propagate), your domain is now able to be verified. 1. You can either wait for Mailgun's system to check the domain and automatically verify it for you, or if you don't want to wait you can click Verify DNS settings in the Domain Settings section of the Control Panel, or call the [Verify API](/docs/mailgun/api-reference/send/mailgun/domains/put-v4-domains--name--verify) Verified domains will show up on the Mailgun Control Panel with a green Verified badge next to it! For more information and help related to verifying domains check out these articles: - How Do I Verify My Domain? and Other DNS Question - Domain Verification Walkthrough ## Common DNS Providers Documentation If you'd like more detailed instructions on how to add DNS records for your domain, please refer to the documentation provided by your DNS provider. Below is a list of common DNS providers and links to their documentation: | Provider | Link to Documentation | | --- | --- | | Go Daddy | [MX](https://www.godaddy.com/help/add-an-mx-record-19234)[CNAME](https://www.godaddy.com/help/add-a-cname-record-19236)[TXT](https://www.godaddy.com/help/add-a-txt-record-19232) | | NameCheap | [All Records](https://www.namecheap.com/support/knowledgebase/subcategory/10/dns-questions/) | | Network Solutions | MXCNAMETXT | | Rackspace Email & Apps | [All Records](https://status.apps.rackspace.com/) | | Rackspace Cloud DNS | [Developers Guide](https://docs.rackspace.com/support/how-to/set-up-dns-records-for-cloud-office-email/) | | Amazon Route 53 | [Developer Guide](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/setting-up-route-53.html) | --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/domains/domains.md # Domains ## Overview When emails are sent, they are transmitted through domains over the internet. An email address has two main parts: the username and the domain (e.g., username@example.com). Domains have a crucial role, as they are responsible for identification, routing and deliverability of email! Within Mailgun, many features such as webhooks, logs, mailing lists and suppressions are associated with individual Domains. --- # Source: https://documentation.mailgun.com/docs/inboxready/email-preview-ir.md # Email Preview Our Email Preview service allows you to see how your emails render across various web, desktop, and mobile clients. ## Create Test This call creates a new email preview test and submits it to our system for processing. All requests must contain a `subject` property and one source property (either `html` or `url` All other properties are optional. In the following table, each property and its default value is shown. The response will include an `id` property that should be used to request the results or run processes on the email content. ``` POST /v1/preview/tests ``` The available request fields are as follows: | Field | Description | | --- | --- | | `subject` | The subject line of your email, encoded as declared in transfer_encoding. | | `html` | The email source of your email, encoded as declared in transfer_encoding. | | `url` | A URL pointing to the email source of your email. | | `clients` | An array of string IDs as returned from client list functions. If no clients are specified, all available clients will be used. | | `reference_id` | This value can be used for searching and internal reporting. | | `charset` | The character set your HTML is encoded in. | | `transfer_encoding` | One of base64, quoted-printable, 7bit, or 8bit. | ```JSON { "message": "example.com has been removed from InboxReady" } ``` Example Response ```JSON { "id": "", "reference_id": "123ABC" } ``` ## Get Tests This call returns a list of all available Email Tests and some metadata about them. Email Tests are stored for 90 days. The query string is an optional standard URL parameterized version containing any or all of the below search parameters. ``` GET /v1/preview/tests?\ ``` The available search query parameters are as follows: | Name | Description | | --- | --- | | `from` | The starting point of your test date range. | | `to` | The ending point of your test date range. | | `subject` | The subject field of returned tests must contain the exact string. This search is case-insensitive. | | `results` | The number of results to return. Must be between 1 and 200. The default value is 50. | | `page` | The page number. If you submit a number higher than the number of pages in the data, an empty array will be returned. The default value is 1. | Example response: ```JSON [ { "id": "", "date": 1648177673, "type": "email-test", }, { "id": "", "date": 1648177673, "type": "email-test", } ] ``` ## Get Test Info This call returns the subject and submission time in UNIX timestamp format. It will also contain one to three properties containing an array of clients. The `completed` property shows clients that have completed screenshots uploaded. The `processing` property contains clients which are still being processed by our system. The bounced property contains clients that were `bounced` by the destination and cannot be retried. This call will automatically requeue screenshots if they stay in processing for more than three minutes. ``` GET /v1/preview/tests/{TEST\_ID} ``` Example response: ```JSON { "subject": "Test Subject", "date": 1470034800, "completed": [ "iphone12_15", "iphone12_15_dm" ], "processing": [ "iphone13_15" ], "bounced": [ "ffr_chr26_win" ] } ``` ## Get Test Results This call returns detailed results for screenshots including their upload locations, send times, completion times, and information about bounces, if any. `TEST_ID` is a test ID returned from test creation or the get tests functions. The URLs in this call are static – that is to say that they will not change for the duration your test is active (90 days from test creation). Any reprocessing that is done will replace the images in these locations. The image locations are generated programmatically before the screenshots are complete, so the presence of a URL in the call is not a guarantee that the file will be present. Use the "status" property to determine whether or not the file is present in the location, or you can manually test the URL provided. If the file is not present, you will receive a 403 Forbidden response from the endpoint. ``` GET /v1/preview/tests/{TEST\_ID}/results ``` Example response: ```JSON { "iphone13_15": { "id": "iphone13_15", "display_name": "iPhone 13", "client": "iPhone", "os": "iOS 15", "category": "Mobile", "screenshots": { "default": "", "horizontal": "" }, "thumbnail": "", "full_thumbnail": "", "status": "Complete", "status_details": { "submitted": 1649353640, "completed": 1649353649 } }, "iphone13_15_dm": { ... } } ``` ## Get Test Content Each of these calls will return an object with a single property `content` that contains the desired format of content. `TEST_ID` is a test ID returned from test creation or the get tests functions. Example response: ```JSON { "content": "" } ``` ### **HTML** This call returns the HTML associated with your Email Test. This is what is sent to our servers. ``` GET /v1/preview/tests/{TEST\_ID}/content ``` ### **INLINED CSS CONTENT** This call returns HTML with all stylesheets inlined into the HTML. ``` GET /v1/preview/tests/{TEST\_ID}/content/inlinecss ``` ### **TEXT ONLY CONTENT** This call returns a plain text version of your HTML. This approximates what will be displayed on devices that do not support HTML content. Our system does not currently support multipart emails, so if you send a separate text/plain section when you send your email, this may not be accurate to what users see. Additionally, devices may differ in their plain text renderings, so this function should be used more as a guide than as an exact preview. ``` GET /v1/preview/tests/{TEST\_ID}/content/textonly ``` ## Delete Test This call marks an Email Test as deleted. Once it is deleted, it cannot be recovered. ``` DELETE /v1/preview/tests/{TEST\_ID} ``` Example response: ```JSON { "success": true } ``` ## Reprocess Screenshots Sometimes strange things happen on the internet. If a strange result has come back in your screenshot, use this function to tell us to retake your screenshot free of charge. The request should contain an object with a property of `clients` that contains a list of clients in the `TEST_ID` provided. The object returned will have a `success` value indicating if the attempt was successful. If it is false, there will be a `reason` value describing the failure reason. ``` PUT /v1/preview/tests/{TEST\_ID}/results/reprocess ``` Example request body: ```JSON { "clients": [ "iphone13_15", "iphone13_15_dm" ] } ``` Example response: ```JSON { "iphone13_15": { "success": true, "remaining_reprocesses": 19, "regional": false, "screenshot": { "id": "", "type": "resubmit", "sent": 1649356634, "completed": 0 } }, "iphone13_15_dm": { ... } } ``` ## **Get Clients** This call returns a list of available email clients. The object will contain a `clients` property, with properties corresponding to the client IDs. Each of these properties will contain an object containing the client ID, a printable client name, and OS. Clients are split into three categories: "Web", "Application", and "Mobile". "Browser" type clients will contain a `browser` property. Missing properties should be interpreted as a feature NOT being supported (i.e. equivalent to "false"). The API MAY respond with "false". ``` GET /v1/preview/tests/clients ``` Example response: ```JSON { "iphone13_15": { "id": "iphone13_15", "client": "iPhone 13", "os": "iOS 15", "category": "Mobile", "rotate": true, "default": true }, ... } ``` Response property details: | Field | Description | | --- | --- | | `id` | Our unique identifier for the email client. This code can be used when creating new Email Tests. | | `client` | Name of the email client. | | `os` | The name of the OS that this client is running on. | | `category` | The type of client this is: one of “Application”, “Mobile”, or “Web” | | `browser` | If this is client is in a browser, the name of the browser the client is running in. | | `rotate` | A boolean value indicating if this client supports orientation changes. If it is missing, assume `false`. | | `default` | A boolean value indicating if this client will be included if no client key is sent with test creation. If it is missing, assume `false`. | --- # Source: https://documentation.mailgun.com/docs/validate/email-valid-ir.md # Email Validation API Note: Our Single and Bulk Email Validation service is available via the EU API. This API endpoint is an email address validation service that will validate the given address based on: - Mailbox detection - Syntax checks (RFC defined grammar) - DNS validation - Spell checks - Email Service Provider (ESP) specific local-part grammar (if available). The Email Validation API endpoint is available at: ``` v4/address/validate ``` Pricing details for Mailgun's email validation service can be found on our [pricing page](https://www.mailgun.com/pricing). Mailgun's email validation service is intended to verify email addresses submitted through forms like newsletters, online registrations and shopping carts. Refer to our [Acceptable Use Policy (AUP)](http://mailgun.com/aup) for more information about how to use the service appropriately. --- # Source: https://documentation.mailgun.com/docs/mailgun/email-best-practices/email_content.md # Email Content There are a few tricks to remember about content besides the mantra of 'sending something people want'. As mentioned above, you can set up a test mailbox at Mailgun and enable our spam filters to receive a "spamicity" score to test how your content is being judged by spam filters. - Personalize your emails to each recipient. Ideally, the content should reflect recipient's specific interests or usage patterns in your application. At least address them by their name. Mailgun has recipient variables that you can define and use with your email templates to achieve detailed levels of personalization. - It is best to send multi-part emails using both text and HTML or text only. Sending HTML only email is not well received by MBPs (Mailbox Providers). Also, remember that some MBPs block images by default so HTML only will not look very good unless users are proactive about enabling images. We recommend [Mailgun Optimize email previews](https://app.mailgun.com/app/email-preview) and [Email on Acid](https://www.emailonacid.com/) for testing how your emails render across MBPs, browsers, and email clients. - The higher the text to link and text to image ratios, the better. Too many links and images trigger spam flags at MBPs. - Misspellings, spammy words (buy now!, Free!) are big spam flags, as are ALL CAPS AND EXCLAMATION MARKS!!!!!!!!!!!!! - The domains in the from field, return-path and message-id should match the domain you are sending from. - Make sure you are using unsubscribe links and headers in your emails. Many MBPs (particularly Hotmail) pay attention to this and if they are not there, you are likely to get filtered. You can always use Mailgun's auto unsubscribe handling if you don't want to deal with this on your end. - Gmail pays particularly close attention to Message ID and Received headers. Message IDs that are formed incorrectly (without brackets <> and with wrong domain after @) can make Gmail think you are a spammer. The simplest way to create the right Message ID with Mailgun is to not include one. Then Mailgun will create a perfect Message ID for you. - Links should include the domain that is sending the email. Also, popular url shorteners can be a bad idea because they are frequently used by spammers. - A/B test your emails to optimize recipient engagement. Subject lines are particularly important. You can use Mailgun's tagging and tracking statistics in order to measure A/B testing and improve your content. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/events/event-polling.md # Event Polling In our system, events are generated by physical hosts and follow different routes to the event storage. Therefore, the order in which they appear in the storage and become retrievable - via the events API - does not always correspond to the order in which they occur. Consequently, this system behavior makes straight forward implementation of event polling miss some events. The page of most recent events returned by the events API may not contain all the events that occurred at that time because some of them could still be on their way to the storage engine. When the events arrive and are eventually indexed, they are inserted into the already retrieved pages which could result in the event being missed if the pages are accessed too early (i.e. before all events for the page are available). To ensure that all your events are retrieved and accounted for, please implement polling in the following way: 1. Make a request to the events API specifying an ascending time range that begins sometime in the past (e.g. half an hour ago) 2. Retrieve a result page 3. Check the timestamp of the last event on the result page. If it is older than the threshold age (e.g. half an hour), then go to step (4), otherwise proceed to step (6). 4. The result page is trustworthy, use events from the page as you please. 5. Make a request using the next page URL retrieved with the result safe, proceed with step (2). 6. Discard the result page for it is not trustworthy. 7. Pause for some time (at least 15 seconds) 8. Repeat the previous request and processed with step (2). --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/events/event-samples.md # Event Samples Response Samples of various Event types can be found on the Events API Reference page. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/events/event-structure.md # Event Structure Events are represented as loosely structured JSON documents. The exact event structure depends on the event type. But there are three fields that every event has. They are as follows: | Field | Description | | --- | --- | | event | The type of the event. Events of a particular type have an identical structure, though some fields may be optional. For the list of event types please refer to Event Types. | | timestamp | The time when the event was generated in the system provided as Unix epoch seconds. | | id | The event ID, unique within a day. It can be used to distinguish events that have already been retrieved when requests with overlapping time ranges are made. | Events can change their structure as new features are added to Mailgun, but we only add new fields and never modify or remove existing ones. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/events/event-types.md # Event Types Mailgun tracks all of the events that occur throughout the system. Below are listed the events that you can retrieve using this API. | Event Type | Description | | --- | --- | | accepted | Mailgun accepted the request to send/forward the email and the message has been placed in queue. | | rejected | Mailgun rejected the request to send/forward the email. | | delivered | Mailgun sent the email and it was accepted by the recipient email server. | | failed | Mailgun could not deliver the email to the recipient email server. severity=permanent when a message is not delivered. There are several reasons why Mailgun stops attempting to deliver messages and drops them including: hard bounces, messages that reached their retry limit, previously unsubscribed/bounced/complained addresses, or addresses rejected by an ESP. severity=temporary when a message is temporary rejected by an ESP. | | opened | The email recipient opened the email and enabled image viewing. Open tracking must be enabled in the Mailgun control panel, and the CNAME record must be pointing to mailgun.org. | | clicked | The email recipient clicked on a link in the email. Click tracking must be enabled in the Mailgun control panel, and the CNAME record must be pointing to mailgun.org. | | unsubscribed | The email recipient clicked on the unsubscribe link. Unsubscribe tracking must be enabled in the Mailgun control panel. | | complained | The email recipient clicked on the spam complaint button within their email client. Feedback loops enable the notification to be received by Mailgun. | | stored | Mailgun has stored an incoming message | --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/events/events.md # Introduction to Events Mailgun retains event data for 30 days. Access to this data varies by plan. Refer to our [Pricing page](https://www.mailgun.com/pricing/) for details. ## Tracked Events | Event | Description | | --- | --- | | `accepted` | Mailgun accepted the request to send/forward the email and the message has been placed in queue. | | `rejected` | Mailgun rejected the request to send/forward the email. | | `delivered` | Mailgun sent the email, and it was accepted by the recipient email server. | | `failed` | Mailgun could not deliver the email to the recipient email server. | | `opened` | The email recipient opened the email and enabled image viewing. Open tracking must be enabled in the Mailgun control panel, and the CNAME record must be pointing to mailgun.org. | | `clicked` | The email recipient clicked on a link in the email. Click tracking must be enabled in the Mailgun control panel, and the CNAME record must be pointing to mailgun.org. | | `unsubscribed` | The email recipient clicked on the unsubscribe link. Unsubscribe tracking must be enabled in the Mailgun control panel. | | `complained` | The email recipient clicked on the spam complaint button within their email client. Feedback loops enable the notification to be received by Mailgun. | | `stored` | Mail has stored an incoming message. | | `list_member_uploaded` | This event occurs after successfully adding a member to a mailing list. | | `list_member_upload_error` | This even occurs if an error occurs adding a member to a mailing list. | | `list_uploaded` | This event occurs after successfully uploading a large list of members to a mailing list. | You can access Events through a few interfaces: - [Webhooks](/docs/mailgun/user-manual/events/webhooks) (we POST data to your configured URL(s)) - [The Logs API](/docs/mailgun/api-reference/send/mailgun/logs). - The Logs tab of the Control Panel (GUI) A request should define a time range and can specify a set of filters to apply. In response, a page of events is returned along with URLs that can be used to retrieve the next and previous result pages. To traverse the entire range, you should keep requesting the next page URLs returned along with result pages until an empty result page is reached. Both the Next and Previous page URLs are always returned. - Previous Page URL for the First Result Page: If you are on the first page of results and request the previous page, it will return an empty result page because there are no events before the first page. - Next Page URL for the Last Result Page: Similarly, if you are on the last page of results and request the next page, it will return an empty result page because there are no events after the last page. --- # Source: https://documentation.mailgun.com/docs/mailgun/faq/faqs.md # FAQ: Getting Started/ Settings ### Why not just use Sendmail + Postfix + Courier IMAP? You can but you should be aware that there is a constant battle raging between good and evil (i.e., spam) in the email universe. In order to be on the 'good' side of that battle and get your email delivered, there are numerous things you need to do. You need to have the right authentication infrastructure and register your IP and Domain appropriately. Also, you need to have a history of email sending that complies with ESPs rules in order to build a good reputation. Moreover, if you are going to receive, store and host emails, you better be prepared for maintaining this orchestra of software, take care of backups, hardware failures, security patches and monitoring. Stop kidding yourself, it's not 1998 anymore. :-) Here's a classic post, [So You'd Like to Send Some Email (Through Code)](http://blog.codinghorror.com/so-youd-like-to-send-some-email-through-code/), from Jeff Atwood about all of the hurdles in order to properly send email, and that's just sending. ### Can I get multiple Domains and IP Addresses? By default we give you one shared IP address. If you would like a dedicated IP address, simply click on the "Add Dedicated IP" button in the **IP Management** section of the Control Panel. You will need to add a credit card to your account first, though, if you have not already done so. If you want multiple IPs, you can [contact our Support Team](https://app.mailgun.com/app/support). You can create up to 1,000 domains on a paid plan in the Control Panel or through the `Domains API `{.interpreted-text role="ref"}(Free accounts do not include the ability to create a custom domain). ### Do I need a dedicated IP address? It depends on various factors. If you are sending a lot of email (greater than 50k per week), it is a good idea to have a dedicated IP in order to isolate your reputation. If you are sharing your IP, you are sharing your reputation with those other senders. In addition, ESPs limit the total volume per IP, per hour. If you are a high volume sender you should consider a pool of IPs. However, you will have trouble establishing your reputation if you are not sending enough volume consistently from an IP - in this case, a shared IP is preferred. If your email sending is volatile with large spikes of volume, ESPs may assume those large spikes are spam. Also, if your overall volume is too low, they won't acknowledge your reputation. Generally, if you are sending less than 5,000 emails per day, a shared IP may be the right solution. The other thing to consider is using separate IPs for your bulk and transactional mail. There are a couple reasons for this: - Delivery of time-sensitive transactional emails may get queued behind a large batch of bulk/marketing emails. - Your transactional mail will be affected by the reputation created by your bulk/marketing mail. Mailgun's infrastructure mitigates some of the arguments for a dedicated IP address. First of all, we are constantly monitoring our shared IP addresses for any reputation issues. We also allow you to schedule delivery of your emails by using the `o:deliverytime` parameter. This allows you to delay the delivery by using a time in the future and also allows you to jump other messages in your queue (say from a large bulk mailing) by using a delivery time of now. ### How do I pick a domain name for my Mailgun account? The name of an email domain matters most for receiving messages: If your domain name is `mycompany.com` it means you can receive messages sent to `xxx@mycompany.com` Domain names do not matter as much if you're only sending. You can send messages from `sales@mycompany.com` even if your domain name is called `anothercompany.org`. Although, it is best for deliverability if you are using the same domain in the From field that the actual sender is using. There are two types of domains you can configure with Mailgun: - A sandbox subdomain of mailgun.org. Example: `sandboxXX.mailgun.org`. This option allows for quick testing, without having to setup DNS entries. This domain is provisioned automatically with every new account. But you can send only to [authorized recipients](https://help.mailgun.com/hc/en-us/articles/217531258). - Your own domain like `mycompany.com`. This requires you to configure some records at your DNS provider. We provide you with those records and instructions in your Control Panel. If your company's primary domain is `mycompany.com`, we recommend the following domain names for mailgun: > - `mycompany.com`, unless you're already using this name for your corporate email; - `m.mycompany.com` or `mail.mycompany.com`; - `mycompany.net` or `mycompany.org`. Sometimes, it is a good idea to separate the domains for the type of messages you are sending. For example, some companies will use a different domains or subdomains for bulk marketing mailings and transactional or corporate mail in order to keep the reputations separate. It is recommended for all domains to use MX records, as they're a verification step that is commonly used by ISPs. MX Records are also required if you want to receive email at the same subdomain you added to Mailgun. Finally, if you want multiple addresses and you want to direct certain emails to certain IP addresses, you will need to have a unique domain or subdomain for each IP address. In this situation, it's best to [contact our Support Team](https://app.mailgun.com/app/support) to discuss your infrastructure. ### Can I use the same domain name for Mailgun and for Google Apps (or another email server)? Yes, for sending. No, for receiving. Only one email server can receive messages for a given domain name. It could be either Mailgun or Google servers, but not both. However, you can use the same domain for sending at multiple servers. If you'd like to register your Domain at multiple servers for sending but you don't want to receive email at Mailgun, just don't configure your MX records to point to Mailgun. If you are receiving emails elsewhere with your domain, we recommend using a subdomain at Mailgun so you can also receive emails at Mailgun. This helps improve deliverability and allows us to more easily deal with any issues that arise with recipient email servers. ### Can I rename a domain? No, you need to create a new one and delete the old one. It's a good idea to create the new one first. ### What if I need multiple SPF records? If you are using multiple email servers and you want an SPF record for each of them, you should NOT set up a separate TXT record for each. You need to include the different servers in the same record. Below is sample syntax: 'v=spf1 include:myemailserver.com include:mailgun.org ~all' ### How do I know if my DNS records are set up correctly We have a "Check DNS Records Now" button when you click on a domain in the `Domains` tab that will confirm that they are set up correctly and, if not, show the incorrect records in red. You could also use [dig](http://en.wikipedia.org/wiki/Domain_Information_Groper) in your command line interface. ### Do you support SSL/TLS? Only TLS is supported. Support for SSL has been dropped due to the [POODLE security vulnerability](http://status.mailgun.com/incidents/9g4kmgh00y5x). ### Ok, everything is set up, how do I start using Mailgun? Mailgun is primarily a developer's tool so the best way use Mailgun is through our APIs. They are quite [RESTful](http://en.wikipedia.org/wiki/REST) and we've tried to make them as intuitive as possible. Our [Quickstart Guide](https://documentation.mailgun.com/docs/mailgun/quickstart/) is a good place to start and you can also use the [API Reference](https://documentation.mailgun.com/docs/mailgun/api-reference/intro/) for more detail. We also expose a lot of the features through the Control Panel. The [User Manual](https://documentation.mailgun.com/docs/mailgun/user-manual/get-started/) is a good place to get a full overview of all of the capabilities of Mailgun. --- # Source: https://documentation.mailgun.com/docs/mailgun/email-best-practices/feedbackloops.md # Feedback Loops and Spam Complaints Most of the major MBPs (Mailbox Providers) other than Gmail provide feedback loops through which they give you information about spam complaints. Here is a thorough [list from Word to the Wise](https://wordtothewise.com/isp-information/). It is important that you sign up for these feedback loops and pay attention to the feedback you are getting. Ignoring this feedback will lead to MBPs throttling you and eventually blocking you completely. Mailgun registers all of our IPs for these feedback loops. You can access this information through the Control Panel, the API or Webhooks. In addition, we process spam complaints automatically and will stop sending to email addresses after a recipient complains. It is possible to remove addresses from the flagged list in your Control Panel or through the API. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/events/filter-expressions.md # Filter Expression Possible filtering expressions are listed below: | Expression | Description | | --- | --- | | foo bar | Matches field values that contain both term `foo` and term `bar`. | | foo AND bar | Same as above. | | foo OR bar | Matches field values that contain either term `foo` or term `bar`. | | "foo bar" | Matches field values that literally contain `foo bar`. | | NOT foo | Matches field values that do not contain term `foo`. | | >10000 | Matches values that greater than 10000. This filter can be applied to numeric fields only. | | >10000 <20000 | Matches values that are greater than 10000 and less than 20000. This filter can be applied to numeric fields only. | info Note that more than one expression can be used as a filter value and parentheses can be used to specify grouping. E.g.: (Hello AND NOT Rachel) OR (Farewell AND Monica). --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/events/filter-field.md # Filter Field Log Records can be filtered by the following fields: | Filter | Description | | --- | --- | | event | An event type. For a complete list of all events written to the log see the Event Types table below. | | list | The email address of a mailing list the message was originally sent to. | | attachment | A name of an attached file | | from | An email address mentioned in the from MIME header. | | message-id | A Mailgun message id returned by the messages API | | subject | A subject line | | to | An email address mentioned in the MIME header | | size | Message size. Mostly intended to be used with a wide ranger filtering expressions (see below) | | recipient | Specific to stored events, this field tracks all the potential message recipients. | | tags | User defined tags | | severity | Temporary or Permanent. Used to filter events based on severity, if exists. (Currently failed events only) | --- # Source: https://documentation.mailgun.com/docs/mailgun/get-started.md # Welcome to Mailgun #### The email infrastructure platform trusted by developers worldwide Mailgun provides powerful APIs and tools to send, receive, and track emails at scale. Whether you're building transactional emails, marketing campaigns, or complex email workflows, Mailgun handles the infrastructure so you can focus on your application. ## Mailgun Features Mailgun features can be accessed through Mailgun's Control Panel by logging in at https://app.mailgun.com/app/dashboard. Here's a lightweight overview of what Mailgun can do: Email Sending | | **Transactional Emails** | Send automated emails like order confirmations, password resets, and notifications. | | **Bulk Emails** | Efficiently send large volumes of emails with optimized delivery performance. | | **SMTP Integration** | Seamlessly integrate Mailgun with your application via SMTP. | | **Support** | Support for custom templates, mailing lists, etc. | Email Receiving | | Inbound Parsing | Parse incoming emails to your domains and route them to your application with ease. | | Route Management | Define rules for handling incoming emails, such as forwarding to a specific address or storing the email. | Email Tracking | | Open and Click Tracking | Monitor who opens your emails and clicks on links, providing insights into recipient engagement. | | Bounce Tracking | Identify and manage bounced emails to maintain a clean email list. | Analytics and Reporting | | Detailed Reports | Access comprehensive reports on email delivery, open rates, click rates, and more | | Event Tracking | Track specific email events like deliveries, opens, clicks, and bounces for granular insights. | Security and Compliance | | DKIM and SPF | Authenticate your emails to improve deliverability and protect against spoofing. | | DMARC | Implement DMARC policies to monitor and protect your domain from email phishing and spoofing. | | Compliance | Our full list of compliance certificates are available via our [trust portal](https://trust.sinch.com/?product=mailgun). | Domain and IP management tools | IP Pooling | Manage IP pools to optimize email delivery and maintain sender reputation. | | --- | --- | | Suppression Management | Automatically handle unsubscribes, complaints, and bounces to maintain a clean email list. | | Domain Management | Add US or EU based domains, as well as manage their settings and sending. | User Friendly Control Panel | | Web Interface | Manage your email campaigns, view analytics, and configure settings through an intuitive web interface. | Please continue to read through the user manual to see all supported functionality, and if at any point in your journey you have questions or need help, please feel free to contact our Support Team [here](https://app.mailgun.com/support) br [Let's get started!](/docs/mailgun/quickstart) br --- # Source: https://documentation.mailgun.com/docs/mailgun/sdk/go_sdk.md # Golang a img Official Mailgun Go SDK ### Installation If you are using [golang modules](https://go.dev/wiki/Modules) make sure you include the `/v5` at the end of your import paths ```bash $ go get github.com/mailgun/mailgun-go/v5 ``` ### Usage Here's a simple example of how to send an email. As always, please consult the repository readme for full details. ```go package main import ( "context" "fmt" "log" "time" "github.com/mailgun/mailgun-go/v5" ) // Your available domain names can be found here: // (https://app.mailgun.com/mg/sending/domains) var yourDomain = "your-domain-name" // e.g. mg.yourcompany.com // You can find the Private API Key in your Account Menu, under "Account Settings": // (https://app.mailgun.com/settings/api_security) var privateAPIKey = "your-private-key" func main() { // Create an instance of the Mailgun Client mg := mailgun.NewMailgun(privateAPIKey) // When you have an EU domain, you must specify the endpoint: // mg.SetAPIBase(mailgun.APIBaseEU) sender := "sender@mg.yourcompany.com" subject := "Fancy subject!" body := "Hello from Mailgun Go!" recipient := "recipient@example.com" // The message object allows you to add attachments and Bcc recipients message := mg.NewMessage(yourDomain, sender, subject, body, recipient) ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) defer cancel() // Send the message with a 10-second timeout resp, err := mg.Send(ctx, message) if err != nil { log.Fatal(err) } fmt.Printf("ID: %s Resp: %s\n", resp.ID, resp.Message) } ``` --- # Source: https://documentation.mailgun.com/docs/mailgun/email-best-practices/hosting.md # Hosting Mailgun is mostly hosted on dedicated servers, however we use cloud servers for some of the infrastructure (where it makes sense). Mailgun uses dedicated IP addresses in large subnets. We also do background checks and extensive testing on our IP addresses; Because they are in large continuous blocks, they are less likely to be affected by other, external IP addresses. MBPs (Mailbox Providers) and blacklists occasionally block entire subnets if any of the IPs have questionable reputations; This means that if your IP is clean, it might be blocked because of surrounding IPs. Larger subnets mitigate this risk. Large, virtual cloud environments are generally not the best environments for email for a few reasons: - The IP address should be static so that your domain(s) & IP address(es) build a reputation together. Also, some more strict recipients MBPs may require whitelisting your IP address. Unfortunately, these should be IPv4. - The IP address and surrounding IP addresses should have a good reputation. This is rarely the case at large cloud environments due to their ease of use and lax monitoring (which is inviting to spammers). - Mail Transfer Agents should ideally be on real (non-virtual) machines, optimized for I/O. --- # Source: https://documentation.mailgun.com/docs/inboxready/inbox-placement-ir.md # Inbox Placement A seed list is an object that provides the mailing list for your inbox placement test. It also acts as a container for all the results of those tests and will aggregate the stats of all the tests. When you create a seed list you will be provided a mailing list. You may adjust this mailing list as you see fit, but you must send to the `target_email` otherwise a placement test will not be run. ## Generate a seed list ``` POST /v4/inbox/seedlists ``` The available form fields to generate a seed list are as follows: | Field | Description | | --- | --- | | name | The name that you would like to use for this seed list. | | seed_filter | A regular expression that will be applied to addresses in the mailing list. | ```JSON curl -X POST https://api.mailgun.net/v4/inbox/seedlists \ -F 'name=list' \ --user 'api:' ``` Example response for creating a seed list. ```JSON { "kid": "610abd2009b08f382ac86c45", "created_at": "2021-08-04T16:15:28.08Z", "updated_at": "2021-08-04T16:15:28.08Z", "last_result_at": "0001-01-01T00:00:00Z", "target_email": "ibp-12345678-1234-1234-1234-123456789012@domain.com", "sending_domains": [], "has_results": false, "name": "My campaign inbox test", "seed_filter": ".*", "mailing_list": "ibp-12345678-1234-1234-1234-123456789012@domain.com,another@email.com", "delivery_stats": { "all": { "delivered": 0, "missing": 0, "pending": 0, "spam": 0, "inbox": 0, "total": 0, "provider": "all" } }, "results": [] } ``` Field Explanation: | Name | Type | Description | | --- | --- | --- | | kid | string | Unique identifier for a seed list. | | created_at | datetime | Date and time that seed list was created. | | updated_at | datetime | Date and time that seed list was updated. Will update whenever it is changed. | | last_result_at | datetime | Date and time that seed list was updated. Will update whenever a new result comes in. | | target_email | string | The required email address that must be included in a mailing list for an inbox placement test to work. | | sending_domains | array | The list of possible domains that the messages must come from. | | has_results | bool | A flag that is true when results exist for this seed list | | name | string | The name of the seed list | | seed_filter | string | A regular expression value that will be used to filter the list of seeds in the seed list. | | mailing_list | string | A mailing list that contains the target email, and available seeds. | | delivery_stats | object | An object that contains sub-objects that describe delivery stats. See below. | | results | array | An array of results from the seed list's tests. | # Delivery Stats Delivery stats is an object that is included with seed list and results from the API. It is an attribute of the main object that is returned. A sample object: ```JSON "delivery_stats": { "all": { "delivered": 10, "missing": 1, "pending": 0, "spam": 3, "inbox": 6, "total": 10, "provider": "all" }, "yahoo.com": { "delivered": 4, "missing": 1, "pending": 0, "spam": 0, "inbox": 4, "total": 5, "provider": "yahoo.com" }, "gmail.com": { "delivered": 5, "missing": 0, "pending": 0, "spam": 3, "inbox": 2, "total": 5, "provider": "gmail.com" } } ``` Field Explanation: | Name | Type | Description | | --- | --- | --- | | sub-object -"subkey" | object | The sub-object of the main delivery_stats object is divided by provider. There will always be an "all" provider that is the total sum. | | delivered | number | The amount of messages that were received by the system. | | missing | number | The amount of messages that were not received by the required reporting time period. | | pending | number | The amount of messages that have yet to be received within the required reporting time period. | | spam | number | The amount of messages that were detected in the provider's spam folder. | | inbox | number | The amount of messages that were detected in a non-spam folder. | | total | number | The amount of messages that are expected. | | provider | string | The provider that these mailboxes are a part of (identical to key). | ## Results A result is an object summarizing Inbox Placement tests sent to the target_email. ```JSON { "result_id": "12345678-1234-1234-1234-123456789012", "subject": "IBP Test - 1", "sender": "generated@yourdomain.com", "delivery_stats": { "all": { "delivered": 7, "missing": 0, "pending": 0, "spam": 2, "inbox": 5, "total": 7, "provider": "all", "categories": {} } } } ``` Field Explanation: | Name | Type | Description | | --- | --- | --- | | result_id | string | Unique identifier for a received test. | | subject | string | The subject of the email sent to the target_email. | | sender | string | Sender address of the email sent to the target_email. | | delivery_stats | object | An object that contains sub-objects that describe delivery stats. See above. | ## Get all seed lists ``` GET /v4/inbox/seedlists ``` Get a list of all of your seed lists. You can filter this using the available filters. These can be listed from the "Get all available filters for seed lists" endpoint described below. ```JSON curl -s --user 'api:YOUR_API_KEY' -G \ https://api.mailgun.net/v4/seedlists ``` Example response for listing seed lists. ```JSON { "items": [ { "kid": "123456789123456789123456", "created_at": "2021-08-02T23:10:17.915Z", "updated_at": "2021-08-03T17:26:55.629Z", "last_result_at": "2021-08-03T17:26:55.629Z", "target_email": "ibp-12345678-1234-1234-1234-123456789012@domain.com", "sending_domains": [ "mydomain.com" ], "has_results": true, "name": "Inbox Placement Test", "seed_filter": ".*", "mailing_list": "ibp-12345678-1234-1234-1234-123456789012@domain.com,some@where.com", "delivery_stats": { "all": { "delivered": 7, "missing": 0, "pending": 0, "spam": 2, "inbox": 5, "total": 7, "provider": "all" } }, "results": [ { "result_id": "12345678-1234-1234-1234-123456789012", "subject": "IBP Test - 1", "sender": "generated@yourdomain.com", "delivery_stats": { "all": { "delivered": 7, "missing": 0, "pending": 0, "spam": 2, "inbox": 5, "total": 7, "provider": "all", "categories": {} } } } ] } ], "paging": { "first": "http://domain.com/v4/inbox/seedlists?ascending=0&limit=1", "last": "http://domain.com/v4/inbox/seedlists?ascending=1&limit=1", "next": "http://domain.com/v4/inbox/seedlists?ascending=0&cursor=123987123981723987873497&limit=1", "previous": "http://domain.com/v4/inbox/seedlists?ascending=1&cursor=123987123981723987873487&limit=1" }, "total": 32 } ``` Field Explanation: | Name | Type | Description | | --- | --- | --- | | items | array | A list of seed list objects (same fields as above). | | paging | object | A paging sub-object to navigate through sections of data. | | total | number | The total amount of seed lists. | ## **Paging sub-object** The paging sub-object assists with navigating paginated responses. For a variety of reasons the number of items that can be returned in a response has been limited. This object contains the following fields: | Name | Type | Description | | --- | --- | --- | | first | url | A url address to the first item of this set | | last | url | A url address to the last item of this set | | next | url | A url address to the next item of this set | | previous | url | A url address to the previous item of this set | Additionally you can interact with the pagination through a few fields added to the query-string of your request: | Name | Type | Description | | --- | --- | --- | | limit | number | A limit on the number of items that can be returned (defaults to 25) | | offset | number | A the amount of items to "move" by | | ascending | bool | A flag that will set the order of the pagination | | cursor | string | A unique id that can be used as a "pivot" of where you are in the set | | sort | string | The parameter to sort by (EXPERIMENTAL) | Note: cursor and offset may not both be used at the same time ## Get a seed list You can select a single seed list with this endpoint. ``` GET /v4/inbox/seedlists/ibp-seedlist-address@domain.net ``` Example response of getting a single seed list. ```JSON { "kid": "610abd2009b08f382ac86c45", "created_at": "2021-08-04T16:15:28.08Z", "updated_at": "2021-08-04T16:15:28.08Z", "last_result_at": "0001-01-01T00:00:00Z", "target_email": "ibp-seedlist-address@domain.net", "sending_domains": [ "yourdomain.com" ], "has_results": false, "name": "My campaign inbox test", "seed_filter": ".*", "mailing_list": "ibp-seedlist-address@domain.net,another@email.com", "delivery_stats": { "all": { "delivered": 0, "missing": 0, "pending": 0, "spam": 0, "inbox": 0, "total": 0, "provider": "all" } }, "results": [ { "result_id": "12345678-1234-1234-1234-123456789012", "subject": "IBP Test - 1", "sender": "generated@yourdomain.com", "delivery_stats": { "all": { "delivered": 7, "missing": 0, "pending": 0, "spam": 2, "inbox": 5, "total": 7, "provider": "all", "categories": {} } } } ] } ``` | Name | Type | Description | | --- | --- | --- | | kid | string | Unique identifier for a seed list. | | created_at | datetime | Date and time that seed list was created. | | updated_at | datetime | Date and time that seed list was updated. Will update whenever it is changed. | | last_result_at | datetime | Date and time that seed list was updated. Will update whenever a new result comes in. | | target_email | string | The required email address that must be included in a mailing list for an inbox placement test to work. | | sending_domains | array | The list of possible domains that the messages must come from. | | has_results | bool | A flag that is true when results exist for this seed list | | name | string | The name of the seed list | | seed_filter | string | A regular expression value that will be used to filter the list of seeds in the seed list. | | mailing_list | string | A mailing list that contains the target email, and available seeds. | | delivery_stats | object | An object that contains sub-objects that describe delivery stats. See below. | | results | array | An array of results from the seed list's tests. | ## Get all iterable attributes of seed lists You can use this endpoint to find all attributes that are available for listing values of. ``` GET /v4/inbox/seedlists/a ``` | Name | Type | Description | | --- | --- | --- | | attribute | string | A string describing what was selected. | | values | array | A list of attributes that can be retrieved from the API. | ## Get all values of a specific attribute of your seed lists You can use this endpoint to find all the values for a particular attribute. This can be used to produce autocomplete or suggestions from a frontend. ``` GET /v4/inbox/seedlists/a/attribute ``` ```JSON curl -s --user 'api:YOUR_API_KEY' -G \ https://api.mailgun.net/v4/inbox/seedlists/a/ATTRIBUTE ``` Example response of seed list attribute values. ```JSON { "items": { "attribute": "name", "values": [ "Inbox Placement Test", "My email campaign" ] } } ``` | Name | Type | Description | | --- | --- | --- | | attribute | string | A string describing what was selected. | | values | array | A list of attributes that can be retrieved from the API. | ## Get all available filters for seed lists You can use this endpoint to list the available filters for seed lists. ``` GET /v4/inbox/seedlists/\_filters ``` ```JSON { "items": { "attribute": "name", "values": [ "Inbox Placement Test", "My email campaign" ] } } ``` Example response of seed list filters. ```JSON { "supported_filters": { "filters": [ { "parameter": "name", "description": "Get seedlists by name" }, { "parameter": "time_before", "description": "Get seedlists before date" }, { "parameter": "time_after", "description": "Get seedlists after date" } ] } } ``` | Name | Type | Description | | --- | --- | --- | | parameter | string | The key of the parameter you can pass in your query string. | | description | string | A description of the filter | ## Delete a seed list You can delete a seed list with this endpoint. The results under it will not be kept. ``` DELETE /v4/inbox/seedlists/ibp-seedlist-address@domain.net ``` ```JSON curl -s --user 'api:YOUR_API_KEY' -X DELETE -G \ https://api.mailgun.net/v4/inbox/seedlists/TARGET_EMAIL ``` This does not return any value. ## Update a seed list You can update a seed list with this endpoint. Modifying the sending domains or the seed filter will not affect historical results. ``` PUT /v4/inbox/seedlists/ibp-seedlist-address@domain.net ``` Update a seed list. The available form fields are as follows: | Field | Description | | --- | --- | | sending_domains | Update the sending domains of the seed list. You can specify this multiple times. | | name | Update the name of the seed list. | | seed_filter | Update the regular expression that will be applied to addresses in the mailing list. | ```JSON curl -X PUT https://api.mailgun.net/v4/inbox/seedlists/TARGET_EMAIL \ -F 'sending_domains=domain.com' \ --user 'api:' ``` Example Response ```JSON { "kid": "610abd2009b08f382ac86c45", "created_at": "2021-08-04T16:15:28.08Z", "updated_at": "2021-08-04T16:15:28.08Z", "last_result_at": "0001-01-01T00:00:00Z", "target_email": "ibp-seedlist-address@domain.net", "sending_domains": [ "yourdomain.com" ], "has_results": false, "name": "My campaign inbox test", "seed_filter": ".*", "mailing_list": "ibp-seedlist-address@domain.net,another@email.com", "delivery_stats": { "all": { "delivered": 0, "missing": 0, "pending": 0, "spam": 0, "inbox": 0, "total": 0, "provider": "all" } }, "results": [] } ``` | Name | Type | Description | | --- | --- | --- | | kid | string | Unique identifier for a seed list. | | created_at | datetime | Date and time that seed list was created. | | updated_at | datetime | Date and time that seed list was updated. Will update whenever it is changed. | | last_result_at | datetime | Date and time that seed list was updated. Will update whenever a new result comes in. | | target_email | string | The required email address that must be included in a mailing list for an inbox placement test to work. | | sending_domains | array | The list of possible domains that the messages must come from. | | has_results | bool | A flag that is true when results exist for this seed list | | name | string | The name of the seed list | | seed_filter | string | A regular expression value that will be used to filter the list of seeds in the seed list. | | mailing_list | string | A mailing list that contains the target email, and available seeds. | | delivery_stats | object | An object that contains sub-objects that describe delivery stats. See below. | | results | array | An array of results from the seed list's tests. | ## List Results Test results are generated when a message has been received at the `target_email`. If a message is not received at the target email no seed test will be run. Results will contain the status of the monitored mail boxes and will provide stats of the test. ``` GET /v4/inbox/results ``` List all results for your account. | Field | Description | | --- | --- | | sender | Filter results by sender address | | provider | Filter which results show up in seed_results by provider | | subject | Filter results by a subject | | target_email | Filter results by a target_email address | ```JSON curl -s --user 'api:YOUR_API_KEY' -G \ https://api.mailgun.net/v4/inbox/results ``` Example Response ```JSON { "items": [ { "rid": "123456789012345678901234", "result_id": "12345678-1234-1234-1234-123456789012", "keybox_email": "ibp-00410325-1c95-492e-bc35-c19899802494@mailgun.net", "subject": "A subject of things", "sender": "person@domain.com", "name": "Such list", "created_at": "2021-08-03T14:20:40.301Z", "updated_at": "2021-08-03T14:36:53.841Z", "seed_results": [ { "email": "mail@box.com", "provider": "box.com", "destination": "inbox", "state": "delivered", "originating_ip": "123.123.123.123", "tags": [ "inbox" ], "spf": "pass", "dkim": "pass", "dmarc": "pass" } ] } ] } ``` | Name | Type | Description | | --- | --- | --- | | rid | string | Unique identifier for a results. | | keybox_email | string | The target email of the seed list associated with this result. | | subject | string | The subject of the email received by the seed list mailbox (target_email) | | sender | string | The email address of the sender received by the seed list mailbox (target_email). All other results must come from the same sender. | | name | string | The name of the seed list. | | created_at | datetime | Date and time that the results were created. | | updated_at | datetime | Date and time that the results were updated. Will update whenever a mailbox within the test receives mail. | | seed_results | object | A sub-object that contains the status of each individual seed mailbox. | | status | string | Will show "processing" or "complete". | | delivery_stats | object | A sub-object that provides the stats of this result. | ## Seed Results The seed results sub-object will provide the details of the individual seed mail boxes. Field Explanation: | Name | Type | Description | | --- | --- | --- | | email | string | The email address of the mailbox. | | provider | string | The email provider of the mailbox (usually the domain). | | destination | string | Either "inbox" or "spam" | | state | string | Whether or not the mailbox has received a message | | originating_ip | string | The IP address from which the message came from (if available) | | tags | array | The folder, or labels of where the message ended up. | | spf | string | SPF email authentication results (if available). Possible values are "pass", "fail", and "missing/not-set". | | dkim | string | Results from DKIM evaluation (if available). Possible values are "pass", "fail", and "missing/not-set". | | dmarc | string | DMARC email authentication results (if available). Possible values are "pass", "fail", and "missing/not-set". | ## Get Available Result Filters ``` GET /v4/inbox/results/\_filters ``` ```JSON curl -s --user 'api:YOUR_API_KEY' -G \ https://api.mailgun.net/v4/results/_filters ``` Example response of getting the available results filters. ```JSON { "supported_filters": { "filters": [ { "parameter": "senderaddr", "description": "Sender address" }, { "parameter": "subject", "description": "Subject line" }, { "parameter": "provider", "description": "E-mail provider" }, { "parameter": "target_email", "description": "Seedlist target e-mail" }, { "parameter": "time_before", "description": "Get results before date" }, { "parameter": "time_after", "description": "Get results after date" } ] } } ``` ## Get all iterable attributes of results ``` GET /v4/inbox/results/a ``` Example response of getting the result attributes. ```JSON { "items": { "attribute": "available attributes", "values": [ "subject", "sender" ] } } ``` ## Get all values of a specific attribute of your results lists ``` GET /v4/inbox/results/a/attribute ``` ```JSON curl -s --user 'api:YOUR_API_KEY' -G \ https://api.mailgun.net/v4/inbox/results/a/ATTRIBUTE ``` You can use this endpoint to find all the values for a particular attribute. This can be used to produce autocomplete or suggestions from a frontend. Example response of response attribute values. ```JSON { "items": { "attribute": "subject", "values": [ "This is a subject", "We've been trying to contact you", "about your car's extended warranty" ] } } ``` ## Get a specific result ``` GET /v4/inbox/results/UUID ``` ```JSON curl -s --user 'api:YOUR_API_KEY' -G \ https://api.mailgun.net/v4/inbox/results/UUID ``` You can use this endpoint to get a single result. | Name | Type | Description | | --- | --- | --- | | rid | string | Unique identifier for a results. | | keybox_email | string | The target email of the seed list associated with this result. | | subject | string | The subject of the email received by the seed list mailbox (`target_email`) | | sender | string | The email address of the sender received by the seed list mailbox (`target_email`). All other results must come from the same sender. | | name | string | The name of the seed list. | | created_at | datetime | Date and time that the results were created. | | updated_at | datetime | Date and time that the results were updated. Will update whenever a mailbox within the test receives mail. | | seed_results | object | A sub-object that contains the status of each individual seed mailbox. | | status | string | Will show "processing" or "complete". | | delivery_stats | object | A sub-object that provides the stats of this result. | Example response ```JSON { "result": { "rid": "123456789012345678901234", "result_id": "12345678-1234-1234-1234-123456789012", "keybox_email": "ibp-00410325-1c95-492e-bc35-c19899802494@mailgun.net", "subject": "A subject of things", "sender": "person@domain.com", "name": "Such list", "created_at": "2021-08-03T14:20:40.301Z", "updated_at": "2021-08-03T14:36:53.841Z", "seed_results": [ { "email": "mail@box.com", "provider": "box.com", "destination": "inbox", "state": "delivered", "originating_ip": "123.123.123.123", "tags": [ "inbox" ], "spf": "pass", "dkim": "pass", "dmarc": "pass" } ] } } ``` ## Delete results Use this endpoint to delete a result. ``` DELETE /v4/inbox/results/UUID ``` ```JSON curl -s --user 'api:YOUR_API_KEY' -X DELETE -G \ https://api.mailgun.net/v4/inbox/results/UUID ``` This does not return any value. ## Create a test Use this endpoint to create an Inbox Placement test. ``` POST /v4/inbox/tests ``` Field Explanation: | Name | Type | Description | | --- | --- | --- | | from | string | Required. The email address from which the email should be sent. Note, the provided domain must be verified within your Mailgun account. | | subject | string | Required. The subject of the email. | | html | string | Required. The body of the email represented in HTML. | | provider_filter | list | Optional. A list of provider domains. This field can be used to test inbox placement against a subset of provider(s). See the List Providers section for available providers. | | seed_list | string | Optional. The identifier for the seedlist you wish to use. | ```JSON curl -X POST https://api.mailgun.net/v4/inbox/tests \ --data-raw '{ "from": "user@domain.com", "subject": "testSubject", "html": "HTML version of the body" } ' \ --user 'api:' ``` Below is an example of the returned response body. ```JSON { "result_id": "1a066d4a-2207-4240-9e89-9e1a55511f0e", "links": { "results": "https://api.mailgun.net/v4/inbox/results/1a066d4a-2207-4240-9e89-9e1a55511f0e" } } ``` ## List Providers Use this endpoint to retrieve a list of providers available for Inbox Placement testing. ``` GET /v4/inbox/providers ``` Below is an example of the returned response body. ```JSON { "items": [ { "domain": "hotmail.com", "display_name": "Hotmail", "region": "Global", }, { "domain": "gmail.com", "display_name": "Gmail", "region": "Global", }, ... ] } ``` --- # Source: https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready.md # Alerts Our alerting solution is centered around two concepts: events and channels. The occurrence of an event can be configured to trigger an alert. A channel describes the delivery method for an alert. Every configured alert consists of an event type / channel pair. This level of granularity allows alerting to be configured to your exact preference. Version: 0.0.1 ## Servers US Mailgun ``` https://api.mailgun.net ``` EU Mailgun ``` https://api.eu.mailgun.net ``` ## Security ### basicAuth HTTP Basic auth using api:YOUR_API_KEY. See [documentation](https://documentation.mailgun.com/docs/mailgun/api-reference/authentication/) Type: http Scheme: basic ### Inbox_Ready_basicAuth HTTP Basic auth using api:YOUR_API_KEY. See [documentation](https://documentation.mailgun.com/docs/mailgun/api-reference/authentication/) Type: http Scheme: basic ### Domain_Blocklist_Monitoring_basicAuth HTTP Basic auth using api:YOUR_API_KEY. See [documentation](https://documentation.mailgun.com/docs/mailgun/api-reference/authentication/) Type: http Scheme: basic ### Spamtraps_Analytics_Service_basicAuth HTTP Basic auth using api:YOUR_API_KEY. See [documentation](https://documentation.mailgun.com/docs/mailgun/api-reference/authentication/) Type: http Scheme: basic ### Inbox_Placement_Testing_basicAuth HTTP Basic auth using api:YOUR_API_KEY. See [documentation](https://documentation.mailgun.com/docs/mailgun/api-reference/authentication/) Type: http Scheme: basic ### Maverick_Score_basicAuth HTTP Basic auth using api:YOUR_API_KEY. See [documentation](https://documentation.mailgun.com/docs/mailgun/api-reference/authentication/) Type: http Scheme: basic ### DMARC_Reports_basicAuth HTTP Basic auth using api:YOUR_API_KEY. See [documentation](https://documentation.mailgun.com/docs/mailgun/api-reference/authentication/) Type: http Scheme: basic ### reputationanalytics_basicAuth HTTP Basic auth using api:YOUR_API_KEY. See [documentation](https://documentation.mailgun.com/docs/mailgun/api-reference/authentication/) Type: http Scheme: basic ## Download OpenAPI description [Alerts](https://documentation.mailgun.com/_spec/docs/inboxready/api-reference/optimize/inboxready.yaml) ## Domains ### Returns Domains on Mailgun Optimize services - [GET /v1/inboxready/domains](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/domains/get-v1-inboxready-domains.md): Will return details on an Mailgun Optimize Domain. If no Domain is provided, then a list of all Mailgun Optimize Domains on an account will be returned. ### Add a single domain to an account - [POST /v1/inboxready/domains](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/domains/post-v1-inboxready-domains.md) ### Deletes a single domain from an account - [DELETE /v1/inboxready/domains](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/domains/delete-v1-inboxready-domains.md) ### Queues a domain to be processed for verification - [PUT /v1/inboxready/domains/verify](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/domains/put-v1-inboxready-domains-verify.md) ## DMARC Reports DMARC reporting provides valuable insights into your infrastructure, helping you identify potential issues like senders, misconfigured email servers, or phishing attempts. ### Retrieves the DMARC DNS records to be used for configuration - [GET /v1/dmarc/records/{domain}](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/dmarc-reports/get-v1-dmarc-records-domain-.md) ### Checks if DMARC has been setup for user - [GET /v1/dmarc/setup](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/dmarc-reports/get-v1-dmarc-setup-.md) ### Gets referral link to redsift - [POST /v1/dmarc/referral](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/dmarc-reports/post-v1-dmarc-referral-.md) ### Retrieves the list of domains that have DMARC monitoring. - [GET /v1/dmarc/domains](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/dmarc-reports/get-v1-dmarc-domains-.md) ### Retrieve DMARC reporting data for a domain. - [GET /v1/dmarc/domains/{domain}](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/dmarc-reports/get-v1-dmarc-domains-domain-.md) ### Retrieve DMARC reporting data from a specific source. - [GET /v1/dmarc/domains/{domain}/s/{source}](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/dmarc-reports/get-v1-dmarc-domains-domain-s-source-.md) ### Retrieve DMARC reporting data for a hostname. - [GET /v1/dmarc/domains/{domain}/s/{source}/h/{host}](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/dmarc-reports/get-v1-dmarc-domains-domain-s-source-h-host-.md) ### Retrieve DMARC reporting data for an IP Address. - [GET /v1/dmarc/domains/{domain}/s/{source}/h/{host}/ip/{ip}](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/dmarc-reports/get-v1-dmarc-domains-domain-s-source-h-host-ip-ip-.md) ## Inbox Placement Inbox Placement testing allows you to see the likely deliverability of your email campaigns. ### List Seed Lists - [GET /v4/inbox/seedlists](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/inbox-placement/get-v4-inbox-seedlists.md) ### Generate a New Seed List - [POST /v4/inbox/seedlists](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/inbox-placement/post-v4-inbox-seedlists.md) ### List Available Attributes for Seed Lists - [GET /v4/inbox/seedlists/a](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/inbox-placement/get-v4-inbox-seedlists-a.md) ### Get List of Values for Seed List Attribute - [GET /v4/inbox/seedlists/a/{attribute}](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/inbox-placement/get-v4-inbox-seedlists-a--attribute-.md) ### Get List of Available Seed List Filters - [GET /v4/inbox/seedlists/_filters](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/inbox-placement/get-v4-inbox-seedlists--filters.md) ### Get Seed List - [GET /v4/inbox/seedlists/{address}](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/inbox-placement/get-v4-inbox-seedlists--address-.md) ### Update Seed List - [PUT /v4/inbox/seedlists/{address}](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/inbox-placement/put-v4-inbox-seedlists--address-.md) ### Delete a Seed List - [DELETE /v4/inbox/seedlists/{address}](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/inbox-placement/delete-v4-inbox-seedlists--address-.md) ### List Results - [GET /v4/inbox/results](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/inbox-placement/get-v4-inbox-results.md): Get the details for all placement test results. ### List Available Attributes for Results - [GET /v4/inbox/results/a](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/inbox-placement/get-v4-inbox-results-a.md): The attributes that can have values listed (for autocomplete). ### Get List of Values for a Result Attribute - [GET /v4/inbox/results/a/{attribute}](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/inbox-placement/get-v4-inbox-results-a--attribute-.md): For the given attribute list the known values (for autocomplete). ### List available filters for Results - [GET /v4/inbox/results/_filters](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/inbox-placement/get-v4-inbox-results--filters.md): The filters that can be used when querying for results. ### Get Result Details - [GET /v4/inbox/results/{result}](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/inbox-placement/get-v4-inbox-results--result-.md): Get the details for a single result. ### Delete Result - [DELETE /v4/inbox/results/{result}](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/inbox-placement/delete-v4-inbox-results--result-.md): Delete the result and all associated information. ### Get Result Sharing Status - [GET /v4/inbox/sharing/{result}](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/inbox-placement/get-v4-inbox-sharing--result-.md): The sharing status of a result. ### Update Result Sharing Status - [PUT /v4/inbox/sharing/{result}](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/inbox-placement/put-v4-inbox-sharing--result-.md): Change the sharing status of a result or create a new share URL ### Get Result by a Share ID - [GET /v4/inbox/sharing/public/{shareid}](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/inbox-placement/get-v4-inbox-sharing-public--shareid-.md): Get a result by the share ID. ### Run Inbox Placement Test - [POST /v4/inbox/tests](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/inbox-placement/post-v4-inbox-tests.md): Create and run a new inbox placement test. Either 'html' or 'template_name' field should be provided. 'variables' are Template variables, which could be used in html or template. You can use next recipient variables inside Template variables, which will be filled for every seed automatically: %recipient.first_name%, %recipient.last_name%. ### List Email Providers - [GET /v4/inbox/providers](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/inbox-placement/get-v4-inbox-providers.md): List all available email providers. ## Spam Traps Monitoring Our spam trap monitoring service surfaces how much of your email is being sent to known spam traps. ### Get Spam Trap Hits - [GET /v1/spamtraps](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/spam-traps-monitoring/get-v1-spamtraps.md): Use this endpoint to understand how much of your mail being sent to known spam traps. This endpoint returns daily spam trap hit counts for a provided timerange, categorized by trap type. ## Email Health Score ### Get Email Health score and rates for account and subaccounts - [GET /v1/maverick-score/total](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/email-health-score/get-v1-maverick-score-total.md) ### List Email Health score and rates grouped by domains/ips/subaccounts/timestamps - [GET /v1/maverick-score/grouped](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/email-health-score/get-v1-maverick-score-grouped.md) ## IP Blocklist Monitoring ### Lists monitored IP addresses - [GET /v1/inboxready/ip_addresses](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/ip-blocklist-monitoring/get-v1-inboxready-ip-addresses.md) ### Register an IP address - [POST /v1/inboxready/ip_addresses](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/ip-blocklist-monitoring/post-v1-inboxready-ip-addresses.md) ### Get the IP address - [GET /v1/inboxready/ip_addresses/{ip}](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/ip-blocklist-monitoring/get-v1-inboxready-ip-addresses--ip-.md) ### Update the IP address - [PUT /v1/inboxready/ip_addresses/{ip}](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/ip-blocklist-monitoring/put-v1-inboxready-ip-addresses--ip-.md) ### Removes IP from monitoring - [DELETE /v1/inboxready/ip_addresses/{ip}](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/ip-blocklist-monitoring/delete-v1-inboxready-ip-addresses--ip-.md) ## Domain Blocklist Monitoring Blocklist Monitoring enables you to keep an eye on your reputation. Monitor your domains against our curated list of blocklist providers to make sure you aren't being blocked. ### Get Monitored Domains - [GET /v1/monitoring/domains](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/domain-blocklist-monitoring/get-v1-monitoring-domains.md): Gets all domains that are being monitored for blocklisting ### Get All Events - [GET /v1/monitoring/domains/events](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/domain-blocklist-monitoring/get-v1-monitoring-domains-events.md): Get all events for all domains monitored ### Get Lists Domain is Listed in - [GET /v1/monitoring/domains/{domain}/blocklists](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/domain-blocklist-monitoring/get-v1-monitoring-domains--domain--blocklists.md): Get blocklists that the domain is listed in ### Get Events for Domain - [GET /v1/monitoring/domains/{domain}/events](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/domain-blocklist-monitoring/get-v1-monitoring-domains--domain--events.md): Get events for a specific domain ## Google Postmaster Tools This API provides access to Google Postmaster data. ### Get GPT Domain - [GET /v1/reputationanalytics/gpt/domains/{domain}](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/google-postmaster-tools/get-v1-reputationanalytics-gpt-domains--domain-.md): Returns domain records for a single domain on the account. Each domain record is for a single domain on a single day. ### Get GPT Domains - [GET /v1/reputationanalytics/gpt/domains](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/google-postmaster-tools/get-v1-reputationanalytics-gpt-domains.md): Returns a list of all domain records for an account. Each domain record is for a single domain on a single day. ### Get GPT Domains - [GET /v1/reputationanalytics/gpt/domains_list](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/google-postmaster-tools/get-v1-reputationanalytics-gpt-domains-list.md): Returns a list of all domains for an account ### Get GPT FBL - [GET /v1/reputationanalytics/gpt/domainsfbl](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/google-postmaster-tools/get-v1-reputationanalytics-gpt-domainsfbl.md): Returns the FBL for the account or domain ### Get GPT FBL - [GET /v1/reputationanalytics/gpt/domainsfbl/{domain}](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/google-postmaster-tools/get-v1-reputationanalytics-gpt-domainsfbl--domain-.md): Returns the FBL for the account or domain ### Get GPT Address - [GET /v1/reputationanalytics/gpt/addresses/{address}](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/google-postmaster-tools/get-v1-reputationanalytics-gpt-addresses--address-.md): Returns address records for an single address on the account. Each address record is for a single address on a single day. ### Get GPT Addresses - [GET /v1/reputationanalytics/gpt/addresses](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/google-postmaster-tools/get-v1-reputationanalytics-gpt-addresses.md): Returns a list of all address records for an account. Each address record is for a single address on a single day. ### Get all GPT Addresses - [GET /v1/reputationanalytics/gpt/addresses_list](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/google-postmaster-tools/get-v1-reputationanalytics-gpt-addresses-list.md): Returns a list of all addresses for an account ### Get GPT Domain Addresses - [GET /v1/reputationanalytics/gpt/domains/{domain}/addresses](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/google-postmaster-tools/get-v1-reputationanalytics-gpt-domains--domain--addresses.md): Returns a list of all address records for an account belonging to a specific domain. Each address record is for a single address on a single day. ### Get GPT Summary - [GET /v1/reputationanalytics/gpt/summary](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/google-postmaster-tools/get-v1-reputationanalytics-gpt-summary.md): Returns a list of all summary records for an account. Each record is for a single domain's summary and error summary data. ### Get GPT Domains Summary - [GET /v1/reputationanalytics/gpt/summary/domains](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/google-postmaster-tools/get-v1-reputationanalytics-gpt-summary-domains.md): Returns a list of all domain summary records for an account. Each record is for a single domain's summary data. ### Get GPT Domains Error Summary - [GET /v1/reputationanalytics/gpt/summary/errors](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/google-postmaster-tools/get-v1-reputationanalytics-gpt-summary-errors.md): Returns a list of all domain error summary records for an account. Each record is for a single domain's error summary data. ### Get GPT Addresses Summary - [GET /v1/reputationanalytics/gpt/summary/addresses](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/google-postmaster-tools/get-v1-reputationanalytics-gpt-summary-addresses.md): Returns a list of all address summary records for an account. Each record is for a single address's summary data. ## Microsoft SNDS This API provides access to Microsoft SNDS data. ### Get SNDS Address Info - [GET /v1/reputationanalytics/snds](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/microsoft-snds/get-v1-reputationanalytics-snds.md): Returns a list of all address summary records for an account. Each record is for a single address's summary data. ### Get SNDS Address Info - [GET /v1/reputationanalytics/snds/{ip}](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/microsoft-snds/get-v1-reputationanalytics-snds--ip-.md): Returns a list of all address summary records for an account and a single address ## Alerts ### List events - [GET /v1/alerts/events](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/alerts/get-v1-alerts-events.md): The current list of events that you can chose to receive alerts for. ### Add Alert - [POST /v1/alerts/settings/events](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/alerts/post-v1-alerts-settings-events.md): Use this endpoint to add new alert settings record. ### Webhooks This section covers details around consuming Mailgun Optimize alerts via webhooks. If you are familiar with Mailgun Send webhooks, there is a lot of overlapping similarity, however, there are also a few minor nuances to account for. #### Securing Webhooks HMAC is used to verified to integrity as well as the authenticity of received webhooks. To verify the origin of a webhook: 1. Encode the webhook’s entire POST request body with the HMAC algorithm (using your webhook signing key and SHA256 digest mode) 2. Compare the resulting hexdigest to the signature provided in the POST request’s X-Sign header. NOTE: If you’re consuming Mailgun Send webhooks, please note that your Mailgun Send webhook signing key differs from your Mailgun Optimize alerts webhook signing key. Your Mailgun Optimize alerts webhook signing key is available within the Mailgun Optimize UI. #### Webhook URL Validation When adding or updating a webhook URL for alerts, we will ensure the endpoint is reachable by sending a GET request to the provided URL. If a 200 response is not returned from your endpoint, the request will be rejected and your alert setting will not be saved. We intentionally chose to send a GET request instead of a POST when validating URLs so that your webhook endpoint does not have to account for test requests. Additionally, when a POST request is sent to your webhook URL, if a 2xx is not returned, we will attempt retries via an exponential backoff strategy for up to ~8 hours. If the max retry count is reached, the alert will be disabled and the related alert settings record’s disabled_at field will be populated. ### Update Alert - [PUT /v1/alerts/settings/events/{id}](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/alerts/put-v1-alerts-settings-events--id-.md): Use this endpoint to update an existing alert setting record. NOTE: When updating a webhook alert, we will ensure the endpoint is reachable by sending a GET request to the provided URL. If a 200 response is not returned, a 400 will be returned and the alert setting update will be rejected. ### Remove Alert - [DELETE /v1/alerts/settings/events/{id}](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/alerts/delete-v1-alerts-settings-events--id-.md) ### List Alerts - [GET /v1/alerts/settings](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/alerts/get-v1-alerts-settings.md): This endpoint returns a list of all configured alert settings for your account. ### Update Slack settings - [PUT /v1/alerts/settings/slack](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/alerts/put-v1-alerts-settings-slack.md) ### Delete Slack settings - [DELETE /v1/alerts/settings/slack](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/alerts/delete-v1-alerts-settings-slack.md): Delete Slack settings and Slack event settings for the Mailgun account. To revoke the Slack access token, use DELETE /v1/alerts/slack/oauth. To completely remove the Slack App from Slack Workspace, go into App Configuration in Slack. ### Reset Webhook Signing Key - [PUT /v1/alerts/settings/webhooks/signing_key](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/alerts/put-v1-alerts-settings-webhooks-signing-key.md) ### Test webhook - [POST /v1/alerts/webhooks/test](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/alerts/post-v1-alerts-webhooks-test.md): Sends test webhook request to specified url with dummy data. ### Test message - [POST /v1/alerts/email/test](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/alerts/post-v1-alerts-email-test.md): Sends test message to emails with dummy data. ### Test message - [POST /v1/alerts/slack/test](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/alerts/post-v1-alerts-slack-test.md): Sends test message to slack channels with dummy data. ### Revoke Slack access token - [DELETE /v1/alerts/slack/oauth](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/alerts/delete-v1-alerts-slack-oauth.md): Revoke Slack access token, delete Slack settings and Slack event settings. NOTE: All Mailgun accounts connected to the same Slack workspace share the same token. To completely remove the Slack App from Slack Workspace, go into App Configuration in Slack. ### Get Slack channel - [GET /v1/alerts/slack/channels/{id}](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/alerts/get-v1-alerts-slack-channels--id-.md): Returns Slack channel. ### List Slack channels - [GET /v1/alerts/slack/channels](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready/alerts/get-v1-alerts-slack-channels.md): List Slack channels for the connected Slack workspace. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/internationalization/internationalization.md # Internationalization Internationalization Domain Names (IDN) Mailgun's Messages API supports sending to addresses that use internationalized domain names in the `to` and `from` fields. When necessary, Mailgun will automatically convert the domains to the ADCII equivalent using [Punycode](https://en.wikipedia.org/wiki/Punycode). Note: Currently, sending domains cannot be created using non-ASCII characters. Internationalized Email Addresses (SMTPUTF8) Mailgun supports internationalized email addresses though the use of the SMTPYTF8 extension. An Internationalized email address will contain a non-ASCII character in the local-part portion of the email address and may also use an internationalized domain name. Mailgun supports internationalized email addresses in the following portions of our product: - Outgoing Messages (HTTP API) - Email Verification - Suppressions Lists Note: Match\recipient and forward action are supported for domains using international characters / punycode. However, sending to a punycode domain is not supported. To send messages to an internationalized email address, the receiving mailbox provider must support the SMTPUTF8 extension --- # Source: https://documentation.mailgun.com/docs/inboxready/intro-ir.md # Mailgun Optimize User's Guide ## Introduction This section documents the API endpoints that support features under the [Mailgun Optimize](https://www.mailgun.com/products/inbox/inboxready) (Formerly InboxReady) offering. The Mailgun Optimize deliverability suite was built to be used seamlessly alongside Mailgun's email sending platform. As such, Mailgun and Mailgun Optimize share the same underlying API infrastructure, which includes authentication, REST conformity, and more. To understand the basics of the API or to get started, see this [Introduction](/docs/mailgun/api-reference/api-overview). --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/intro.md # Mailgun User Manual 📚 The Mailgun User Manual is your comprehensive guide to using Mailgun's email platform. It covers everything you need to know to send, receive, and track emails through Mailgun's APIs and web interface, from basic setup and domain configuration to advanced features like templates, webhooks, and analytics. Whether you're integrating email into your application or managing email campaigns, this manual provides step-by-step instructions, code examples, and best practices to help you get the most out of Mailgun's email services. --- # Source: https://documentation.mailgun.com/docs/mailgun/sdk/introduction.md # SDKs Mailgun offers a variety of SDKs designed to simplify email integration for developers. Our SDKs support multiple programming languages, allowing you to seamlessly send, receive, and track emails within your applications. Go Node.js PHP Java Ruby Python --- # Source: https://documentation.mailgun.com/docs/inboxready/ip-blocklist-ir.md # IP Blocklist Monitoring [Blocklist Monitoring](https://www.mailgun.com/products/inbox/deliverability/blocklist-monitoring-service/) enables you to keep an eye on your reputation. Monitor every IP address you have against our curated list of blocklist providers to make sure you aren't being blocked. Monitored blocklists include: - SpamCop - CBL - Spamhaus SBL - Spamhaus PBL - Spamhaus XBL - Barracuda - Senderscore BL ## Add IP This endpoint allows IP addresses to be registered for blocklist monitoring. ``` POST /v1/inboxready/ip\_addresses ``` The available JSON request fields are as follows: | Field | Description | | --- | --- | | ip | Required. The IP address you wish to add. Note that only IPv4 format is supported. | | ip_pool | Optional. Use this field to specify an IP pool. | | description | Optional. Use this field to provide a description for you IP address. | Example 201 response: ```JSON { "ip": "127.0.0.1", "ip_pool": "", "description": "", "state": "healthy", "listed": [] } ``` ## Read IP This endpoint allows you to retrieve the current health status of a single IP address. ``` GET /v1/inboxready/ip\_addresses/{ip} ``` Example 200 response: ```JSON { "ip": "127.0.0.1", "ip_pool": "", "description": "", "state": "listed", "listed": [ { "list":"cbl.abuseat.org", "name":"CBL", "first_seen":"2022-06-24T04:19:43.212Z", "last_seen":"2022-06-28T16:43:38.954Z", "delist_requested_at":"0001-01-01T00:00:00Z", "comments":["https://www.spamhaus.org/query/ip/127.0.0.1"] }, ... ] } ``` See below for an explanation of the health details returned in the response body: | Field | Description | | --- | --- | | state | This field describes IP's current state of health. Possible values include "healthy" and "listed". If the IP exists on any monitored blocklists, state will be "listed". | | listed | This field contains a list of blocklists where your IP is currently listed. | ## List IPs This endpoint allows you to retrieve a list of monitored IP addresses including their information about their health statuses. ``` GET /v1/inboxready/ip\_addresses ``` Example 200 response: ```JSON { "items": [ { "ip": "127.0.0.1", "ip_pool": "", "description": "", "state": "listed", "listed": [ { "list":"cbl.abuseat.org", "name":"CBL", "first_seen":"2022-06-24T04:19:43.212Z", "last_seen":"2022-06-28T16:43:38.954Z", "delist_requested_at":"0001-01-01T00:00:00Z", "comments":["https://www.spamhaus.org/query/ip/127.0.0.1"] }, ... ] }, { "ip": "124.124.124.124", "ip_pool": "", "description": "", "state": "healthy", "listed": [] }, ... ] } ``` See below for an explanation of the health details returned in the response body: | Field | Description | | --- | --- | | state | This field describes IP's current state of health. Possible values include "healthy" and "listed". If the IP exists on any monitored blocklists, state will be "listed". | | listed | This field contains a list of blocklists where your IP is currently listed. | ## Update IP Use this endpoint to update IP address attributes. ``` PUT /v1/inboxready/ip\_addresses/{ip} ``` The available JSON request fields are as follows: | Field | Description | | --- | --- | | ip_pool | Optional. Use this field to specify an IP pool. | | description | Optional. Use this field to provide a description for you IP address. | Example 200 response: ```JSON { "ip": "127.0.0.1", "ip_pool": "", "description": "", "state": "healthy", "listed": [] } ``` ## Remove IP Use this endpoint to remove an IP address from blocklist monitoring. A 204/No-Content response will be returned on success. ``` DELETE /v1/inboxready/ip\_addresses/{ip} ``` ## Blocklist Events This endpoint returns blocklisted and delisted event data for your monitored IP addresses. ``` GET /v1/blocklist-monitoring/events ``` The available filter parameters are as follows: | Field | Description | | --- | --- | | timerangeStart | Optional. An ISO8601 format timestamp specifying the start of your desired timerange. | | timerangeEnd | Optional. An ISO8601 format timestamp specifying the end of your desired timerange. | | ip | Optional. Use to filter events by specific IP address. | | blocklist | Optional. Use to filter events by specific blocklist. | | event | Optional. Use to filter events by event type. Accepted values include [ip_listed, ip_delisted]. | | limit | Optional. Defaults to 10. Minimum accepted value is 10 and maximum accepted value is 50. | Example 200 response: ```JSON { "items":[ { "ip":"123.123.123.123", "ip\_pool":"", "timestamp":"2022-01-01T12:14:16-04:00", "event":"ip\_delisted", "blocklist":"pbl.spamhaus.org", }, { "ip":"123.123.123.123", "ip\_pool":"", "timestamp":"2022-01-01T12:12:12-04:00", "event":"ip\_listed", "blocklist":"pbl.spamhaus.org", }, ... ], "paging":{ ... } } ``` ## Monitored Blocklists This endpoint returns the blocklists monitored by InboxReady. ``` GET /v1/blocklist-monitoring/blocklists ``` Example 200 response: ```JSON { "items":[ { "blocklist":"b.barracudacentral.org", "name":"Barracuda", }, { "blocklist":"bl.score.senderscore.com", "name":"Senderscore BL", }, ... ], } ``` ## Alerts Use our alerting platform to be notified when your monitored IPs are blocklisted. To learn more, see the [alerting documentation](/docs/inboxready/alerts-ir) --- # Source: https://documentation.mailgun.com/docs/mailgun/email-best-practices/ip_address.md # IP Addresses and Sending Volume Mailgun offers both shared and dedicated IPs. We are constantly monitoring the traffic on these IPs, so even for shared IPs, you can feel comfortable knowing that your reputation is not being unduly influenced by others. We also offer pools of IPs for high volume senders. In addition, we have queuing algorithms that gradually warm up your IPs. Our sending rates automatically increase over time as your IP warms up. Finally, we separate our sending queues for each domain you set up at Mailgun, which mitigates the need for multiple IPs for different types of traffic. If you are sending a lot of email (greater than 50K per week), it is best to isolate your reputation by having a dedicated IP address. When you use a shared IP, you are sharing your reputation with those other senders. In addition, MBPs (Mailbox Providers) rate limit your emails based on the IP. So if you are a high volume sender, you should consider getting a pool of IPs. However, your reputation can also be hurt if you are not sending enough volume consistently from an IP so it's a tricky balance. If your email sending is volatile with large spikes of volume, MBPs may assume those large spikes are spam. Also, if you overall volume is too low, they won't acknowledge your reputation. Generally, if you are sending less than 5,000 emails per day, a shared IP may be the right solution. The other thing to consider is using separate IPs for your bulk and transactional mail if you are sending high volumes of email. There are a couple reasons for this: - Delivery of time-sensitive transactional emails may get queued behind a large batch of bulk/marketing emails. - Your transactional mail will be affected by the reputation created by your bulk/marketing mail. Even if you have a clean IP address, you need to warm up the IP gradually. This means sending emails at a low rate initially and then gradually increasing that rate, taking into account MBP feedback. If you send a ton of emails right away, they will get filtered or dropped by the MBPs. In some cases, they won't even tell you they are dropping them. --- # Source: https://documentation.mailgun.com/docs/mailgun/sdk/java_sdk.md # Java a img Official Mailgun Java SDK ### Installation To run the SDK, you will need **Java 1.8+**. The recommended way to use the **Mailgun Java SDK** in your project: Add the following to your `pom.xml`: ```xml ... com.mailgun mailgun-java 1.1.x ... ``` Gradle Groovy DSL ```xml implementation 'com.mailgun:mailgun-java:1.1.3' ``` ### Usage Here's a simple example on how to send an email. As always, please consult the repository readme for full details. ```java Message message = Message.builder() .from(EMAIL_FROM) .to(USER_EMAIL) .subject(SUBJECT) .text(TEXT) .build(); MessageResponse messageResponse = mailgunMessagesApi.sendMessage(DOMAIN, message); ``` --- # Source: https://documentation.mailgun.com/docs/mailgun/api-reference/lower-bounce-rate.md # How to lower your bounce rate Mailgun has thresholds in place that if exceeded will result in a domain being temporarily disabled. These limits are in place to **protect your email reputation** in case your system is compromised by a spammer or someone in your organization makes a large mistake. If you do not have a good reputation tied to your domain and IP address, your email will not reach your recipients' inboxes. The number one reason we see people get blocked is because they have a **bad mailing list**. Most of these lists have bad email addresses and include spam traps. ESPs are good at recognizing bad mailing lists. You can check your [logs](https://app.mailgun.com/app/logs) to see emails that are bouncing and check your [bounce list](https://app.mailgun.com/app/suppressions) for emails that we have stopped sending to as a result of bounces. ## Best practices for lowering bounce rates 1. If you think your application has been compromised, change your SMTP credentials or API key through the [Mailgun control panel](https://app.mailgun.com/app/dashboard). 2. Clean your mailing list of invalid email addresses. 3. Only send emails to recipients that have signed up to receive them. 4. Verify the email address is correct with a confirmation email (aka, [confirmed opt-in](http://en.wikipedia.org/wiki/Opt-in_email)). 5. We recommend using our [Email Validation API](https://documentation.mailgun.com/docs/validate/api-overview) at the point of signup to reduce invalid email addresses. 6. **Don't** purchase your list or scrape websites for emails. If your domain does get disabled, [contact support](https://app.mailgun.com/app/support) after you have made the recommended changes above so we can re-enable your domain. --- # Source: https://documentation.mailgun.com/docs/mailgun/api-reference/mailboxes.md # Mailboxes {#api-mailboxes} Mailgun Mailbox API allows you to programmatically create as many mailboxes as you wish. The incoming messages can be stored in mailboxes. There is no HTTP API to fetch the contents of the mailboxes: you need to use POP3 or IMAP protocols for that. ::: warning ::: title Warning ::: Mailboxes is a legacy feature of Mailgun that is no longer offered to new customers. Please utilize the Store() endpoint instead. ::: ::: warning ::: title Warning ::: Currently Mailgun stores mailbox passwords in plain text. This is not acceptable for some applications. We are considering changing this in the future. ::: ``` GET //mailboxes ``` Fetches the list of mailboxes for a given domain. ::: {.container .ptable} Parameter Description limit Maximum number of records to return. (100 by default) skip Number of records to skip. (0 by default) ::: ``` POST //mailboxes ``` Creates a new mailbox for a supplied domain ::: {.container .ptable} Parameter Description mailbox The name of the mailbox, for example `bob.bar` password Mailbox password. ::: ``` PUT //mailboxes/ ``` Updates the specified mailbox. Currently only the password can be changed. ::: {.container .ptable} Parameter Description password Mailbox password. ::: ``` DELETE //mailboxes/ ``` Deletes the given mailbox. ## Examples Listing all mailboxes: Sample response: ``` { "total_count": 2, "items": [ { "size_bytes": 0, "created_at": "Tue, 27 Sep 2011 20:24:22 GMT", "mailbox": "postmaster@samples.mailgun.org" }, { "size_bytes": 0, "created_at": "Thu, 06 Oct 2011 10:22:36 GMT", "mailbox": "user@samples.mailgun.org" } ] } ``` Creating a new mailbox: Sample response: ``` { "message": "Created 1 mailboxes" } ``` Updating the password for a given mailbox: Sample response: ``` { "message": "Password changed" } ``` Deleting a given mailbox: Sample response: ``` { "message": "Mailbox has been deleted", "spec": "alice@samples.mailgun.org" } ``` --- # Source: https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun.md # Mailgun API Mailgun API defined by OpenAPI Specification (OAS) 3.1.0 Version: 3.0.0 ## Servers US Mailgun ``` https://api.mailgun.net ``` EU Mailgun ``` https://api.eu.mailgun.net ``` ## Security ### basicAuth HTTP Basic auth using api:YOUR_API_KEY. See [documentation](https://documentation.mailgun.com/docs/mailgun/api-reference/authentication/) Type: http Scheme: basic ## Download OpenAPI description [Mailgun API](https://documentation.mailgun.com/_spec/docs/mailgun/api-reference/send/mailgun.yaml) ## Messages Send email two ways via our REST API: 1. Send emails using MIME format using a MIME building library 2. Submit the individual parts (Text, html, attachments, etc.) Reminder: You can also send email via SMTP with Mailgun. Please reference the user manual. ### Send an email - [POST /v3/{domain_name}/messages](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/messages/post-v3--domain-name--messages.md): Pass the components of the messages such as To, From, Subject, HTML, text parts, attachments, etc. Mailgun will build a MIME representation of the message and send it. In order to send you must provide one of the following parameters: 'text', 'html', 'amp-html' or 'template'. Important: Send options (parameters starting with o:, h:, v:, or t:) are limited to 16KB total ### Send an email in MIME format - [POST /v3/{domain_name}/messages.mime](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/messages/post-v3--domain-name--messages-mime.md): Build a MIME string yourself using a MIME library and submit it to Mailgun. Important: Send options (parameters starting with o:, h:, v:, or t:) are limited to 16KB total ### Retrieve a stored email - [GET /v3/domains/{domain_name}/messages/{storage_key}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/messages/get-v3-domains--domain-name--messages--storage-key-.md): Event(s) created from sending an email with Mailgun will contain a to use to retrieve the email. ### Resend an email - [POST /v3/domains/{domain_name}/messages/{storage_key}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/messages/post-v3-domains--domain-name--messages--storage-key-.md) ### Get messages queue status - [GET /v3/domains/{name}/sending_queues](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/messages/get-v3-domains--name--sending-queues.md): Provides default and scheduled message queue information. ### Delete scheduled and undelivered mail - [DELETE /v3/{domain_name}/envelopes](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/messages/delete-v3--domain-name--envelopes.md): Deletes all scheduled and undelivered mail from the domain queue. This endpoint must be called on the same storage API host as the mail's generated storage URL. e.g. https://storage-us-east4.api.mailgun.net/v3/example.com/envelopes The storage hosts are: , , and . ## Domains Domains API manages domains, domain keys and DNS verification. ### Get domains - [GET /v4/domains](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/domains/get-v4-domains.md): Get the list of domains. Can be filtered by state or authority. Sorting is optional. The list is paginated and limited to 1000 items per page. ### Create a domain - [POST /v4/domains](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/domains/post-v4-domains.md): Creates a domain for sending emails ### Get domain details - [GET /v4/domains/{name}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/domains/get-v4-domains--name-.md): Fetches json representation of a domain that includes details about the domain's state and settings. ### Update domain - [PUT /v4/domains/{name}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/domains/put-v4-domains--name-.md): Update domain configuration like smtp credentials, enable/disable automatic sender security, spam actions, wildcard, or tracking web scheme. ### Verify Domain - [PUT /v4/domains/{name}/verify](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/domains/put-v4-domains--name--verify.md): Verify the domains DNS records (includes A, CNAME, SPF, DKIM and MX records) to ensure the domain is ready and able to send ### Delete a domain - [DELETE /v3/domains/{name}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/domains/delete-v3-domains--name-.md): The domain must not be disabled or used as an authority for an other domain. Sandbox domain can't be deleted. ## Domain Keys An authentication standard used to prevent email spoofing. ### List keys for all domains - [GET /v1/dkim/keys](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/domain-keys/get-v1-dkim-keys.md): List domain keys, and optionally filter by signing domain or selector. Results are paginated - use the 'limit' parameter to control page size (default 10, max 100). Use the 'page' parameter from the paging response URLs to navigate through pages. ### Create a domain key - [POST /v1/dkim/keys](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/domain-keys/post-v1-dkim-keys.md): Create a domain key. Note that once private keys are created or imported they are never exported. Alternatively, you can import an existing PEM file containing a RSA private key in PKCS #1, ASn.1 DER format. Note, the pem can be passed as a file attachment or as a form-string parameter. ### Delete a domain key - [DELETE /v1/dkim/keys](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/domain-keys/delete-v1-dkim-keys.md): Domain keys are not recoverable after deletion so use with care ### Activate a domain key - [PUT /v4/domains/{authority_name}/keys/{selector}/activate](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/domain-keys/put-v4-domains--authority-name--keys--selector--activate.md): Activate a key to be used to DKIM sign emails with. Note: dns records must be valid for a domain key to be activated ### List domain keys - [GET /v4/domains/{authority_name}/keys](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/domain-keys/get-v4-domains--authority-name--keys.md): List all domain keys for your domain, including active/inactive and valid/invalid ones. ### Deactivate a domain key - [PUT /v4/domains/{authority_name}/keys/{selector}/deactivate](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/domain-keys/put-v4-domains--authority-name--keys--selector--deactivate.md): Deactivating for a specified authority and/or selector means a key won't be used for signing email anymore, even if they are valid. ### Update DKIM authority - [PUT /v3/domains/{name}/dkim_authority](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/domain-keys/put-v3-domains--name--dkim-authority.md): You can delegate the domain authority to an other domain. Domain's authority is set to itself by default. ### Update a DKIM selector - [PUT /v3/domains/{name}/dkim_selector](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/domain-keys/put-v3-domains--name--dkim-selector.md): Selector is the unique identifier of your key. It has to be different from other keys selector. ## Domain Tracking Mailgun offers tracking for clicks, unsubscribes, and opens, with optional HTTPS protocol support on tracking URLs. To enable HTTPS, Mailgun uses Let’s Encrypt with HTTP-01 challenges through your existing tracking CNAME record to issue a TLS certificate. This setup also includes support for HTTP Strict Transport Security (HSTS) for enhanced security. ### Get tracking settings - [GET /v3/domains/{name}/tracking](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/domain-tracking/get-v3-domains--name--tracking.md): Use to check if open, click and unsubscribe tracking are active/inactive. ### Update click tracking settings - [PUT /v3/domains/{name}/tracking/click](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/domain-tracking/put-v3-domains--name--tracking-click.md): Use to turn on/off the click tracking at the domain level. ### Update open tracking settings - [PUT /v3/domains/{name}/tracking/open](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/domain-tracking/put-v3-domains--name--tracking-open.md): Use to turn on/off the open tracking at the domain level. ### Update unsubscribe tracking settings - [PUT /v3/domains/{name}/tracking/unsubscribe](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/domain-tracking/put-v3-domains--name--tracking-unsubscribe.md): Use to turn on/off the unsubscribe tracking at the domain level. ### Tracking Certificate: Get certificate and status - [GET /v2/x509/{domain}/status](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/domain-tracking/get-v2-x509--domain--status.md): Get x509 TLS certificate and status ### Tracking Certificate: Regenerate expired certificate - [PUT /v2/x509/{domain}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/domain-tracking/put-v2-x509--domain-.md): Initiates regeneration of an expired TLS certificate for the tracking domain in a background task. Once generation is enqueued, you may poll status endpoint in location field to check for success. This will not regenerate an existing certificate that is still valid ### Tracking Certificate: Generate - [POST /v2/x509/{domain}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/domain-tracking/post-v2-x509--domain-.md): Initiates generation of a TLS certificate for the tracking domain in a background task. Once generation is enqueued, you may poll the status endpoint in field to check for success ## DKIM Security Automatic Sender Security DKIM Key APIs. To enable this feature please see 'Update a domain' API docs. ### Update Automatic Sender Security DKIM key rotation for a domain - [PUT /v1/dkim_management/domains/{name}/rotation](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/dkim-security/put-v1-dkim-management-domains--name--rotation.md): The minimum allowed interval for rotation is 5 days. ### Rotate Automatic Sender Security DKIM key for a domain - [POST /v1/dkim_management/domains/{name}/rotate](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/dkim-security/post-v1-dkim-management-domains--name--rotate.md): Immediately rotate your DKIM key. This will trigger a rotation even if auto-rotation is disabled on the domain. ## Webhooks Webhooks API manages domain's webhooks. You can create, access and delete webhooks programmatically. ### Get domain webhooks - [GET /v3/domains/{domain}/webhooks](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/webhooks/get-v3-domains--domain--webhooks.md): Returns all webhooks for the domain. ### Create a domain webhook - [POST /v3/domains/{domain}/webhooks](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/webhooks/post-v3-domains--domain--webhooks.md): Create a list of webhook URLs you'd like to receive Mailgun's POST requests containing event information. ### Get domain webhooks by type - [GET /v3/domains/{domain_name}/webhooks/{webhook_name}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/webhooks/get-v3-domains--domain-name--webhooks--webhook-name-.md): Get the list of url(s) for a webhook identified by its webhook_name. ### Update domain webhook - [PUT /v3/domains/{domain_name}/webhooks/{webhook_name}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/webhooks/put-v3-domains--domain-name--webhooks--webhook-name-.md): Replace the list of urls by the given one with the param. Here is the list of supported webhook: , , , , , , and . ### Delete domain webhooks by type - [DELETE /v3/domains/{domain_name}/webhooks/{webhook_name}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/webhooks/delete-v3-domains--domain-name--webhooks--webhook-name-.md): Remove all url(s) for a specified webhook type. ### Update domain webhooks (v4) - [PUT /v4/domains/{domain}/webhooks](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/webhooks/put-v4-domains--domain--webhooks.md): Update webhook URL to associate it with different event types. This replaces the existing event type associations for the given URL. ### Create domain webhooks (v4) - [POST /v4/domains/{domain}/webhooks](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/webhooks/post-v4-domains--domain--webhooks.md): Create webhook URLs for multiple event types in a single operation. This v4 endpoint allows associating one URL with multiple webhook event types. ### Delete domain webhooks (v4) - [DELETE /v4/domains/{domain}/webhooks](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/webhooks/delete-v4-domains--domain--webhooks.md): Delete webhook URLs from all event types they are associated with. Supports deleting multiple URLs at once by providing a comma-separated list. ## Metrics The Mailgun Metrics API provides programmatic access to detailed analytics data about your email sending activity. This API allows you to query, filter, and analyze email performance metrics to gain insights into deliverability, engagement, and overall sending health. ## Metrics vs. Stats API The Metrics API is the modern replacement for the deprecated Stats API: | Feature | Stats API (Deprecated) | Metrics API (Current) | |---------|----------------------|---------------------| | Flexibility | Limited filtering | Advanced filtering with logical operators | | Dimensions | Fixed groupings | Flexible dimension combinations | | Metrics | Basic counts | Comprehensive metrics including rates | | Performance | Slower | Optimized for large datasets | | Future Support | None | Active development | **Migration:** If you're using the Stats API, plan to migrate to the Metrics API for continued support and new features. ## What Are Metrics? Metrics are quantitative measurements of your email activity. The Mailgun platform collects event data in real-time and aggregates it into meaningful metrics that help you understand how your emails are performing. ## Types of Metrics Mailgun provides two categories of metrics: ### Sending Metrics (via `/v1/analytics/metrics`) These metrics track the lifecycle and performance of your outbound emails: - **Volume Metrics**: Messages accepted, delivered, failed, queued - **Engagement Metrics**: Opens, clicks, unsubscribes - **Deliverability Metrics**: Bounces (permanent and temporary), complaints (spam reports) - **Rate Metrics**: Delivered rate, open rate, click rate, bounce rate - **ESP-Specific Metrics**: Performance broken down by email service provider See [metric definitions](https://documentation.mailgun.com/docs/mailgun/user-manual/reporting/metric-definitions) for a complete list of available metrics. ### Usage Metrics (via `/v1/analytics/usage/metrics`) These metrics track your consumption of Mailgun services and features: - **Email Validation**: Single validations, bulk validations, API calls - **Email Preview**: Preview generation counts and failures - **Blocklist Monitoring**: Domain and IP blocklist checks - **Accessibility Checks**: Accessibility validation counts - **Seed Testing**: Seed test campaigns sent ## Core Concepts ### Dimensions Dimensions are the attributes by which you can slice and group your metrics data. Think of them as the "categories" or "labels" for your data. **Available Dimensions:** See [dimensions](https://documentation.mailgun.com/docs/mailgun/user-manual/reporting/dimensions) for a complete list of available dimensions. **Example:** If you query with dimensions `["time", "domain"]`, your results will be grouped by time period for each sending domain. ### Resolution Resolution determines the time granularity of your results: - **hour**: Data grouped by hour (useful for real-time monitoring) - **day**: Data grouped by day (most common for daily reports) - **month**: Data grouped by month (useful for trend analysis) The resolution you choose affects how the `time` dimension groups your data. ### Time Range Selection You have flexible options for specifying the time range: **Option 1: Start and End Dates** ```json { "start": "Mon, 13 Nov 2023 00:00:00 -0600", "end": "Mon, 20 Nov 2023 23:59:59 -0600" } ``` **Option 2: Duration** ```json { "duration": "7d" } ``` This calculates the start date and end date automatically (7 days before the today). **Date Format:** RFC 2822 format with timezone support ### Filters Filters allow you to narrow down your data to specific criteria. The filter system uses a logical structure: ```json { "filter": { "AND": [ { "attribute": "domain", "comparator": "=", "values": [ {"value": "example.com"} ] }, { "attribute": "tag", "comparator": "=", "values": [ {"value": "newsletter"} ] } ] } } ``` **Note:** Filters only support the "AND" operator. "OR" is not supported. In the example above, only data where the sending domain equals `example.com` and the tag equals `newsletter` will be returned. **Filter Components:** - **attribute**: The field to filter on (domain, tag, subaccount) - **comparator**: The comparison operator (=, !=, contains, not contains) - **values**: Array of values to match against ### Aggregates When `include_aggregates` is set to `true`, the API returns top-level summary statistics across all your queried data. This gives you totals and averages without having to sum the individual items yourself. ### Subaccounts If you use Mailgun's subaccount feature, you can: - Query metrics for a specific subaccount using filters - Include all subaccounts' data with `include_subaccounts: true` - View aggregated data across all subaccounts ## Data Retention Mailgun retains metrics data for different durations based on resolution: - **Hourly**: 60 days - **Daily**: 1 year - **Monthly**: Indefinitely ## Pagination For queries that return large result sets, the API uses offset-based pagination with `skip` and `limit` request attributes. - `skip` specifies how many items to offset (skip) from the beginning of the result set. - `limit` specifies the maximum number of items to return in a single request. Defaults and limits: - Default page size varies by dimension. Default for time dimension is 1500 items. All other dimensions default to 10 items. - Maximum `limit` is 1500 for the time dimension and 1000 for all other dimensions. How pagination works: - Start with `skip=0` and a desired `limit` (for example, `limit=1000`). - Retrieve the next page by increasing `skip` by the value of `limit`: - First page: `skip=0`, `limit=1000` - Second page: `skip=1000`, `limit=1000` - Third page: `skip=2000`, `limit=1000` - Continue paging until fewer items than the specified `limit` are returned. Additional details: - The response includes a `pagination` object containing the total number of available items. - Results can be sorted using the `sort` parameter, for example `time:asc` or `time:desc`. For consistent pagination, use a deterministic sort order. ## Rate Limits and Quotas - API calls are subject to a rate limit of 500 requests every 10 seconds ### Query account metrics - [POST /v1/analytics/metrics](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/metrics/post-v1-analytics-metrics.md): Queries filtered metrics for an account ### Query account usage metrics - [POST /v1/analytics/usage/metrics](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/metrics/post-v1-analytics-usage-metrics.md): Queries filtered usage metrics for an account ## Logs Mailgun keeps track of every inbound and outbound message event and stores this log data. This data can be queried and filtered to provide insights into the health of your email infrastructure. ### List logs - [POST /v1/analytics/logs](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/logs/post-v1-analytics-logs.md): Gets customer event logs for an account ## Bounce Classification ### List statistic v2 - [POST /v2/bounce-classification/metrics](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/bounce-classification/post-v2-bounce-classification-metrics.md): Items that have no bounces and no delays(classified_failures_count==0) are not returned. ### List statistics, ordered by total bounces (deprecated) - [GET /v1/bounce-classification/stats](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/bounce-classification/get-v1-bounce-classification-stats.md): Deprecated: use POST /v2/bounce-classification/metrics instead ### List domains statistic per account (deprecated) - [GET /v1/bounce-classification/domains](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/bounce-classification/get-v1-bounce-classification-domains.md): Deprecated: use POST /v2/bounce-classification/metrics ### List statistic per domain (deprecated) - [GET /v1/bounce-classification/domains/{domain}/entities](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/bounce-classification/get-v1-bounce-classification-domains--domain--entities.md): Deprecated: use POST /v2/bounce-classification/metrics ### List statistic per entity (deprecated) - [GET /v1/bounce-classification/domains/{domain}/entities/{entity-id}/rules](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/bounce-classification/get-v1-bounce-classification-domains--domain--entities--entity-id--rules.md): Deprecated: use POST /v2/bounce-classification/metrics ### List Bounce Logs (deprecated) - [GET /v1/bounce-classification/domains/{domain}/events](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/bounce-classification/get-v1-bounce-classification-domains--domain--events.md): Deprecated: use POST /v1/analytics/logs - https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/logs ### List entities (deprecated) - [GET /v1/bounce-classification/config/entities](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/bounce-classification/get-v1-bounce-classification-config-entities.md): Deprecated: use POST /v2/bounce-classification/metrics ### List rules (deprecated) - [GET /v1/bounce-classification/config/rules](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/bounce-classification/get-v1-bounce-classification-config-rules.md): Deprecated: use GET /v2/bounce-classification/config/groups/{group-id} ## Tags New Mailgun allows you to tag your email with unique identifiers. Tags are visible via our analytics tags API endpoint. ### Update account tag - [PUT /v1/analytics/tags](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/tags-new/put-v1-analytics-tags.md): Updates the tag description for an account ### Post query to list account tags or search for single tag - [POST /v1/analytics/tags](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/tags-new/post-v1-analytics-tags.md): Gets the list of all tags, or filtered by tag prefix, for an account ### Delete account tag - [DELETE /v1/analytics/tags](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/tags-new/delete-v1-analytics-tags.md): Deletes the tag for an account ### Get account tag limit information - [GET /v1/analytics/tags/limits](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/tags-new/get-v1-analytics-tags-limits.md): Gets the tag limit and current number of unique tags for an account ## Stats Mailgun collects many different events and generates event statistics which are available in your Control Panel. This data is also available via our stats API endpoint.

WARNING: This API is deprecated in favor of our [Metrics](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/metrics) API. ### Totals for entire account (deprecated) - [GET /v3/stats/total](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/stats/get-v3-stats-total.md): Gets stat totals for an entire account ### Totals for entire domain (deprecated) - [GET /v3/{domain}/stats/total](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/stats/get-v3--domain--stats-total.md): Gets stat totals for an entire domain ### Totals for account domains for a single time resolution (deprecated) - [GET /v3/stats/total/domains](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/stats/get-v3-stats-total-domains.md): Gets stat totals for domains in an account for a single time resolution ### Filtered/grouped totals for entire account (deprecated) - [GET /v3/stats/filter](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/stats/get-v3-stats-filter.md): Gets filtered and group stat totals for an entire account ### Aggregate counts by ESP (deprecated) - [GET /v3/{domain}/aggregates/providers](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/stats/get-v3--domain--aggregates-providers.md): Gets aggregate counts by email service provider ### Aggregate counts by devices triggering events (deprecated) - [GET /v3/{domain}/aggregates/devices](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/stats/get-v3--domain--aggregates-devices.md): Gets aggregate counts on devices that triggered events ('tablet', 'phone', 'pc', etc…) ### Aggregate counts by country (deprecated) - [GET /v3/{domain}/aggregates/countries](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/stats/get-v3--domain--aggregates-countries.md): Gets aggregate counts by country (USA, RUS, etc…) ## Tags Mailgun lets you tag each outgoing message with a custom value. When you access stats on your messages, they will be aggregated by these tags.

WARNING: This API is deprecated in favor of our new [Tags](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/tags-new) API. ### List all tags (deprecated) - [GET /v3/{domain}/tags](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/tags/get-v3--domain--tags.md): List all tags associated with a domain ### Get a tag (deprecated) - [GET /v3/{domain}/tag](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/tags/get-v3--domain--tag.md): Get a tag associated with a domain ### Update tag (deprecated) - [PUT /v3/{domain}/tag](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/tags/put-v3--domain--tag.md): Update a tag associated with a domain ### Delete tag (deprecated) - [DELETE /v3/{domain}/tag](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/tags/delete-v3--domain--tag.md): Delete a tag associated with a domain ### Get aggregate stat types by tag (deprecated) - [GET /v3/{domain}/tag/stats/aggregates](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/tags/get-v3--domain--tag-stats-aggregates.md): Returns a list for a given domain for different event types ### Get stats by tag (deprecated) - [GET /v3/{domain}/tag/stats](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/tags/get-v3--domain--tag-stats.md): Retrieve stats by tag ### Get tag limits (deprecated) - [GET /v3/domains/{domain}/limits/tag](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/tags/get-v3-domains--domain--limits-tag.md): Get tag limits by domain ## Events Mailgun keeps track of every inbound and outbound message event and stores this data for at least 3 days.

WARNING: This API is deprecated in favor of our [Logs](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/logs) API. ### Retrieves a paginated list of events - [GET /v3/{domain_name}/events](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/events/get-v3-domain_name-events.md): Mailgun tracks every inbound and outbound message event and retains this data for at least 3 days. See Filter expression for details about filtering expressions ## Alerts Mailgun allows you to get instant notifications on the sending metrics that matter most, configured specifically for your unique business needs and assets. Route these alerts to the channels your team relies on. Stay on top of sending performance without the need to manually monitor. ### List send alerts - [GET /v1/thresholds/alerts/send](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/alerts/get-v1-thresholds-alerts-send.md) ### Create a send alert for an account - [POST /v1/thresholds/alerts/send](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/alerts/post-v1-thresholds-alerts-send.md) ### Get a send alert - [GET /v1/thresholds/alerts/send/{name}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/alerts/get-v1-thresholds-alerts-send--name-.md) ### Update a send alert - [PUT /v1/thresholds/alerts/send/{name}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/alerts/put-v1-thresholds-alerts-send--name-.md) ### Delete a send alert - [DELETE /v1/thresholds/alerts/send/{name}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/alerts/delete-v1-thresholds-alerts-send--name-.md) ### List account hits - [GET /v1/thresholds/hits](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/alerts/get-v1-thresholds-hits.md) ## Unsubscribe Unsubscribe list stores email addresses of recipients who unsubscribed from your mailings by clicking a Mailgun generated unsubscribe link. ### Import unsubscribe list - [POST /v3/{domain_name}/unsubscribes/import](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/unsubscribe/post-v3--domainid--unsubscribes-import.md): Import a CSV file containing a list of addresses to add to the unsubscribe list. The CSV file must be 25MB or under and can contain the following column headers: address, tags, created_at. address is a valid email address (required). tags is tag to unsubscribe from, use ). created_at is timestamp of unsubscribe event in RFC2822 format (optional, default: current time) ### Lookup unsubscribe record - [GET /v3/{domain_name}/unsubscribes/{address}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/unsubscribe/get-v3--domainid--unsubscribes--address-.md): Fetch a single unsubscribe record to check if a given address is present in a list of unsubscribed users. ### Remove unsubscribe - [DELETE /v3/{domain_name}/unsubscribes/{address}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/unsubscribe/delete-v3--domainid--unsubscribes--address-.md): Delivery to the deleted email address resumes until it unsubscribes again. ### List all unsubscribes - [GET /v3/{domain_name}/unsubscribes](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/unsubscribe/get-v3--domainid--unsubscribes.md): Paginate over a list of unsubscribes for domain. ### Add unsubscribes - [POST /v3/{domain_name}/unsubscribes](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/unsubscribe/post-v3--domainid--unsubscribes.md): Request body is expected to be a valid JSON encoded sting containing up to 1000 unsubscribe records or a single unsubscribe record as application/form-data ### Clear all unsubscribes - [DELETE /v3/{domain_name}/unsubscribes](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/unsubscribe/delete-v3--domainid--unsubscribes.md): Clear all unsubscribe email addresses for the domain. Delivery to the deleted email addresses will no longer be suppressed. ## Complaints Email addresses of recipients who marked your messages as a spam (for ESPs that support FBL). ### Import complaint list - [POST /v3/{domain_name}/complaints/import](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/complaints/post-v3--domainid--complaints-import.md): Import a CSV file containing a list of addresses to add to the complaint list. The CSV file must be 25MB or under and can contain the following column headers: address, created_at. address is a valid email address (required). created_at is timestamp of complaint event in RFC2822 format (optional, default: current time) ### Lookup complaint record - [GET /v3/{domain_name}/complaints/{address}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/complaints/get-v3--domainid--complaints--address-.md): Fetch a single complaint records to check if a given address is present in the list of complaints. ### Remove complaint - [DELETE /v3/{domain_name}/complaints/{address}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/complaints/delete-v3--domainid--complaints--address-.md): Delivery to the deleted email address resumes until there is another complaint. ### List all complaints - [GET /v3/{domain_name}/complaints](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/complaints/get-v3--domainid--complaints.md): Paginate a list of complaints for the domain. ### Add complaints - [POST /v3/{domain_name}/complaints](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/complaints/post-v3--domainid--complaints.md): Request body is expected to be a valid JSON encoded sting containing up to 1000 complaint records or a single complaint record as application/form-data ### Clear all complaints - [DELETE /v3/{domain_name}/complaints](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/complaints/delete-v3--domainid--complaints.md): Clears all email addresses with complaints from the domain. Delivery to the deleted email addresses will longer be suppressed. ## Bounces Bounces - Bounce list stores events of delivery failures due to permanent recipient mailbox errors such as non-existent mailbox. Soft bounces (for example, mailbox is full) and other failures (for example, ESP rejects an email because it thinks it is spam) are not added to the list. ### Import list of bounces - [POST /v3/{domain_name}/bounces/import](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/bounces/post-v3--domainid--bounces-import.md): Import a CSV file containing a list of addresses to add to the bounce list. The CSV file must be 25MB or under and must contain the following column headers: address, code, error, created_at. address is a valid email address. code is error code (optional, default: 550). error is error description (optional, default: empty string). created_at is timestamp of bounce event in RFC2822 format (optional, default: current time) ### Lookup bounce record - [GET /v3/{domain_name}/bounces/{address}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/bounces/get-v3--domainid--bounces--address-.md): Fetch a single bounce event by a given email address. ### Remove bounce - [DELETE /v3/{domain_name}/bounces/{address}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/bounces/delete-v3--domainid--bounces--address-.md): Delivery to the deleted email address resumes until it bounces again. ### List all bounces - [GET /v3/{domain_name}/bounces](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/bounces/get-v3--domainid--bounces.md): Paginate over a list of bounces for a domain. ### Add bounces - [POST /v3/{domain_name}/bounces](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/bounces/post-v3--domainid--bounces.md): Request body is expected to be a valid JSON encoded sting containing up to 1000 bounce records or a single bounce record as application/form-data ### Clear all bounces - [DELETE /v3/{domain_name}/bounces](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/bounces/delete-v3--domainid--bounces.md): Clears all email addresses with bounces from the domain. Delivery to the deleted email addresses will longer be suppressed. ## Allowlist The allowlist API provides the ability to allowlist specific addresses from being added to bounce list. You can allowlist by domain name (i.e example.com) or by specific address (i.e. alice@example.com). Mailgun doesn’t add an address to bounce list if the address is allowlisted. This API is very useful if you test against your private services and don’t want to constantly clean up bounce lists ### Import allowlist - [POST /v3/{domain_name}/whitelists/import](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/allowlist/post-v3--domainid--whitelists-import.md): Import a CSV file containing a list of addresses and/or domains to add to the allowlist. The CSV file must be 25MB or under and must contain the following column headers: address, domain. For each row provide either an address or a domain, but not both - choose one, keep the other blank. ### Lookup allowlist record - [GET /v3/{domain_name}/whitelists/{value}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/allowlist/get-v3--domainid--whitelists--value-.md): Fetch a single allowlist record to check if a given address or domain is present. ### Remove entry from allowlist - [DELETE /v3/{domain_name}/whitelists/{value}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/allowlist/delete-v3--domainid--whitelists--value-.md): Remove a single entry from the allowlist ### List allowlist records for domain - [GET /v3/{domain_name}/whitelists](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/allowlist/get-v3--domainid--whitelists.md): Paginate over all allowlist records for a domain. ### Add allowlist record - [POST /v3/{domain_name}/whitelists](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/allowlist/post-v3--domainid--whitelists.md): Add an address or domain to the allowlist table ### Clear allowlist - [DELETE /v3/{domain_name}/whitelists](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/allowlist/delete-v3--domainid--whitelists.md): Delete an entire allowlist for a domain ## Routes Define a list of routes to handle incoming emails. When a message matches a route expression, Mailgun can forward it on to your application via HTTP or another email address, or store the message temporarily (3 days) for subsequent retrieval. ### Create a route - [POST /v3/routes](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/routes/post-v3-routes.md): Adds a new route to the account ### Get all routes - [GET /v3/routes](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/routes/get-v3-routes.md): Get the list of routes. Note that routes are defined globally, per account, not per domain. ### Get a route - [GET /v3/routes/{id}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/routes/get-v3-routes-id.md): Returns a detailed view of the route ### Update a route - [PUT /v3/routes/{id}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/routes/put-v3-routes-id.md): Updates a given route. All parameters are optional. This only updates the specified fields, leaving others unchanged. ### Delete a route - [DELETE /v3/routes/{id}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/routes/delete-v3-routes-id.md): Remove the rotue from the account. ### Match address to route - [GET /v3/routes/match](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/routes/get-v3-routes-match.md): Checks if an address matches at least one route. ## Mailing Lists Programatically create mailing lists. ### Create a mailing list - [POST /v3/lists](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/mailing-lists/post-v3-lists.md): Adds a mailing list to the account. ### Get mailing lists - [GET /v3/lists](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/mailing-lists/get-v3-lists.md): A mailing list is a group of members (recipients) which itself has an email address. This address becomes an ID for this mailing list. ### Get mailing lists members - [GET /v3/lists/{list_address}/members](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/mailing-lists/get-lists-string:list_address-members.md): Lists members in a given mailing list ### Create a mailing list member - [POST /v3/lists/{list_address}/members](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/mailing-lists/post-lists-string:list_address-members.md): Adds a new member to the mailing list. For adding many list members, consider bulk upload endpoints "POST /v3/lists/{list_address}/members.json" or "members.csv". ### Bulk upload members to a mailing list (JSON) - [POST /v3/lists/{list_address}/members.json](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/mailing-lists/post-lists-list_address-members.json.md): Adds multiple members, up to 1000 per call, to a mailing list, using JSON array format. If the request includes more than 100 entries, the mailing list will be updated asynchronously. ### Bulk upload members to a mailing list (CSV) - [POST /v3/lists/{list_address}/members.csv](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/mailing-lists/post-lists-list_address-members.csv.md): Adds multiple members, up to 1000 per call, to a mailing list via CSV file. ### Get a member - [GET /v3/lists/{list_address}/members/{member_address}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/mailing-lists/get-lists-list_address-members-member_address.md): Get details about a specific mailing list member ### Update a mailing list member - [PUT /v3/lists/{list_address}/members/{member_address}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/mailing-lists/put-lists-list_address-members-member_address.md): Updates a mailing list member with the given properties. Existing properties not included in the request will not be changed. ### Delete a member - [DELETE /v3/lists/{list_address}/members/{member_address}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/mailing-lists/delete-lists-list_address-members-member_address.md): Deletes a member from a mailing list ### Update a mailing list - [PUT /v3/lists/{list_address}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/mailing-lists/put-v3-lists-address.md): Update mailing list properties, such as address, description or name ### Delete a mailing list - [DELETE /v3/lists/{list_address}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/mailing-lists/delete-v3-lists-address.md): Deletes a mailing list ### Get a mailing list by address - [GET /v3/lists/{list_address}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/mailing-lists/get-v3-lists-address.md): Returns the matching mailing list for the given address ### Get mailing lists by page - [GET /v3/lists/pages](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/mailing-lists/get-v3-lists-pages.md): Paginate over mailing lists ### Get members by page - [GET /v3/lists/{list_address}/members/pages](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/mailing-lists/get-lists-list_address-members-pages.md): Paginate over list members in a given mailing list in ascending order ## Templates This API allows you to store predefined templates and use them to send messages using the Sending API. ### Get templates - [GET /v3/{domain_name}/templates](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/templates/get-v3--domain-name--templates.md): Returns a list of templates for the domain. ### Create a template - [POST /v3/{domain_name}/templates](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/templates/post-v3--domain-name--templates.md): Store a new template, including its name, description and (optionally) the template content. If the template content is provided, a new version is automatically created and becomes the active version. ### Delete all templates - [DELETE /v3/{domain_name}/templates](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/templates/delete-v3--domain-name--templates.md): Delete all templates and their versions for the domain. ### Get all template versions - [GET /v3/{domain_name}/templates/{template_name}/versions](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/templates/get-v3--domain-name--templates--template-name--versions.md): Returns a paginated list of template versions. ### Create a template version - [POST /v3/{domain_name}/templates/{template_name}/versions](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/templates/post-v3--domain-name--templates--template-name--versions.md): Adds a new template version. If the template doesn’t contain any other versions, the first version becomes active. A template can store up to 40 versions. ### Get template - [GET /v3/{domain_name}/templates/{template_name}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/templates/get-v3--domain-name--templates--template-name-.md): Returns metadata information about the stored template specified in the url. If the active flag is provided, the content of the active version of the template is returned. If the version_name flag is provided, version information will be included as well. By default: the field is not provided. To see available versions other than the active version, use the API instead ### Update template - [PUT /v3/{domain_name}/templates/{template_name}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/templates/put-v3--domain-name--templates--template-name-.md): Update the description of a template. ### Delete a template - [DELETE /v3/{domain_name}/templates/{template_name}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/templates/delete-v3--domain-name--templates--template-name-.md): Delete the template specified in the url. NOTE: This method deletes all versions of the specified template. ### Get a version - [GET /v3/{domain_name}/templates/{template_name}/versions/{version_name}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/templates/get-v3--domain-name--templates--template-name--versions--version-name-.md): Retrieve the information and content of the specified version of a template. ### Update a version - [PUT /v3/{domain_name}/templates/{template_name}/versions/{version_name}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/templates/put-v3--domain-name--templates--template-name--versions--version-name-.md): Update information or content of the specific template version. Existing fields not included in the request will not be changed ### Delete a version - [DELETE /v3/{domain_name}/templates/{template_name}/versions/{version_name}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/templates/delete-v3--domain-name--templates--template-name--versions--version-name-.md): Delete a specific template version. ### Copy a version - [PUT /v3/{domain_name}/templates/{template_name}/versions/{version_name}/copy/{new_version_name}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/templates/put-v3--domain-name--templates--template-name--versions--version-name--copy--new-version-name-.md): Copies an existing version into a new version with the provided name. ## IPs The IP API endpoint allows you to access information regarding the IPs allocated to your Mailgun account that are used for outbound sending. ### Remove an IP from the domain pool, unlink a DIPP or remove the domain pool - [DELETE /v3/domains/{name}/ips/{ip}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ip-pools/delete-v3-domains--name--ips--ip-.md): The behavior of the endpoint depends on the value of the parameter. It can be one of the following: * a valid IP address: this IP address will be removed from the domain pool. * string : the entire domain pool will be removed. As far as the system is concerned, such domain will no longer exist. * string : the DIPP which is currently linked to the domain will be unlinked. ### Removing An IP Note that it's impossible to alter domain IPs if a DIPP is linked to the domain. If the account is not eligible for shared IPs, additional rules apply: * removing the last IP from the domain is not allowed; * if all of the remaining dedicated IPs are on warmup, an extra IP might be added to the domain pool. ### Unlinking The DIPP The account must have 'DIPPs' feature enabled. Either or query parameter must be specified, but not both. If the special value is used for the replacement IP, the account must be eligible for shared IPs. In this case the system will assign a shared IP as the replacement. ### Remove an IP from the domain pool, unlink a DIPP or remove the domain pool - [DELETE /v3/domains/{name}/pool/{ip}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ip-pools/delete-v3-domains--name--pool--ip-.md): The behavior of the endpoint depends on the value of the parameter. It can be one of the following: * a valid IP address: this IP address will be removed from the domain pool. * string : the entire domain pool will be removed. As far as the system is concerned, such domain will no longer exist. * string : the DIPP which is currently linked to the domain will be unlinked. ### Removing An IP Note that it's impossible to alter domain IPs if a DIPP is linked to the domain. If the account is not eligible for shared IPs, additional rules apply: * removing the last IP from the domain is not allowed; * if all of the remaining dedicated IPs are on warmup, an extra IP might be added to the domain pool. ### Unlinking The DIPP The account must have 'DIPPs' feature enabled. Either or query parameter must be specified, but not both. If the special value is used for the replacement IP, the account must be eligible for shared IPs. In this case the system will assign a shared IP as the replacement. ### Remove an IP from the domain pool, unlink a DIPP or remove the domain pool - [DELETE /v3/domains/{name}/ips/{ip}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ips/delete-v3-domains--name--ips--ip-.md): The behavior of the endpoint depends on the value of the parameter. It can be one of the following: * a valid IP address: this IP address will be removed from the domain pool. * string : the entire domain pool will be removed. As far as the system is concerned, such domain will no longer exist. * string : the DIPP which is currently linked to the domain will be unlinked. ### Removing An IP Note that it's impossible to alter domain IPs if a DIPP is linked to the domain. If the account is not eligible for shared IPs, additional rules apply: * removing the last IP from the domain is not allowed; * if all of the remaining dedicated IPs are on warmup, an extra IP might be added to the domain pool. ### Unlinking The DIPP The account must have 'DIPPs' feature enabled. Either or query parameter must be specified, but not both. If the special value is used for the replacement IP, the account must be eligible for shared IPs. In this case the system will assign a shared IP as the replacement. ### Remove an IP from the domain pool, unlink a DIPP or remove the domain pool - [DELETE /v3/domains/{name}/pool/{ip}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ips/delete-v3-domains--name--pool--ip-.md): The behavior of the endpoint depends on the value of the parameter. It can be one of the following: * a valid IP address: this IP address will be removed from the domain pool. * string : the entire domain pool will be removed. As far as the system is concerned, such domain will no longer exist. * string : the DIPP which is currently linked to the domain will be unlinked. ### Removing An IP Note that it's impossible to alter domain IPs if a DIPP is linked to the domain. If the account is not eligible for shared IPs, additional rules apply: * removing the last IP from the domain is not allowed; * if all of the remaining dedicated IPs are on warmup, an extra IP might be added to the domain pool. ### Unlinking The DIPP The account must have 'DIPPs' feature enabled. Either or query parameter must be specified, but not both. If the special value is used for the replacement IP, the account must be eligible for shared IPs. In this case the system will assign a shared IP as the replacement. ### List account IPs - [GET /v3/ips](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ips/get-v3-ips.md): in response lists which IPs can be assigned to DIPPs; this field is present only if the account has 'DIPPs' feature enabled. contains the number of items returned in (this depends on the filters applied). ### Get details about account IP - [GET /v3/ips/{ip}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ips/get-v3-ips--ip-.md) ### Get all domains of an account where a specific IP is assigned - [GET /v3/ips/{ip}/domains](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ips/get-v3-ips--ip--domains.md): The IP must belong to the account. Matching domains are ordered by increasing id, then the and parameters are applied. If the parameter is present, it is used to limit the results to domains whose names match the search query. The search query is split into words by whitespace and punctuation, then the logical OR is applied. ### Assign an IP to all account domains - [POST /v3/ips/{ip}/domains](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ips/post-v3-ips--ip--domains.md): The IP must belong to the account. ### Remove an IP from all account domains - [DELETE /v3/ips/{ip}/domains](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ips/delete-v3-ips--ip--domains.md): The IP must belong to the account. If the parameter is present, it is used to replace the removed ip on all domains. ### Place account IP into a dedicated IP band - [POST /v3/ips/{addr}/ip_band](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ips/post-v3-ips--addr--ip-band.md): The feature must be enabled for the account. The IP must be a dedicated one belonging to the account. ### Return the number of IPs available to the account per its billing plan - [GET /v3/ips/request/new](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ips/get-v3-ips-request-new.md): This endpoint remains active for backwards compatibility. Do not use it in new code. Field in the response is deprecated and should not be used. ### Add a new dedicated IP to the account - [POST /v3/ips/request/new](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ips/post-v3-ips-request-new.md): A new IP can be assigned only if billing limits allow that. ## IP Pools IP Pools allow you to group your dedicated IPs into customized "pools" to help manage your sending reputation for different mail sending streams. ### Remove an IP from the domain pool, unlink a DIPP or remove the domain pool - [DELETE /v3/domains/{name}/ips/{ip}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ip-pools/delete-v3-domains--name--ips--ip-.md): The behavior of the endpoint depends on the value of the parameter. It can be one of the following: * a valid IP address: this IP address will be removed from the domain pool. * string : the entire domain pool will be removed. As far as the system is concerned, such domain will no longer exist. * string : the DIPP which is currently linked to the domain will be unlinked. ### Removing An IP Note that it's impossible to alter domain IPs if a DIPP is linked to the domain. If the account is not eligible for shared IPs, additional rules apply: * removing the last IP from the domain is not allowed; * if all of the remaining dedicated IPs are on warmup, an extra IP might be added to the domain pool. ### Unlinking The DIPP The account must have 'DIPPs' feature enabled. Either or query parameter must be specified, but not both. If the special value is used for the replacement IP, the account must be eligible for shared IPs. In this case the system will assign a shared IP as the replacement. ### Remove an IP from the domain pool, unlink a DIPP or remove the domain pool - [DELETE /v3/domains/{name}/pool/{ip}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ip-pools/delete-v3-domains--name--pool--ip-.md): The behavior of the endpoint depends on the value of the parameter. It can be one of the following: * a valid IP address: this IP address will be removed from the domain pool. * string : the entire domain pool will be removed. As far as the system is concerned, such domain will no longer exist. * string : the DIPP which is currently linked to the domain will be unlinked. ### Removing An IP Note that it's impossible to alter domain IPs if a DIPP is linked to the domain. If the account is not eligible for shared IPs, additional rules apply: * removing the last IP from the domain is not allowed; * if all of the remaining dedicated IPs are on warmup, an extra IP might be added to the domain pool. ### Unlinking The DIPP The account must have 'DIPPs' feature enabled. Either or query parameter must be specified, but not both. If the special value is used for the replacement IP, the account must be eligible for shared IPs. In this case the system will assign a shared IP as the replacement. ### List dedicated IP pools of the account - [GET /v3/ip_pools](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ip-pools/get-v3-ip-pools.md): #### Description Lists all dedicated IP pools of the account. For each pool returns its basic properties (name, description, the list of IPs) and indicates whether the pool is linked to any domains and whether it's an inherited one. Only one pool can be inherited from the parent account. ### Add a new DIPP to the account - [POST /v3/ip_pools](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ip-pools/post-v3-ip-pools.md): The account must have 'DIPPs' feature enabled. Returns the id of the newly created DIPP. ### Get DIPP details - [GET /v3/ip_pools/{pool_id}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ip-pools/get-v3-ip-pools--pool-id-.md): in the response indicates whether the DIPP is currently linked to any domains. If it's , lists those domains. ### Delete the DIPP - [DELETE /v3/ip_pools/{pool_id}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ip-pools/delete-v3-ip-pools--pool-id-.md): The feature must be enabled for the account. It is not allowed to delete a DIPP inherited from the parent account. If the DIPP is delegated to subaccounts, those will also be updated. If the replacement DIPP is specified, all domains linked to the deleted DIPP will be relinked to the replacement DIPP. The latter must contain at least one IP. If the replacement IP is specified, all domains linked to the deleted DIPP will be unlinked, and the replacement IP will be assigned to them. It is not allowed to delete a DIPP inherited from the parent account and replace it with an IP (subaccounts do not explicitly manage their IPs). The replacement IP must be a dedicated one; it can't belong to another DIPP. If a special value is used, appropriate shared IPs will be used (the account must be eligible for shared IPs in this case). Omitting both replacement DIPP and replacement IP is allowed only if the DIPP being deleted contains no IPs. The processing of affected domains and subaccounts happens asynchronously after the endpoint returns a response. ### Edit DIPP - [PATCH /v3/ip_pools/{pool_id}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ip-pools/patch-v3-ip-pools--pool-id-.md): The account must have 'DIPPs' feature enabled. It's not allowed to edit a DIPP inherited from the parent account. IPs being added to the DIPP must be dedicated ones and belong to the account. If IPs of the DIPP end up modified, and the DIPP is linked to domains, the domains will be updated asynchronously (after this endpoint returns response). Returns an error if the passed parameters won't result in any changes. ### Get domains linked to DIPP - [GET /v3/ip_pools/{pool_id}/domains](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ip-pools/get-v3-ip-pools--pool-id--domains.md): Returns a paginated list of domains that are linked to the specified dedicated IP pool. ### Add an IP to a DIPP - [PUT /v3/ip_pools/{pool_id}/ips/{ip}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ip-pools/put-v3-ip-pools--pool-id--ips--ip-.md): The account must have 'DIPPs' feature enabled. It is not allowed to modify a DIPP inherited from the parent account. The IP must be a dedicated one, belong to the account and not belong to any other DIPP. All domains linked to the DIPP will be updated so that their IPs include the newly added address. If the DIPP is delegated to subaccounts, those will also be updated. The processing of affected domains and subaccounts happens asynchronously after the endpoint returns a response. ### Remove an IP from a DIPP - [DELETE /v3/ip_pools/{pool_id}/ips/{ip}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ip-pools/delete-v3-ip-pools--pool-id--ips--ip-.md): The account must have 'DIPPs' feature enabled. It's not allowed to edit a DIPP inherited from the parent account. If the DIPP is linked to domains, the domains will be updated asynchronously (after this endpoint returns response). ### Add multiple IPs to the DIPP - [POST /v3/ip_pools/{pool_id}/ips.json](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ip-pools/post-v3-ip-pools--pool-id--ips-json.md): The account must have 'DIPPs' feature enabled. It is not allowed to modify a DIPP inherited from the parent account. All IPs must be dedicated ones, belong to the account and not belong to any other DIPP. All domains linked to the DIPP will be updated so that their IPs include the newly added addresses. If the DIPP is delegated to subaccounts, those will also be updated. The processing of affected domains and subaccounts happens asynchronously after the endpoint returns a response. ### Remove an IP from the domain pool, unlink a DIPP or remove the domain pool - [DELETE /v3/domains/{name}/ips/{ip}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ips/delete-v3-domains--name--ips--ip-.md): The behavior of the endpoint depends on the value of the parameter. It can be one of the following: * a valid IP address: this IP address will be removed from the domain pool. * string : the entire domain pool will be removed. As far as the system is concerned, such domain will no longer exist. * string : the DIPP which is currently linked to the domain will be unlinked. ### Removing An IP Note that it's impossible to alter domain IPs if a DIPP is linked to the domain. If the account is not eligible for shared IPs, additional rules apply: * removing the last IP from the domain is not allowed; * if all of the remaining dedicated IPs are on warmup, an extra IP might be added to the domain pool. ### Unlinking The DIPP The account must have 'DIPPs' feature enabled. Either or query parameter must be specified, but not both. If the special value is used for the replacement IP, the account must be eligible for shared IPs. In this case the system will assign a shared IP as the replacement. ### Remove an IP from the domain pool, unlink a DIPP or remove the domain pool - [DELETE /v3/domains/{name}/pool/{ip}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ips/delete-v3-domains--name--pool--ip-.md): The behavior of the endpoint depends on the value of the parameter. It can be one of the following: * a valid IP address: this IP address will be removed from the domain pool. * string : the entire domain pool will be removed. As far as the system is concerned, such domain will no longer exist. * string : the DIPP which is currently linked to the domain will be unlinked. ### Removing An IP Note that it's impossible to alter domain IPs if a DIPP is linked to the domain. If the account is not eligible for shared IPs, additional rules apply: * removing the last IP from the domain is not allowed; * if all of the remaining dedicated IPs are on warmup, an extra IP might be added to the domain pool. ### Unlinking The DIPP The account must have 'DIPPs' feature enabled. Either or query parameter must be specified, but not both. If the special value is used for the replacement IP, the account must be eligible for shared IPs. In this case the system will assign a shared IP as the replacement. ## Dynamic IP Pools Dynamic IP Pools allow you to group your dedicated IPs into customized "pools" based on sender reputation. Domains enrolled in Dynamic IP Pools will be assigned to a pool based on the result of periodic health checks. ### Enroll domain - [POST /v3/domains/{name}/dynamic_pools](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/dynamic-ip-pools/post-v3-domains--name--dynamic-pools.md): Domains enrolled in the Dynamic IP pools feature will be assigned an IP pool based on reputation. The feature must be enabled and configured before enrolling domains. ### Remove domain from dynamic IP pools - [DELETE /v3/domains/{name}/dynamic_pools](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/dynamic-ip-pools/delete-v3-domains--name--dynamic-pools.md): The behavior of this endpoint depends on the value of the and parameters. One of these parameters (but not both) must be provided. If is provided, the IP(s) will be assigned to the domain. can include one of the following: * valid IP(s): this IP address or addresses will be added to the domain * string : if the account is eligible for shared IPs, a suitable shared IP will be chosen and added to the domain The 'replacement_ip' parameter cannot include any IPs that are already assigned to a Dedicated IP Pool or a Dynamic IP Pool. If is provided, the Dedicated IP Pool will be assigned to the domain. ### List assignable domains - [GET /v3/domains/dynamic_pools/assignable](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/dynamic-ip-pools/get-v3-domains-dynamic-pools-assignable.md): Lists all domains that are not already enrolled in dynamic IP pools. ### Enroll all account domains - [POST /v3/domains/all/dynamic_pools/enroll](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/dynamic-ip-pools/post-v3-domains-all-dynamic-pools-enroll.md): Begins an asynchronous background job to assign all domains to Dynamic IP Pools. This can also include domains belonging to subaccounts depending on the provided parameters. The Dynamic IP Pools feature must be enabled for the account and the request must come from a parent account user. ### List all Dynamic IP pools - [GET /v3/dynamic_pools](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/dynamic-ip-pools/get-v3-dynamic-pools.md): Returns the list of IPs belonging to each of the account's Dynamic IP Pools. ### Initialize/set IPs for all pools - [POST /v3/dynamic_pools/all](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/dynamic-ip-pools/post-v3-dynamic-pools-all.md): Any existing IPs in dynamic IP pools will be replaced. All IPs must be dedicated IPs and belong to the account. Additionally, each dynamic IP pool must contain at least 1 IP that is not currently warming. ### Remove all dynamic IP pools - [DELETE /v3/dynamic_pools/all](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/dynamic-ip-pools/delete-v3-dynamic-pools-all.md): Removes all dynamic IP pools from the account. All domains on the account (and subaccounts, if any) must be removed from dynamic IP pools before the pools can be removed. Any standard dedicated IP pools will not be modified. ### Add IP to Dynamic IP Pool - [POST /v3/dynamic_pools/{pool_name}/{ip}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/dynamic-ip-pools/post-v3-dynamic-pools--pool-name---ip-.md): Adds a given IP to a Dynamic IP Pool. The IP must be dedicated and belong to the account. ### Update pool IPs - [PATCH /v3/dynamic_pools/{pool_name}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/dynamic-ip-pools/patch-v3-dynamic-pools--pool-name-.md): Adds and/or removes IPs to/from the specified dynamic IP pool. A given pool is required to have at least 1 IP that is not actively warming. Additionally, a single IP cannot be assigned to multiple dynamic pools. ### List all domains assigned to dynamic IP pools - [GET /v1/dynamic_pools/domains](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/dynamic-ip-pools/get-v1-dynamic-pools-domains.md): Retrieves all domains enrolled in dynamic IP pools across the parent account and subaccounts. ### Preview domain assignment - [GET /v1/dynamic_pools/domains/{name}/preview](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/dynamic-ip-pools/get-v1-dynamic-pools-domains--name--preview.md): Runs a health check on a domain and returns which pool it would be placed in. It does NOT enroll the domain or set the band ### List domain history - [GET /v1/dynamic_pools/domains/{name}/history](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/dynamic-ip-pools/get-v1-dynamic-pools-domains--name--history.md): Retrieves a domain's history records ### Override domain assignment - [PUT /v1/dynamic_pools/domains/{name}/override](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/dynamic-ip-pools/put-v1-dynamic-pools-domains--name--override.md): Overrides a domain's dynamic IP pool assignment. A domain's pool will not be updated by health checks while an override is present. ### Remove override - [DELETE /v1/dynamic_pools/domains/{name}/override](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/dynamic-ip-pools/delete-v1-dynamic-pools-domains--name--override.md): Removes any dynamic IP pool override for a domain. The domain's pool assignment will be managed by health checks. ### List account history - [GET /v1/dynamic_pools/history](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/dynamic-ip-pools/get-v1-dynamic-pools-history.md): Retrieve history records for all domains assigned to Dynamic IP Pools across the parent and subaccounts. ## IP Address Warmup ### Retrieves the list of in-flight IP address warmup statuses. - [GET /v3/ip_warmups](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ip-address-warmup/get-v3-ip-warmups.md): Retrieves a list of in-flight IP warmup statuses for dedicated IP addresses owned by the account. The response includes pagination URLs for navigating through the results. ### Retrieves the status of an in-flight IP warmup - [GET /v3/ip_warmups/{addr}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ip-address-warmup/get-v3-ip-warmups--addr-.md): Retrieves the status of an in-flight IP warmup, which must be a dedicated IP owned by the account. ### Creates a warmup plan for an IP Address - [POST /v3/ip_warmups/{addr}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ip-address-warmup/post-v3-ip-warmups--addr-.md): Creates a new warmup plan for an IP address. The IP must be dedicated and owned by the account. ### Cancels the warmup plan for an IP address - [DELETE /v3/ip_warmups/{addr}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ip-address-warmup/delete-v3-ip-warmups--addr-.md): Cancels the warmup plan for an IP address. The IP must be dedicated and owned by the account. ## Subaccounts Mailgun supports the creation, modification, and deletion of subaccounts. A subaccount is a child account of a parent account. The parent account can have multiple subaccounts. The subaccounts are created and managed by the parent account. ### Get a single subaccount - [GET /v5/accounts/subaccounts/{subaccount_id}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/subaccounts/get-v5-accounts-subaccounts-subaccount_id.md): Fetch the details of a single subaccount ### List all subaccounts - [GET /v5/accounts/subaccounts](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/subaccounts/get-v5-accounts-subaccounts.md): Fetch all subaccounts ### Create a subaccount - [POST /v5/accounts/subaccounts](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/subaccounts/post-v5-accounts-subaccounts.md): Create a subaccount ### Delete a subaccount - [DELETE /v5/accounts/subaccounts](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/subaccounts/delete-v5-accounts-subaccounts-subaccount_id.md): Delete a subaccount ### Disable a subaccount - [POST /v5/accounts/subaccounts/{subaccount_id}/disable](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/subaccounts/post-v5-accounts-subaccounts-subaccount_id-disable.md): Disable a subaccount ### Enable a subaccount - [POST /v5/accounts/subaccounts/{subaccount_id}/enable](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/subaccounts/post-v5-accounts-subaccounts-subaccount_id-enable.md): Enable a subaccount ### Get current custom sending limit - [GET /v5/accounts/subaccounts/{subaccount_id}/limit/custom/monthly](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/subaccounts/get-v5-accounts-subaccounts-subaccount_id-limit-custom-monthly.md): Fetch the details of custom sending limit on the account ### Set a custom sending limit - [PUT /v5/accounts/subaccounts/{subaccount_id}/limit/custom/monthly](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/subaccounts/put-v5-accounts-subaccounts-subaccount_id-limit-custom-monthly.md): Set a custom sending limit ### Delete a custom sending limit - [DELETE /v5/accounts/subaccounts/{subaccount_id}/limit/custom/monthly](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/subaccounts/delete-v5-accounts-subaccounts-subaccount_id-limit-custom-monthly.md): Delete a custom sending limit ### Update subaccount feature - [PUT /v5/accounts/subaccounts/{subaccount_id}/features](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/subaccounts/put-v5-accounts-subaccounts-subaccount_id-features.md): Update subaccount feature ## Custom Message Limit The custom message limit imposes a hard limit on how many messages your account can send during a calendar month. ### Get current custom sending limit - [GET /v5/accounts/limit/custom/monthly](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/custom-message-limit/get-v5-accounts-limit-custom-monthly.md): Fetch the details of custom sending limit on the account ### Set a custom sending limit - [PUT /v5/accounts/limit/custom/monthly](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/custom-message-limit/put-v5-accounts-limit-custom-monthly.md): Set a custom sending limit ### Delete a custom sending limit - [DELETE /v5/accounts/limit/custom/monthly](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/custom-message-limit/delete-v5-accounts-limit-custom-monthly.md): Delete a custom sending limit ### Re-enable account disabled for hitting send limit - [PUT /v5/accounts/limit/custom/enable](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/custom-message-limit/put-v5-accounts-limit-custom-enable.md): Re-enable an account that was disabled for reaching the custom sending limit ## Account Management Perform account-level CRUD operations. ### Update variable account settings - [PUT /v5/accounts](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/account-management/put-v5-accounts.md): Update variable account settings ### Get webhook signing key saved on the account - [GET /v5/accounts/http_signing_key](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/account-management/get-v5-accounts-http_signing_key.md): Get webhook signing key saved on the account ### Create or regenerate webhook signing key on an account - [POST /v5/accounts/http_signing_key](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/account-management/post-v5-accounts-http_signing_key.md): Create or regenerate webhook signing key on an account ### Get authorized email recipients for a sandbox domain - [GET /v5/sandbox/auth_recipients](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/account-management/get-v5-sandbox-auth_recipients.md): Get webhook signing key saved on the account ### Add authorized email recipient for a sandbox domain - [POST /v5/sandbox/auth_recipients](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/account-management/post-v5-sandbox-auth_recipients.md): Add authorized email recipient for a sandbox domain ### Remove an authorized sandbox domain email recipient - [DELETE /v5/sandbox/auth_recipients/{email}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/account-management/delete-v5-sandbox-auth_recipients-email.md): Remove an authorized sandbox domain email recipient ### Resend account activation email to the account owner - [POST /v5/accounts/resend_activation_email](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/account-management/post-v5-accounts-resend_activation_email.md): Resend account activation email to the account owner ## Keys The Keys API lets you view and manage API keys. ### List Mailgun API keys - [GET /v1/keys](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/keys/get-v1-keys.md): List Mailgun API keys ### Create Mailgun API key - [POST /v1/keys](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/keys/post-v1-keys.md): Create Mailgun API key ### Delete Mailgun API key - [DELETE /v1/keys/{key_id}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/keys/delete-v1-keys--key-id-.md): Delete Mailgun API key ### Regenerate Mailgun Public API key - [POST /v1/keys/public](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/keys/post-v1-keys-public.md): Regenerate Mailgun Public API key ## Credentials The Credentials API lets you view and manage SMTP credentials. ### List Mailgun SMTP credential metadata for a given domain - [GET /v3/domains/{domain_name}/credentials](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/credentials/get-v3-domains--domain-name--credentials.md): List Mailgun SMTP credential metadata for a given domain ### Create Mailgun SMTP credentials for a given domain - [POST /v3/domains/{domain_name}/credentials](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/credentials/post-v3-domains--domain-name--credentials.md): Create Mailgun SMTP credentials for a given domain ### Delete all Mailgun SMTP credentials for a domain - [DELETE /v3/domains/{domain_name}/credentials](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/credentials/delete-v3-domains--domain-name--credentials.md): Delete Mailgun SMTP credentials for a given domain ### Update Mailgun SMTP credentials - [PUT /v3/domains/{domain_name}/credentials/{spec}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/credentials/put-v3-domains--domain-name--credentials--spec-.md): Update Mailgun SMTP credentials for a given domain and SMTP user ### Delete Mailgun SMTP credentials - [DELETE /v3/domains/{domain_name}/credentials/{spec}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/credentials/delete-v3-domains--domain-name--credentials--spec-.md): Delete Mailgun SMTP credentials for a given domain and SMTP user ## IP Allowlist The IP Allowlist API lets you view and manage allowlisted IP addresses to which API key and SMTP credential usage is restricted. ### List Mailgun account IP allowlist entries - [GET /v2/ip_whitelist](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ip-allowlist/get-v2-ip-whitelist.md): List Mailgun account IP allowlist entries ### Update individual Mailgun account IP allowlist entry's description - [PUT /v2/ip_whitelist](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ip-allowlist/put-v2-ip-whitelist.md): Update individual Mailgun account IP allowlist entry's description ### Add Mailgun account IP allowlist entry - [POST /v2/ip_whitelist](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ip-allowlist/post-v2-ip-whitelist.md): Add Mailgun account IP allowlist entry ### Delete Mailgun account IP allowlist entry - [DELETE /v2/ip_whitelist](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/ip-allowlist/delete-v2-ip-whitelist.md): Delete Mailgun account IP allowlist entry ## Users Mailgun API supports viewing user entities. ### Get users on an account - [GET /v5/users](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/users/get-v5-users.md): Get users on an account ### Get a user's details - [GET /v5/users/{user_id}](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/users/get-v5-users-user_id.md): Get details for a user on the account ### Get one's own user details - [GET /v5/users/me](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/users/get-v5-users-me.md): Get one's own user details, requires use of an API key with a saved on it, typically of 'web' kind --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/sending-messages/mailing-lists.md # Mailing Lists Mailing Lists are a great way to send to multiple recipients while using an email alias. When you use mailing lists, Mailgun will send a copy of the message to each subscribed member using the email alias. You can create and maintain your subscriber lists using the API or Control Panel. In addition, you can use Template Variables to create a unique message for each member of the mailing list. ### Using Mailing Lists 1. Create a mailing list email address (example: devs@example.com) 2. Add member email addresses to the mailing list 3. Each time you send a message using the mailing list email address (example: devs@example.com), a copy of the email is delivered to each subscribed member. ### Managing a Mailing List You can create Mailing Lists using the Mailing Lists tab in the Control Panel or through the API. To make it easier, Mailgun has support for a couple different formats to upload Mailing List members: - You can upload a CSV file with the members. - You can use a JSON array form parameter - You can use form-like file upload Creating a mailing list through the API: ```bash curl -s --user 'api:YOUR_API_KEY' \ https://api.mailgun.net/v3/lists \ -F address='LIST@YOUR_DOMAIN_NAME' \ -F description='Mailgun developers list' ``` Adding a single member through the API: ```bash curl -s --user 'api:YOUR_API_KEY' \ https://api.mailgun.net/v3/lists/LIST@YOUR_DOMAIN_NAME/members \ -F subscribed=True \ -F address='bar@example.com' \ -F name='Bob Bar' \ -F description='Developer' \ -F vars='{"age": 26}' ``` Adding multiple members using the JSON array approach, you can either send a flat list of member addresses: ```bash curl -s --user 'api:YOUR_API_KEY' \ https://api.mailgun.net/v3/lists/LIST@YOUR_DOMAIN_NAME/members.json \ -F members='["alice@example.com","bob@example.com"]' ``` Members added this way are implicitly set as `subscribed`. Alternatively, you can provide the full JSON payload expected for a member for the same fine-grained control when adding a single member: ```bash curl -s --user 'api:YOUR_API_KEY' \ https://api.mailgun.net/v3/lists/LIST@YOUR_DOMAIN_NAME/members.json \ -F members='[{"name": "Bob Bar", "address": "bar@example.com", "subscribed": true, "vars": "{}"}]' ``` Info Note the use of `vars` to attach a JSON dictionary with structured data to each member of the mailing list. You can reference that data in the body of the message using Template Variables. There are two modes available when adding a new member, strict and upsert. - Strict will raise an error in case the member already exists. - Upsert will update an existing member if it's already in the list or insert a new one. Learn how to toggle between the modes and skip malformed addresses in the API documentation pages for the Mailing Lists API ### Sending to a Mailing List Sending to a Mailing List is as easy as using one of our APIs, HTTP or SMTP, and sending an email to the address created for the Mailing List as the recipient. You can set the access level on Mailing Lists to: - Only allow the administrator to post to the list (limited to an API call or authenticated SMTP session) - Allow Mailing List members to post to the list - Allow anybody to post to the list ### Replying to a Mailing List You can set the preferred method to where a reply to the list should go: - `list` Replies to the list go to the list address. This is the default setting for any new list created, except for read-only lists, where replies can only go to the sender. Reply-all will still go to the list. - `sender` Replies to the list going to the sender (FROM) address. This is the default and the only option for read-only lists. ### Template Variables There are some pre-defined variables you can use to personalize your message to each recipient. | Header | Description | | --- | --- | | `%recipient%` | Full recipient spec, like “Bob [bob@example.com](mailto:bob@example.com)” (for using as value for “To” MIME header). | | `%recipient_email%` | Recipient’s email address, like bob@example.com. | | `%recipient_name%` | Recipient’s full name, like “John Q. Public”. | | `%recipient_fname%` | Recipient’s first name. | | `%recipient_lname%` | Recipient’s last name. | | `%unsubscribe_url%` | A generated URL which allows users to unsubscribe from messages. | | `%mailing_list_unsubscribe_url%` | A generated URL which allows users to unsubscribe from mailing lists. | | `%unsubscribe_email%` | An email address which can be used for automatic unsubscription by adding it to List-Unsubscribe MIME header. | | `%recipient.yourvar%` | Accessing a custom datavalue. (see Attaching Data to Messages) | ### Unsubscribing To manage unsubscribes in Mailing Lists, you can use %mailing_list_unsubscribe_url%. Mailgun will generate a unique link to unsubscribe from the mailing list. Once a recipient clicks on the unsubscribe link. The recipient is marked as "unsubscribed" from this mailing list and won't get any further emails addressed to this list. Info You can still override the "unsubscribe" setting via the API or the Control Panel (in case of user error or accidental unsubscribe). You can also manually unsubscribe to the customer without using any links via the API or the Control Panel. Read more in the Mailing Lists API section. ### Mailing Lists and Routes Mailing lists work independently from Routes. When there is a Mailing List or Route with the same address, the incoming message will hit the Route and Mailing List simultaneously. This can be convenient for processing replies to the Mailing List and integrating into things like forums or commenting systems. --- # Source: https://documentation.mailgun.com/docs/mailgun/email-best-practices/mailinglists.md # Mailing Lists The number one reason we see people getting blocked is due to them having a bad mailing list. You should only send emails to people that have opted in to receiving your emails on YOUR website. In addition, you should be sending a verification email with a link that confirms their subscription (double opt-in) to make sure their email address is correct and that they are the person that signed up. You should have your Privacy Policy easily accessible on your website. In addition, you should have a place on your website where users can unsubscribe from your mailings, in addition to a link in every email you send. While you are responsible for procuring your mailing list, Mailgun does track and give you data to easily see how your emails are being received. We also give you information for bounces, unsubscribes, complaints, opens and clicks so that you can modify your mailing lists appropriately. In addition, we automate a lot of the work by keeping track of recipients that have unsubscribed, bounced or complained and stopping future deliveries to those recipients. We give you various levels of unsubscribe granularity so your recipients can unsubscribe to all emails from the domain, just that mailing list or just emails with that "tag" (which you define). Tip: **Do not purchase your list or scrape websites for emails.** It's the easy way out, but you will pay the consequences. Most of these lists have bad email addresses and include spam traps. MBPs (Mailbox Providers) are very good at recognizing bad mailing lists. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/sending-messages/message-queue.md # Message Queue The queuing algorithms are one of the most important features of Mailgun. If you try sending bulk mailings all at once, most ISPs will block you. Mailgun will put your messages in a message queue when you submit them for delivery. - A large number of messages can be submitted. - Mailgun will automatically queue for the delivery in compliance with the receiving domains' guidelines and maximum sending rate optimized for each ESP (email service provider), such as Yahoo, Gmail, etc. - The messaging queue is dynamic. - Your messages may take longer at first, however, your sending rates will increase the more you send messages. - As your reputation grows, your sending rate will grow too. Note: Note: It is important to make sure you are sending quality traffic to ensure sending rates. It is important to gradually increase your sending rates according to many factors, including: - Consistency of traffic - IP address sending history - Domain reputation. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/reporting/metric-definitions.md # Metric Definitions Mailgun's Metrics API offers endpoints to access summarized data, including counts, rates, and dimensions. It supports up to 10 counts and rates, as well as 3 dimensions. ## Metric Definitions | Metric Label | API Variable Name | Calculation | Description | | --- | --- | --- | --- | | Accepted | accepted_count | accepted_incoming_count + accepted_outgoing_count | A sum of incoming and outgoing accepted events. This includes all accepted emails to be sent as well as routes, forwards, mailing lists, and batch events. To only view accepted events on emails sent to recipients, use the Accepted Outgoing metric. Accepted events are not associated to IP addresses. The “processed” metric can be used in place of accepted to view similar data by IP. | | Accepted incoming | accepted_incoming_count | Sum of all raw accepted_incoming events. | Mailgun accepted the API request to forward, and the message has been put in your queue. These accepted events only cover routes, forwards, and mailing lists. Mailing lists will record a single accepted incoming event, with emails sent to recipients recording their own accepted outgoing events. | | Accepted outgoing | accepted_outgoing_count | Sum of all raw accepted_outgoing events. | Mailgun accepted the API request to send, and the message was put in your queue. Batch sends will result in one additional accepted outgoing event to record the initial batch request. Accepted events are not associated to IP addresses. The “processed” metric can be used in place of accepted to view data by IP. | | Bounced (all) | bounced_count | permanent_failed_count -(suppressed_bounces_count + suppressed_complaints_count + suppressed_unsubscribed_count) | A sum of all soft and hard bounces. Permanent failures fall into three categories, soft bounces, hard bounces, and suppressions. This field is equal to permanent failures minus suppressions. | | Clicked | clicked_count | Sum of all raw clicked events | The email recipient clicked on a link in the email. Click tracking must be turned on and the CNAME record must be pointing to mailgun.org. | | Complained | complained_count | Sum of all raw complained events | The email recipient clicked on the spam complaint button and the recipient's email server provides feedback loops to Mailgun for these complaints. | | Delayed bounces | delayed_bounce_count | Sum of all raw failed events with a severity equal to “permanent” and is-delayed-bounce equals true. | Emails were initially marked as delivered, but later received a permanent failure from the mailbox provider. | | Delayed first attempt | delayed_first_attempt_count | delivered_two_plus_attempts_count + permanent_failed_old_count | Emails that were temporarily rejected on the first delivery attempt. These emails will have been retried until delivery or until a “too old” permanent failure is generated. | | Delivered | delivered_count | delivered_http_count + delivered_smtp_count | Mailgun sent the email and it was accepted by the recipient email server. | | Delivered first attempt | delivered_first_attempt_count | Sum of all raw delivered events with delivery-status.attempt-no equal to 1. | Emails that were delivered on the first delivery attempt without being delayed or bounced. | | Delivered HTTP | delivered_http_count | Sum of all raw delivered_http events at the hourly, daily, and monthly resolutions. | The count of delivered events for routes and forwards. | | Delivered optimized | delivered_optimized_count | Sum of all raw delivered events that had optimized set to true. | Emails delivered with Send Time Optimization. | | Delivered SMTP | delivered_smtp_count | Sum of all raw delivered_smtp events. | The count of delivered events for emails sent to recipient addresses. | | Delivered two plus attempts | delivered_two_plus_attempts_count | Sum of all raw delivered events with delivery-status. Attempt-no greater than or equal to 2. | Emails that were delivered after two or more delivery attempts. This indicates the emails received at least one temporary failure. | | ESP blocked | esp_block_count | Sum of all raw failed events with a severity that does not equal “permanent” and a reason equal to “espblock“. | Emails that were temporarily blocked by the ESP for policy errors and reputation rate limiting. | | Failed (all) | failed_count | permanent_failed_count + temporary_failed_count | A sum of all permanent and temporary failures. | | Hard bounces | hard_bounces_count | Sum of all raw failed events with a severity equal to “permanent”, a reason equal to “bounce“, and is-delayed-bounce equal to false. | A hard bounce is a message that cannot be delivered to its intended recipient due to an invalid recipient address or non-existent mailbox. These addresses will be automatically added to your suppressions list when you receive a hard bounce to prevent subsequent hard bounces. | | Opened | opened_count | Sum of all raw opened events at the hourly, daily, and monthly resolutions. | The email recipient opened the email and enabled image viewing. Tracking must be turned on. | | Permanent failed | permanent_failed_count | Sum of all raw failed events with a severity equal to “permanent”. | Mailgun could not deliver the email to the recipient email server, and will drop the message without retrying sending. | | Permanent failed optimized | permanent_failed_optimized_count | Sum of all raw failed events with a severity equal to “permanent”, a reason equal to “bounce“, and i-delivery-optimizer is not empty. | Events that were sent with send time optimization, but received a permanent failure. | | Permanent failed old | permanent_failed_old_count | Sum of all raw failed events with a severity equal to “permanent” and “reason” equal to “old”. | Mailgun attempted to deliver the email for the maximum number of retry attempts, but received a temporary failure each time. Upon the last retry attempt, the message was classified as a ”Too Old” permanent failure. | | Processed | processed_count | delivered_count + permanent_failed_count - webhook_count - delayed_bounce_count | Messages processed after being accepted. Processed messages are billed to your account at the end of the month. | | Sent | sent_count | (delivered_http_count + delivered_smtp_count + permanent_failed_count) - (suppressed_bounces_count + suppressed_complaints_count + suppressed_unsubscribed_count) | A count of all sent messages. This includes delivered and failed messages, but does not include suppressed messages. | | Soft bounces | soft_bounces_count | Sum of all raw failed events with a severity equal to "permanent", a reason equal to "generic", "greylisted", "blacklisted", or "espblock", and is-delayed-bounce equal to false. | A soft bounce is a message that cannot be delivered to its intended recipient due to a temporary delivery issue, often stemming from a server outage, full mailbox, oversize files/messages, blocklistings, or reputation issues. Mailgun treats soft bounces as permanent failures, meaning we will not automatically attempt to redeliver the message. The recipient address will not be added to the suppression list, and the next time you attempt to send a message to this recipient we will attempt to deliver. | | Suppressed: bounced | suppressed_bounces_count | Sum of all raw failed events with a severity equal to “permanent” and a reason equal to “suppress-bounce“. | The email was suppressed due to a previous bounce with the recipient address. No delivery attempt was made. | | Suppressed: complaints | suppressed_unsubscribed_count | Sum of all raw failed events with a severity equal to “permanent” and a reason equal to “suppress-complaint“. | The email was suppressed due to a previous complaint from the recipient. No delivery attempt was made. | | Suppressed: unsubscribed | unsubscribed_rate | Sum of all raw failed events with a severity equal to “permanent” and a reason equal to “suppress-unsubscribe“. | The unsubscribe rate accounts for the total number of unsubscribes divided by the total number of emails delivered and multiplied by 100, expressed as a percentage. | | Temporary failed | temporary_failed_count | Sum of all raw failed events with a severity that does not equal “permanent”. | Mailgun could not deliver the email to the recipient email server, but will retry. | | Unique clicked | unique_clicked_count | Sum of all unique_clicked events. A unique click event is for a particular messageID, recipient, and bot. Only a single click event is stored for the particular {messageID, recipient,bot} combination. | A unique count of click events. Clicks are deduplicated on a rolling seven days. If you’re viewing two weeks of data, it’s possible to see two unique click events for a single delivered event. Keep in mind date ranges when viewing unique clicks, if your date filter doesn’t include the delivery event, you may see more unique clicks than delivered events. | | Unique opened | unique_opened_count | Sum of all unique_opened events. A unique open event is for a particular messageID, recipient, and bot. Only a single open event is stored for the particular {messageID, recipient,bot} combination. | A unique count of open events. Opens are deduplicated on a rolling seven days. If you’re viewing two weeks of data, it’s possible to see two unique open events for a single delivered event.Keep in mind date ranges when viewing unique opens, if your date filter doesn’t include the delivery event, you may see more unique opens than delivered events. | | Unsubscribed | unsubscribed_count | Sum of all raw unsubscribed events at the hourly, daily, and monthly resolutions | The email recipient clicked on the unsubscribe link. Unsubscribe tracking must be turned on. | | Webhook Failed | webhook_count | Sum of all raw failed events with a severity equal to “permanent” and is-callback equals true. | A count of failed webhook events. | ## Rate Definitions html table tr th Rate Label th API Variable Name th Calculation th Definition (Used in tooltip) tr td Bounced td bounce_rate td bounced_count / processed_count td Bounce rate measures the percentage of emails that bounce back, or the number of emails that couldn’t be delivered to users over the total number of emails sent. tr td Clicked td clicked_rate td clicked_count / delivered_count td The rate at which delivered emails are clicked. This calculation uses total clicks, not unique clicks. Use the unique click rate if percentages exceed 100%. tr td Complained td complained_rate td complained_count / delivered_count td Complaint rate measures the percentages of delivered emails reported as spam by recipients. This rate should be kept below 0.1%. Please note that Gmail does not provide complaints, to see Gmail complaint data, sign up for Google Postmaster Tools. tr td Delayed td delayed_rate td delivered_two_plus_attempts_count / delivered_count td The percentage of emails that were delivered with two or more delivery attempts. This rate does not include delayed emails that could not be delivered. tr td Delivered td delivered_rate td delivered_count / sent_count td The rate at which sent emails are delivered to recipient addresses. This calculation does not include suppressed emails. tr td Failed td permanent_fail_rate td permanent_failed_count / processed_count td The percentage of sent emails that resulted in a permanent failure. These emails could not be delivered and will not be retried. tr td Opened td opened_rate td opened_count / delivered_count td The rate at which delivered emails are opened. This calculation uses total opens, not unique opens. Use the unique open rate if percentages exceed 100%. tr td Unique clicked td unique_clicked_rate td unique_clicked_count / delivered_count td The percentage of delivered emails that resulted in a unique click event. This calculation will exceed 100% if your date filter excludes a large amount of delivery events. tr td Unique opened td unique_opened_rate td unique_opened_count / delivered_count td The percentage of delivered emails that resulted in a unique open event. This calculation will exceed 100% if your date filter excludes a large amount of delivery events. tr td Unsubscribed td unsubscribed_rate td unsubscribed_count / delivered_count td The unsubscribe rate accounts for the total number of unsubscribes divided by the total number of emails delivered and multiplied by 100, expressed as a percentage. # Metrics API and Usage Reporting Mailgun collects a variety of different events and generates analytic reports based on both account and usage metrics. Visit [Metrics API](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/metrics) for more details. Note: Usage data is available starting 09/01/24. # Events Mailgun retains event data for 30 days. Access to this data varies by plan. Refer to our [Pricing page](https://www.mailgun.com/pricing/) for details. ## Tracked Events | Event | Description | | --- | --- | | `accepted` | Mailgun accepted the request to send/forward the email and the message has been placed in queue. | | `rejected` | Mailgun rejected the request to send/forward the email. | | `delivered` | Mailgun sent the email, and it was accepted by the recipient email server. | | `failed` | Mailgun could not deliver the email to the recipient email server. | | `opened` | The email recipient opened the email and enabled image viewing. Open tracking must be enabled in the Mailgun control panel, and the CNAME record must be pointing to mailgun.org. | | `clicked` | The email recipient clicked on a link in the email. Click tracking must be enabled in the Mailgun control panel, and the CNAME record must be pointing to mailgun.org. | | `unsubscribed` | The email recipient clicked on the unsubscribe link. Unsubscribe tracking must be enabled in the Mailgun control panel. | | `complained` | The email recipient clicked on the spam complaint button within their email client. Feedback loops enable the notification to be received by Mailgun. | | `stored` | Mail has stored an incoming message. | You can access Events through a few interfaces: - Webhooks (we POST data to your configured URL(s)) - [The Logs API](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/logs). - The **Logs** tab of the Control Panel (GUI) ## Filter Field Log Records can be filtered by the following fields: | Filter | Comparators | Description | | --- | --- | --- | | `event` | =,!= | An event type. For a complete list of all events written to the log see the Event Types table below. | | `mailing_list_address` | contains, not contains | The email address of a mailing list the message was originally sent to. | | `attachment_filename` | =,!= | A name of an attached file | | `from` | =, !=, contains, not contains | An email address mentioned in the from MIME header. | | `message_id` | =, != | A Mailgun message id returned by the messages API | | `subject` | =, !=, contains, not contains | A subject line | | `to` | contains, not contains | An email address mentioned in the MIME header | | `size` | >,< | Message size. | | `recipients` | contains, not contains | This field tracks all the potential message recipients. | | `tag` | =, != | User defined tag | | `severity` | =,!= | Temporary or Permanent. Used to filter events based on severity, if exists. (Currently failed events only) | | `recipient` | =, !=, contains, not contains | The recipient of the message. | | `domain` | =, !=, contains, not contains | The domain of a sender. | | `ip` | =, != | IP address the event originated from. | | `ip_pool` | =, != | The sending ip pool. | | `recipient_domain` | =, != | The domain of the recipient. | | `recipient_provider` | =, != | The provider of the recipient. | | `country` | =, != | Two-letter country code (as specified by [ISO3166](http://www.iso.org/iso/country_codes.htm)) the event came from or ‘unknown’ if it couldn’t be determined. | | `bot` | =, !=, contains, not contains | The bot that opened the message (only present on opened/click events if bot performed the action). | | `subaccount` | =, != | The subaccount for which the message was sent. | | `device` | =, !=, contains, not contains | Device type the link was clicked on. Can be ‘desktop’, ‘mobile’, ‘tablet’, ‘other’ or ‘unknown’. | | `id` | =, != | The id of the log statement. | | `user_variables` | contains, not contains | The user variables from the message. | | `delivery_status_code` | =, != | The SMTP delivery status code. | | `delivery_status_message` | contains, not contains | The SMTP delivery status message. | | `is_routed ` | =, != | Indicates the message has been processed by a route. | | `i_classification_rule_id` | =, != | The classification rule id. | --- # Source: https://documentation.mailgun.com/docs/mailgun/api-reference/mg-auth.md # Authentication Authentication to the Mailgun API is done by providing an Authorization header using [HTTP Basic Auth:](http://en.wikipedia.org/wiki/Basic_access_authentication) - **Username:** `api` - **Password:** `YOUR_API_KEY` ### API keys Mailgun provides two types of API keys for authenticating against the API #### Primary account API key When you sign up for Mailgun, a primary account API key is generated. This key allows you to perform all CRUD operations via our various API endpoints and for any of your sending domains. To view your primary account API key: 1. **Go** to the **Mailgun Dashboard** 2. **Click** on **Account Settings** on the right-hand side. 3. **Select API Keys** and **click** on the eye icon next to **Private API** key. #### Domain Sending Keys Domain Sending Keys are API keys that only allow sending messages via a POST call on /messages and /messages.mime endpoints for the domain in which they are created for. To create a sending API key: 1. **Go** to the **Mailgun Dashboard** 2. **Click** the **Sending** tab on the left-hand side of the Mailgun dashboard 3. **Click** the **Domains** tab and select the domain in which you wish to add a sending key to 4. **Click** the **Domain Settings** and navigate to the **Sending API keys** tab 5. **Click** on **Add Sending Key** Give your key a suitable description (such as the name of the application or client you are creating the key for) and click Create Sending Key Copy your API key and keep it in a safe place. For security purposes, we will not be able to show you the key again. If you lose your key, you will need to create a new key. Here is how you use basic HTTP auth with curl: ```curl curl --user 'api:YOUR_API_KEY' ``` Warning! Important reminder to keep your API key safe and secure! --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/reporting/mg_reporting.md # Reporting Overview ## Reporting Dashboard Mailgun's Reporting Dashboard provides a quick and easy way to view your sending metrics and reports. You can view reports on both a graphical and tabular representation. You also have the ability to export the tabular data to a CSV. Note: By default, the Reporting Dashboard displays the last 24 hours of data and does not load tabular data. To learn more, see our article on [Reporting Dashboard](https://help.mailgun.com/hc/en-us/articles/4402703701019-Reporting-Dashboard?_gl=1*1f4xpey*_ga*MTY2NDk5NTk0MC4xNjgyMDk3MjE5*_ga_PZB2JSMCGC*MTcyMzczNTI2MS43Ni4xLjE3MjM3MzcwMjkuMC4wLjA.) ## Data Retention The following retention policy is applied to the metrics: Hourly stats are preserved for 60 days. Daily stats are preserved for 1 year. Monthly stats are stored indefinitely. --- # Source: https://documentation.mailgun.com/docs/mailgun/sdk/nodejs_sdk.md # Node.js a img Official Mailgun Node.JS SDK ### Installation - Requires node.js >= 18.x Install mailgun.js with: ```sh npm install mailgun.js ``` ## Setup Client Next, require the module and instantiate a mailgun client by calling `new Mailgun(formData)` and then using `mailgun.client` setup the client with basic auth credentials `(username: 'api', key: 'MAILGUN_API_KEY')`. NOTE: starting from version 3.0 you need to pass FormData (we need this to keep library universal). For node.js you can use `form-data` library. IMPORTANT: if you are using EU infrastructure, you need to also pass `url: 'https://api.eu.mailgun.net'` together with auth credentials as stated in [Mailgun docs](https://documentation.mailgun.com/docs/mailgun/api-reference/api-overview) ### Imports Once the package is installed, you can import the library using `import` or `require` approach: ```js const formData = require('form-data'); const Mailgun = require('mailgun.js'); const mailgun = new Mailgun(formData); const mg = mailgun.client({username: 'api', key: process.env.MAILGUN_API_KEY || 'MAILGUN_API_KEY'}); ``` ### Usage Here's a simple example on how to send an email. As always, please consult the repository readme for full details. ```JS mg.messages.create('sandbox-123.mailgun.org', { from: "Excited User ", to: ["test@example.com"], subject: "Hello", text: "Testing some Mailgun awesomness!", html: "

Testing some Mailgun awesomness!

" }) .then(msg => console.log(msg)) // logs response data .catch(err => console.error(err)); // logs any error ``` --- # Source: https://documentation.mailgun.com/docs/inboxready/onboarding-ir.md # Mailgun Optimize APIs Overview Mailgun Optimize by Sinch is a suite of deliverability tools and services that help take the complexity out of email deliverability. Here you will find the API's for Mailgun Optimize. Info To learn more about Optimize, see our article: [Mailgun Optimize: Introducing the best way to improve email deliverability](https://www.mailgun.com/blog/product/introducing-inboxready/) Below is a list of Mailgun Optimize APIs and an overview of each. Each of these represents a critical aspect of email deliverability and management, ensuring that your email campaigns achieve maximum reach and effectiveness. You will be able to see the various endpoints for each API by clicking on the dropdown for each API on the left sidebar. The complete [OpenAPI](https://www.openapis.org/) spec is available here: [Download OAS 3.1 Specification](https://documentation.mailgun.com/docs/inboxready/api-reference/optimize/inboxready) ## Domains Manage domains to monitor reputation. Use these APIs to register domains for domain-based reputation monitoring tools such as Bounce Classification, Spam Trap Monitoring, Domain Blocklist Monitoring,and Google Postmaster tools. ## Domain Blocklist Monitoring Similar to IP blocklist monitoring, this function focuses on keeping an eye on your domain’s presence in blocklists, providing an additional layer of security and reputation management for your email campaigns. Some of the monitored blocklists include: - Spamhaus DBL - URIBL - SURBL ## Spam Trap Monitoring Mailgun Optimize identifies and helps you avoid spam traps within your email lists. This feature is essential for maintaining a healthy sender reputation and ensuring that your emails are not flagged as spam. To learn more about spam traps, read our article, What are Spam Traps. ## Google Postmaster Tools Integration with Google Postmaster Tools allows you to gain insights into how your emails are performing within the Gmail ecosystem. This can include data on spam rates, domain reputation, and other metrics relevant to Gmail. ## Bounce Classification Identify critical bounces sent from Mailgun to quickly and easily identify problems with your sending. Continuing to generate bounces like this will lower your reputation and cause other problems with your sending. Our API classifies these bounces by sending domain and mailbox provider/spam filter. You can pull the logs on an individual bounce to get more details on the specific messages causing these bounces. ## IP Blocklist Monitoring This feature enables you to monitor IP blocklists, allowing you to take immediate action if your IP is listed. This is crucial for maintaining the integrity of your email campaigns and ensuring consistent deliverability. Monitored blocklists include: - SpamCop - CBL - Spamhaus SBL - Spamhaus PBL - Spamhaus XBL - Barracuda - Senderscore BL ## Microsoft SNDS (Smart Network Data Services) This feature provides data and insights into how your emails are being handled by Microsoft’s email services, like Outlook. This includes information on spam filtering and IP status, helping you optimize for one of the world’s largest email service providers. ## Inbox Placement This feature ensures that your emails land in the inbox and not the spam folder. By seed testing your emails, Mailgun Optimize can predict and improve where your emails will appear in various email services, like Gmail, with its tab organization. ### Creating Tests When creating a test, all requests must contain a `subject` property and one source property (`html` or `url`). All other properties are optional. ### Getting Test Info When getting test info, the call will return the subject and submission in UNIX timestamp format. It will also contain one to three properties containing any array of clients. The `completed` property shows clients that have completed screenshots uploaded. The `processing` property contains clients which are still processd by our system. The `bounced` property contains clients that were bounced by the destination and cannot be retried. ### Getting Test Results This returns detailed results for screenshots which include their upload locations, send times, completion times, and information about bounces,if any. The URLS in this call are static and will not change for the duration of your active test (90 days from test creation). Any reprocessing that is done will replace the images in these locations. The image locations are generated progammatically before the screenshots are complete. This means that the presence of the URL in the call is not a guarantee that the file will be present. Use the `status` property to determine whenther or not the file is present in the location, ot ou can manually test the URL provided. If the file is not present, you will receieve a 403 Forbidden response from the endpoint. ### Reprocess Screenshots Sometimes strange things happen on the internet. If a strange result has come back in your screenshot, use this function to tell us to retake screenshots free of charge. The request should contain and object with a property of `clients` that contains a list of clients in the `TEST_ID` provided. The object returned will have a `success` value indicating if the attemp was successful. If it is false, there will be a `reason` value describing the failure. For more on Blocklist Monitoring, see the article, How to Setup Blocklist Monitoring. ## Alerts Mailgun Optimize provides alerts that notify you of critical issues with your email program, such as blocklistings or other factors that could impact your email deliverability. This enables you to act swiftly to resolve issues. ## Email Health Score The Email Health Score API provides health scores for the overall account, as well as by domain, IP, and subaccount. Think of your email health score as the email equivalent of a credit score, assessing your email program's health and IP reputation. Ranging from 0 to 100, it indicates the quality of your sender reputation and reflects how mailbox providers perceive you IP address and domain. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/tracking-messages/open-click-bot-detect.md # Open and Click Bot Detection Mailgun uses tracking pixels and URL redirects to track when a user opens the message and clicks links in the email. However, there are various third-party automated systems that will automatically open and message and follow the links for virus scanning and user activity obfuscation, such as [Apple Mail Privacy Protection.](https://support.apple.com/guide/iphone/use-mail-privacy-protection-iphf084865c7/ios) Because automated systems can affect the accuracy of open and click tracking, Mailgun will attempt to detect when one of the systems retrieves the tracking pixel or clicks a link. When a bot is detected opening or clicking a link in the email, Mailgun will indicate this via the client-info.bot field in the open/click events. ```JSON { "client-info": { "client-name": "unknown", "client-type": "unknown", "user-agent": "Mozilla/5.0", "device-type": "unknown", "client-os": "unknown", "bot": "apple" }, "tags": [], "timestamp": 1652883435.279025, "recipient": "bot@apple.com", "geolocation": { "region": "Unknown", "country": "US", "city": "Unknown" }, "event": "opened", } ``` The bot field can have one of the possible values: | **Value** | **Description** | | --- | --- | | `apple` | Indicates Apple MPP bot | | `gmail` | Indicates a Gmail bot | | `generic` | Indicate an unknown bot (mostly likely a firewall or anti-virus scan) | | `(empty)` | If the bot field is empty, no bot was detected. | ## Tracking Unsubscribes Every time a recipient requests to unsubscribe from mailings, Mailgun can keep track of it. When you enable unsubscribe tracking, Mailgun will insert unsubscribe links and remove those recipients from your mailings automatically for you. To see unsubscribes, go to the Logs tab, or see counters of unsubscribes aggregated by tags found on the Analytics tab of the Control Panel. You can also get notifications through a webhook, or get data programmatically through the Events or Bounces API Mailgun supports three types of unsubscribe levels: domain, tag, Mailing Lists | **Unsubscribe Level** | **Description** | | --- | --- | | `Domain Level` | Once a recipient selects to unsubscribe from the domain, they will not receive any more messages from that sending domain. | | `Tag Level` | Sometimes traffic needs to be separated by different types of mailings, such as newsletters, security updates and other types. You may have recipients who would like to unsubscribe to a specific type of mailing you're sending out. For this reason, you can use tags by marking your messages with the appropriate X-Mailgun-Tag header, and use the special %tag_unsubscribe_url% variable (See the table below) | | `Mailing Lists Level` | When a recipient unsubscribes from a Mailing List, they will still be a member of the Mailing List, however, they will be flagged as unsubscribed, and Mailgun will no longer send messages from the Mailing List to the unsubscribed recipient. | --- # Source: https://documentation.mailgun.com/docs/inspect/api-reference/openapi-final.md # Source: https://documentation.mailgun.com/docs/validate/oas/openapi-final.md # Alerts Our alerting solution is centered around two concepts: events and channels. The occurrence of an event can be configured to trigger an alert. A channel describes the delivery method for an alert. Every configured alert consists of an event type / channel pair. This level of granularity allows alerting to be configured to your exact preference. Version: 0.0.1 ## Servers US Mailgun ``` https://api.mailgun.net ``` EU Mailgun ``` https://api.eu.mailgun.net ``` ## Security ### basicAuth HTTP Basic auth using api:YOUR_API_KEY. See [documentation](https://documentation.mailgun.com/docs/mailgun/api-reference/authentication/) Type: http Scheme: basic ### Inbox_Ready_basicAuth HTTP Basic auth using api:YOUR_API_KEY. See [documentation](https://documentation.mailgun.com/docs/mailgun/api-reference/authentication/) Type: http Scheme: basic ### Domain_Blocklist_Monitoring_basicAuth HTTP Basic auth using api:YOUR_API_KEY. See [documentation](https://documentation.mailgun.com/docs/mailgun/api-reference/authentication/) Type: http Scheme: basic ### Spamtraps_Analytics_Service_basicAuth HTTP Basic auth using api:YOUR_API_KEY. See [documentation](https://documentation.mailgun.com/docs/mailgun/api-reference/authentication/) Type: http Scheme: basic ### Inbox_Placement_Testing_basicAuth HTTP Basic auth using api:YOUR_API_KEY. See [documentation](https://documentation.mailgun.com/docs/mailgun/api-reference/authentication/) Type: http Scheme: basic ### Maverick_Score_basicAuth HTTP Basic auth using api:YOUR_API_KEY. See [documentation](https://documentation.mailgun.com/docs/mailgun/api-reference/authentication/) Type: http Scheme: basic ### DMARC_Reports_basicAuth HTTP Basic auth using api:YOUR_API_KEY. See [documentation](https://documentation.mailgun.com/docs/mailgun/api-reference/authentication/) Type: http Scheme: basic ### reputationanalytics_basicAuth HTTP Basic auth using api:YOUR_API_KEY. See [documentation](https://documentation.mailgun.com/docs/mailgun/api-reference/authentication/) Type: http Scheme: basic ## Download OpenAPI description [Alerts](https://documentation.mailgun.com/_spec/docs/validate/oas/openapi-final.yaml) ## Domains ### Returns Domains on Mailgun Optimize services - [GET /v1/inboxready/domains](https://documentation.mailgun.com/docs/validate/oas/openapi-final/domains/get-v1-inboxready-domains.md): Will return details on an Mailgun Optimize Domain. If no Domain is provided, then a list of all Mailgun Optimize Domains on an account will be returned. ### Add a single domain to an account - [POST /v1/inboxready/domains](https://documentation.mailgun.com/docs/validate/oas/openapi-final/domains/post-v1-inboxready-domains.md) ### Deletes a single domain from an account - [DELETE /v1/inboxready/domains](https://documentation.mailgun.com/docs/validate/oas/openapi-final/domains/delete-v1-inboxready-domains.md) ### Queues a domain to be processed for verification - [PUT /v1/inboxready/domains/verify](https://documentation.mailgun.com/docs/validate/oas/openapi-final/domains/put-v1-inboxready-domains-verify.md) ## DMARC Reports DMARC reporting provides valuable insights into your infrastructure, helping you identify potential issues like senders, misconfigured email servers, or phishing attempts. ### Retrieves the DMARC DNS records to be used for configuration - [GET /v1/dmarc/records/{domain}](https://documentation.mailgun.com/docs/validate/oas/openapi-final/dmarc-reports/get-v1-dmarc-records-domain-.md) ### Checks if DMARC has been setup for user - [GET /v1/dmarc/setup](https://documentation.mailgun.com/docs/validate/oas/openapi-final/dmarc-reports/get-v1-dmarc-setup-.md) ### Gets referral link to redsift - [POST /v1/dmarc/referral](https://documentation.mailgun.com/docs/validate/oas/openapi-final/dmarc-reports/post-v1-dmarc-referral-.md) ### Retrieves the list of domains that have DMARC monitoring. - [GET /v1/dmarc/domains](https://documentation.mailgun.com/docs/validate/oas/openapi-final/dmarc-reports/get-v1-dmarc-domains-.md) ### Retrieve DMARC reporting data for a domain. - [GET /v1/dmarc/domains/{domain}](https://documentation.mailgun.com/docs/validate/oas/openapi-final/dmarc-reports/get-v1-dmarc-domains-domain-.md) ### Retrieve DMARC reporting data from a specific source. - [GET /v1/dmarc/domains/{domain}/s/{source}](https://documentation.mailgun.com/docs/validate/oas/openapi-final/dmarc-reports/get-v1-dmarc-domains-domain-s-source-.md) ### Retrieve DMARC reporting data for a hostname. - [GET /v1/dmarc/domains/{domain}/s/{source}/h/{host}](https://documentation.mailgun.com/docs/validate/oas/openapi-final/dmarc-reports/get-v1-dmarc-domains-domain-s-source-h-host-.md) ### Retrieve DMARC reporting data for an IP Address. - [GET /v1/dmarc/domains/{domain}/s/{source}/h/{host}/ip/{ip}](https://documentation.mailgun.com/docs/validate/oas/openapi-final/dmarc-reports/get-v1-dmarc-domains-domain-s-source-h-host-ip-ip-.md) ## Inbox Placement Inbox Placement testing allows you to see the likely deliverability of your email campaigns. ### List Seed Lists - [GET /v4/inbox/seedlists](https://documentation.mailgun.com/docs/validate/oas/openapi-final/inbox-placement/get-v4-inbox-seedlists.md) ### Generate a New Seed List - [POST /v4/inbox/seedlists](https://documentation.mailgun.com/docs/validate/oas/openapi-final/inbox-placement/post-v4-inbox-seedlists.md) ### List Available Attributes for Seed Lists - [GET /v4/inbox/seedlists/a](https://documentation.mailgun.com/docs/validate/oas/openapi-final/inbox-placement/get-v4-inbox-seedlists-a.md) ### Get List of Values for Seed List Attribute - [GET /v4/inbox/seedlists/a/{attribute}](https://documentation.mailgun.com/docs/validate/oas/openapi-final/inbox-placement/get-v4-inbox-seedlists-a--attribute-.md) ### Get List of Available Seed List Filters - [GET /v4/inbox/seedlists/_filters](https://documentation.mailgun.com/docs/validate/oas/openapi-final/inbox-placement/get-v4-inbox-seedlists--filters.md) ### Get Seed List - [GET /v4/inbox/seedlists/{address}](https://documentation.mailgun.com/docs/validate/oas/openapi-final/inbox-placement/get-v4-inbox-seedlists--address-.md) ### Update Seed List - [PUT /v4/inbox/seedlists/{address}](https://documentation.mailgun.com/docs/validate/oas/openapi-final/inbox-placement/put-v4-inbox-seedlists--address-.md) ### Delete a Seed List - [DELETE /v4/inbox/seedlists/{address}](https://documentation.mailgun.com/docs/validate/oas/openapi-final/inbox-placement/delete-v4-inbox-seedlists--address-.md) ### List Results - [GET /v4/inbox/results](https://documentation.mailgun.com/docs/validate/oas/openapi-final/inbox-placement/get-v4-inbox-results.md): Get the details for all placement test results. ### List Available Attributes for Results - [GET /v4/inbox/results/a](https://documentation.mailgun.com/docs/validate/oas/openapi-final/inbox-placement/get-v4-inbox-results-a.md): The attributes that can have values listed (for autocomplete). ### Get List of Values for a Result Attribute - [GET /v4/inbox/results/a/{attribute}](https://documentation.mailgun.com/docs/validate/oas/openapi-final/inbox-placement/get-v4-inbox-results-a--attribute-.md): For the given attribute list the known values (for autocomplete). ### List available filters for Results - [GET /v4/inbox/results/_filters](https://documentation.mailgun.com/docs/validate/oas/openapi-final/inbox-placement/get-v4-inbox-results--filters.md): The filters that can be used when querying for results. ### Get Result Details - [GET /v4/inbox/results/{result}](https://documentation.mailgun.com/docs/validate/oas/openapi-final/inbox-placement/get-v4-inbox-results--result-.md): Get the details for a single result. ### Delete Result - [DELETE /v4/inbox/results/{result}](https://documentation.mailgun.com/docs/validate/oas/openapi-final/inbox-placement/delete-v4-inbox-results--result-.md): Delete the result and all associated information. ### Get Result Sharing Status - [GET /v4/inbox/sharing/{result}](https://documentation.mailgun.com/docs/validate/oas/openapi-final/inbox-placement/get-v4-inbox-sharing--result-.md): The sharing status of a result. ### Update Result Sharing Status - [PUT /v4/inbox/sharing/{result}](https://documentation.mailgun.com/docs/validate/oas/openapi-final/inbox-placement/put-v4-inbox-sharing--result-.md): Change the sharing status of a result or create a new share URL ### Get Result by a Share ID - [GET /v4/inbox/sharing/public/{shareid}](https://documentation.mailgun.com/docs/validate/oas/openapi-final/inbox-placement/get-v4-inbox-sharing-public--shareid-.md): Get a result by the share ID. ### Run Inbox Placement Test - [POST /v4/inbox/tests](https://documentation.mailgun.com/docs/validate/oas/openapi-final/inbox-placement/post-v4-inbox-tests.md): Create and run a new inbox placement test. Either 'html' or 'template_name' field should be provided. 'variables' are Template variables, which could be used in html or template. You can use next recipient variables inside Template variables, which will be filled for every seed automatically: %recipient.first_name%, %recipient.last_name%. ### List Email Providers - [GET /v4/inbox/providers](https://documentation.mailgun.com/docs/validate/oas/openapi-final/inbox-placement/get-v4-inbox-providers.md): List all available email providers. ## Spam Traps Monitoring Our spam trap monitoring service surfaces how much of your email is being sent to known spam traps. ### Get Spam Trap Hits - [GET /v1/spamtraps](https://documentation.mailgun.com/docs/validate/oas/openapi-final/spam-traps-monitoring/get-v1-spamtraps.md): Use this endpoint to understand how much of your mail being sent to known spam traps. This endpoint returns daily spam trap hit counts for a provided timerange, categorized by trap type. ## Email Health Score ### Get Email Health score and rates for account and subaccounts - [GET /v1/maverick-score/total](https://documentation.mailgun.com/docs/validate/oas/openapi-final/email-health-score/get-v1-maverick-score-total.md) ### List Email Health score and rates grouped by domains/ips/subaccounts/timestamps - [GET /v1/maverick-score/grouped](https://documentation.mailgun.com/docs/validate/oas/openapi-final/email-health-score/get-v1-maverick-score-grouped.md) ## IP Blocklist Monitoring ### Lists monitored IP addresses - [GET /v1/inboxready/ip_addresses](https://documentation.mailgun.com/docs/validate/oas/openapi-final/ip-blocklist-monitoring/get-v1-inboxready-ip-addresses.md) ### Register an IP address - [POST /v1/inboxready/ip_addresses](https://documentation.mailgun.com/docs/validate/oas/openapi-final/ip-blocklist-monitoring/post-v1-inboxready-ip-addresses.md) ### Get the IP address - [GET /v1/inboxready/ip_addresses/{ip}](https://documentation.mailgun.com/docs/validate/oas/openapi-final/ip-blocklist-monitoring/get-v1-inboxready-ip-addresses--ip-.md) ### Update the IP address - [PUT /v1/inboxready/ip_addresses/{ip}](https://documentation.mailgun.com/docs/validate/oas/openapi-final/ip-blocklist-monitoring/put-v1-inboxready-ip-addresses--ip-.md) ### Removes IP from monitoring - [DELETE /v1/inboxready/ip_addresses/{ip}](https://documentation.mailgun.com/docs/validate/oas/openapi-final/ip-blocklist-monitoring/delete-v1-inboxready-ip-addresses--ip-.md) ## Domain Blocklist Monitoring Blocklist Monitoring enables you to keep an eye on your reputation. Monitor your domains against our curated list of blocklist providers to make sure you aren't being blocked. ### Get Monitored Domains - [GET /v1/monitoring/domains](https://documentation.mailgun.com/docs/validate/oas/openapi-final/domain-blocklist-monitoring/get-v1-monitoring-domains.md): Gets all domains that are being monitored for blocklisting ### Get All Events - [GET /v1/monitoring/domains/events](https://documentation.mailgun.com/docs/validate/oas/openapi-final/domain-blocklist-monitoring/get-v1-monitoring-domains-events.md): Get all events for all domains monitored ### Get Lists Domain is Listed in - [GET /v1/monitoring/domains/{domain}/blocklists](https://documentation.mailgun.com/docs/validate/oas/openapi-final/domain-blocklist-monitoring/get-v1-monitoring-domains--domain--blocklists.md): Get blocklists that the domain is listed in ### Get Events for Domain - [GET /v1/monitoring/domains/{domain}/events](https://documentation.mailgun.com/docs/validate/oas/openapi-final/domain-blocklist-monitoring/get-v1-monitoring-domains--domain--events.md): Get events for a specific domain ## Google Postmaster Tools This API provides access to Google Postmaster data. ### Get GPT Domain - [GET /v1/reputationanalytics/gpt/domains/{domain}](https://documentation.mailgun.com/docs/validate/oas/openapi-final/google-postmaster-tools/get-v1-reputationanalytics-gpt-domains--domain-.md): Returns domain records for a single domain on the account. Each domain record is for a single domain on a single day. ### Get GPT Domains - [GET /v1/reputationanalytics/gpt/domains](https://documentation.mailgun.com/docs/validate/oas/openapi-final/google-postmaster-tools/get-v1-reputationanalytics-gpt-domains.md): Returns a list of all domain records for an account. Each domain record is for a single domain on a single day. ### Get GPT Domains - [GET /v1/reputationanalytics/gpt/domains_list](https://documentation.mailgun.com/docs/validate/oas/openapi-final/google-postmaster-tools/get-v1-reputationanalytics-gpt-domains-list.md): Returns a list of all domains for an account ### Get GPT FBL - [GET /v1/reputationanalytics/gpt/domainsfbl](https://documentation.mailgun.com/docs/validate/oas/openapi-final/google-postmaster-tools/get-v1-reputationanalytics-gpt-domainsfbl.md): Returns the FBL for the account or domain ### Get GPT FBL - [GET /v1/reputationanalytics/gpt/domainsfbl/{domain}](https://documentation.mailgun.com/docs/validate/oas/openapi-final/google-postmaster-tools/get-v1-reputationanalytics-gpt-domainsfbl--domain-.md): Returns the FBL for the account or domain ### Get GPT Address - [GET /v1/reputationanalytics/gpt/addresses/{address}](https://documentation.mailgun.com/docs/validate/oas/openapi-final/google-postmaster-tools/get-v1-reputationanalytics-gpt-addresses--address-.md): Returns address records for an single address on the account. Each address record is for a single address on a single day. ### Get GPT Addresses - [GET /v1/reputationanalytics/gpt/addresses](https://documentation.mailgun.com/docs/validate/oas/openapi-final/google-postmaster-tools/get-v1-reputationanalytics-gpt-addresses.md): Returns a list of all address records for an account. Each address record is for a single address on a single day. ### Get all GPT Addresses - [GET /v1/reputationanalytics/gpt/addresses_list](https://documentation.mailgun.com/docs/validate/oas/openapi-final/google-postmaster-tools/get-v1-reputationanalytics-gpt-addresses-list.md): Returns a list of all addresses for an account ### Get GPT Domain Addresses - [GET /v1/reputationanalytics/gpt/domains/{domain}/addresses](https://documentation.mailgun.com/docs/validate/oas/openapi-final/google-postmaster-tools/get-v1-reputationanalytics-gpt-domains--domain--addresses.md): Returns a list of all address records for an account belonging to a specific domain. Each address record is for a single address on a single day. ### Get GPT Summary - [GET /v1/reputationanalytics/gpt/summary](https://documentation.mailgun.com/docs/validate/oas/openapi-final/google-postmaster-tools/get-v1-reputationanalytics-gpt-summary.md): Returns a list of all summary records for an account. Each record is for a single domain's summary and error summary data. ### Get GPT Domains Summary - [GET /v1/reputationanalytics/gpt/summary/domains](https://documentation.mailgun.com/docs/validate/oas/openapi-final/google-postmaster-tools/get-v1-reputationanalytics-gpt-summary-domains.md): Returns a list of all domain summary records for an account. Each record is for a single domain's summary data. ### Get GPT Domains Error Summary - [GET /v1/reputationanalytics/gpt/summary/errors](https://documentation.mailgun.com/docs/validate/oas/openapi-final/google-postmaster-tools/get-v1-reputationanalytics-gpt-summary-errors.md): Returns a list of all domain error summary records for an account. Each record is for a single domain's error summary data. ### Get GPT Addresses Summary - [GET /v1/reputationanalytics/gpt/summary/addresses](https://documentation.mailgun.com/docs/validate/oas/openapi-final/google-postmaster-tools/get-v1-reputationanalytics-gpt-summary-addresses.md): Returns a list of all address summary records for an account. Each record is for a single address's summary data. ## Microsoft SNDS This API provides access to Microsoft SNDS data. ### Get SNDS Address Info - [GET /v1/reputationanalytics/snds](https://documentation.mailgun.com/docs/validate/oas/openapi-final/microsoft-snds/get-v1-reputationanalytics-snds.md): Returns a list of all address summary records for an account. Each record is for a single address's summary data. ### Get SNDS Address Info - [GET /v1/reputationanalytics/snds/{ip}](https://documentation.mailgun.com/docs/validate/oas/openapi-final/microsoft-snds/get-v1-reputationanalytics-snds--ip-.md): Returns a list of all address summary records for an account and a single address ## Alerts ### List events - [GET /v1/alerts/events](https://documentation.mailgun.com/docs/validate/oas/openapi-final/alerts/get-v1-alerts-events.md): The current list of events that you can chose to receive alerts for. ### Add Alert - [POST /v1/alerts/settings/events](https://documentation.mailgun.com/docs/validate/oas/openapi-final/alerts/post-v1-alerts-settings-events.md): Use this endpoint to add new alert settings record. ### Webhooks This section covers details around consuming Mailgun Optimize alerts via webhooks. If you are familiar with Mailgun Send webhooks, there is a lot of overlapping similarity, however, there are also a few minor nuances to account for. #### Securing Webhooks HMAC is used to verified to integrity as well as the authenticity of received webhooks. To verify the origin of a webhook: 1. Encode the webhook’s entire POST request body with the HMAC algorithm (using your webhook signing key and SHA256 digest mode) 2. Compare the resulting hexdigest to the signature provided in the POST request’s X-Sign header. NOTE: If you’re consuming Mailgun Send webhooks, please note that your Mailgun Send webhook signing key differs from your Mailgun Optimize alerts webhook signing key. Your Mailgun Optimize alerts webhook signing key is available within the Mailgun Optimize UI. #### Webhook URL Validation When adding or updating a webhook URL for alerts, we will ensure the endpoint is reachable by sending a GET request to the provided URL. If a 200 response is not returned from your endpoint, the request will be rejected and your alert setting will not be saved. We intentionally chose to send a GET request instead of a POST when validating URLs so that your webhook endpoint does not have to account for test requests. Additionally, when a POST request is sent to your webhook URL, if a 2xx is not returned, we will attempt retries via an exponential backoff strategy for up to ~8 hours. If the max retry count is reached, the alert will be disabled and the related alert settings record’s disabled_at field will be populated. ### Update Alert - [PUT /v1/alerts/settings/events/{id}](https://documentation.mailgun.com/docs/validate/oas/openapi-final/alerts/put-v1-alerts-settings-events--id-.md): Use this endpoint to update an existing alert setting record. NOTE: When updating a webhook alert, we will ensure the endpoint is reachable by sending a GET request to the provided URL. If a 200 response is not returned, a 400 will be returned and the alert setting update will be rejected. ### Remove Alert - [DELETE /v1/alerts/settings/events/{id}](https://documentation.mailgun.com/docs/validate/oas/openapi-final/alerts/delete-v1-alerts-settings-events--id-.md) ### List Alerts - [GET /v1/alerts/settings](https://documentation.mailgun.com/docs/validate/oas/openapi-final/alerts/get-v1-alerts-settings.md): This endpoint returns a list of all configured alert settings for your account. ### Update Slack settings - [PUT /v1/alerts/settings/slack](https://documentation.mailgun.com/docs/validate/oas/openapi-final/alerts/put-v1-alerts-settings-slack.md) ### Delete Slack settings - [DELETE /v1/alerts/settings/slack](https://documentation.mailgun.com/docs/validate/oas/openapi-final/alerts/delete-v1-alerts-settings-slack.md): Delete Slack settings and Slack event settings for the Mailgun account. To revoke the Slack access token, use DELETE /v1/alerts/slack/oauth. To completely remove the Slack App from Slack Workspace, go into App Configuration in Slack. ### Reset Webhook Signing Key - [PUT /v1/alerts/settings/webhooks/signing_key](https://documentation.mailgun.com/docs/validate/oas/openapi-final/alerts/put-v1-alerts-settings-webhooks-signing-key.md) ### Test webhook - [POST /v1/alerts/webhooks/test](https://documentation.mailgun.com/docs/validate/oas/openapi-final/alerts/post-v1-alerts-webhooks-test.md): Sends test webhook request to specified url with dummy data. ### Test message - [POST /v1/alerts/email/test](https://documentation.mailgun.com/docs/validate/oas/openapi-final/alerts/post-v1-alerts-email-test.md): Sends test message to emails with dummy data. ### Test message - [POST /v1/alerts/slack/test](https://documentation.mailgun.com/docs/validate/oas/openapi-final/alerts/post-v1-alerts-slack-test.md): Sends test message to slack channels with dummy data. ### Revoke Slack access token - [DELETE /v1/alerts/slack/oauth](https://documentation.mailgun.com/docs/validate/oas/openapi-final/alerts/delete-v1-alerts-slack-oauth.md): Revoke Slack access token, delete Slack settings and Slack event settings. NOTE: All Mailgun accounts connected to the same Slack workspace share the same token. To completely remove the Slack App from Slack Workspace, go into App Configuration in Slack. ### Get Slack channel - [GET /v1/alerts/slack/channels/{id}](https://documentation.mailgun.com/docs/validate/oas/openapi-final/alerts/get-v1-alerts-slack-channels--id-.md): Returns Slack channel. ### List Slack channels - [GET /v1/alerts/slack/channels](https://documentation.mailgun.com/docs/validate/oas/openapi-final/alerts/get-v1-alerts-slack-channels.md): List Slack channels for the connected Slack workspace. --- # Source: https://documentation.mailgun.com/docs/validate/oas/openapi-validate-final.md # Validations Service Mailgun Email Validation service with RESTful JSON HTTP API for performing email validation. This service also manages list and CSV ingestion used in bulk validation processing. Version: 1.0.0 ## Servers US Mailgun ``` https://api.mailgun.net ``` EU Mailgun ``` https://api.eu.mailgun.net ``` ## Security ### basicAuth HTTP Basic auth using api:YOUR_API_KEY. See [documentation](https://documentation.mailgun.com/docs/mailgun/api-reference/authentication/) Type: http Scheme: basic ## Download OpenAPI description [Validations Service](https://documentation.mailgun.com/_spec/docs/validate/oas/openapi-validate-final.yaml) ## Validations This API provides functionality to validate single addresses, and managing thresholds. ### Validate Address V4 - [GET /v4/address/validate](https://documentation.mailgun.com/docs/validate/oas/openapi-validate-final/validations/get-v4-address-validate.md): A single email address to validate. ## Bulk Validations This API provides functionality to upload and manage bulk validation lists and previews. ### Create Bulk Job - [POST /v4/address/validate/bulk/{list_id}](https://documentation.mailgun.com/docs/validate/oas/openapi-validate-final/bulk-validations/post-v4-address-validate-bulk--list-id-.md): Validate a full list of addresses. ### Get Job V4 - [GET /v4/address/validate/bulk/{list_id}](https://documentation.mailgun.com/docs/validate/oas/openapi-validate-final/bulk-validations/api.initv4api.(*apihelpers).isfreeorfishy.func2-9.md): Gets a selected job by list ID. ### Delete Job V4 - [DELETE /v4/address/validate/bulk/{list_id}](https://documentation.mailgun.com/docs/validate/oas/openapi-validate-final/bulk-validations/api.initv4api.(*apihelpers).isfreeorfishy.func1-8.md): Cancels a selected job by list ID. ### List Jobs V4 - [GET /v4/address/validate/bulk](https://documentation.mailgun.com/docs/validate/oas/openapi-validate-final/bulk-validations/api.initv4api.(*apihelpers).isfreeorfishy.func4-11.md): Returns all jobs. ### Get Job V3 - [GET /v3/lists/{list_id}/validate](https://documentation.mailgun.com/docs/validate/oas/openapi-validate-final/bulk-validations/api.initv3api.(*apihelpers).isfreeorfishy.func2-13.md): Gets a selected job by list ID. ### Create Job V3 - [POST /v3/lists/{list_id}/validate](https://documentation.mailgun.com/docs/validate/oas/openapi-validate-final/bulk-validations/api.initv3api.(*apihelpers).isfreeorfishy.func3-14.md): Starts a V3 list validation job. ### Delete Job V3 - [DELETE /v3/lists/{list_id}/validate](https://documentation.mailgun.com/docs/validate/oas/openapi-validate-final/bulk-validations/api.initv3api.(*apihelpers).isfreeorfishy.func1-12.md): Cancels a selected job by list ID. ## List Health Preview ### Get List Health Preview Job - [GET /v4/address/validate/preview/{list_id}](https://documentation.mailgun.com/docs/validate/oas/openapi-validate-final/list-health-preview/get-v4-address-validate-preview--list-id-.md): A single list health preview job by ID. ### Promote List Health Preview Job - [PUT /v4/address/validate/preview/{list_id}](https://documentation.mailgun.com/docs/validate/oas/openapi-validate-final/list-health-preview/put-v4-address-validate-preview--list-id-.md): A currently running list health preview job can be promoted to a full bulk validations job, which will validate all addresses in the list. ### Create a List Health Preview Job - [POST /v4/address/validate/preview/{list_id}](https://documentation.mailgun.com/docs/validate/oas/openapi-validate-final/list-health-preview/post-v4-address-validate-preview--list-id-.md): Start a list health preview job from a list of addresses. We will sample the list and run validations on a small percentage. ### Delete List Health Preview Job - [DELETE /v4/address/validate/preview/{list_id}](https://documentation.mailgun.com/docs/validate/oas/openapi-validate-final/list-health-preview/delete-v4-address-validate-preview--list-id-.md): Deletes a single list health previewk job by ID. ### List List Health Preview Jobs - [GET /v4/address/validate/preview](https://documentation.mailgun.com/docs/validate/oas/openapi-validate-final/list-health-preview/get-v4-address-validate-preview.md): All list health preview jobs you have started. --- # Source: https://documentation.mailgun.com/docs/inspect/overview.md # Mailgun Inspect: Your Email Pre-Send Quality Control Solution ## Overview Mailgun Inspect is an email pre-send quality control tool that ensures your emails are optimized for delivery, readability, and accessibility. By integrating Mailgun Inspect into your workflow, you can catch potential issues before they reach your recipients, saving time and improving your email campaigns' effectiveness. Mailgun Inspect empowers developers and marketers to deliver emails that meet the highest standards of quality and accessibility. ## Key Features - Mail Accessibility Testing: Ensure your emails comply with accessibility standards, such as WCAG, to make your content inclusive for all users. - Email Previews: Generate previews of your email across various clients and devices to ensure a consistent and polished look. - Link Validation: Verify the validity and status of links within your emails, ensuring recipients don't encounter broken or malicious URLs. - Image Validation: Check image properties such as dimensions, size, and availability to avoid rendering issues in email clients. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/sending-messages/pass-sending-options.md ## Passing Sending Options When sending emails there are a variety of sending options to consider. See the table below: - For HTTP please use the specified `o:` parameter, these are also found in our [API documentation](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/messages/post-v3--domain-name--messages) - For SMTP you must use the SMTP Headers below | HTTP Option | SMTP Header | Description | | --- | --- | --- | | `o:tag` | `X-Mailgun-Tag` | The Tag string is used for aggregating stats. You can make a message with several categories by setting multiple X-Mailgun-Tag headers. | | `o:dkim` | `X-Mailgun-Dkim` | Enables/disables DKIM signatures on a per-message basis. Use `yes` or `no` | | `o:testmode` | `X-Mailgun-Drop-Message` | Enables sending in test mode. Note: Sending in Test Mode will not actually deliver an email but will emit a `delivered` event with a 650 status code `Pass`, `yes`, or `no` if needed. | | `o:tracking` | `X-Mailgun-Track` | Toggles tracking on a per-message basis. `Pass`, `yes` or `no`. | | `o:tracking-clicks` | `X-Mailgun-Track-Clicks` | Toggles clicks tracking on a per-message basis. It has a higher priority than the domain-level setting. `Pass`, `yes`, `no`, or `htmlonly` | | `o:tracking-opens` | `X-Mailgun-Track-Opens` | Toggles opens tracking on a per-message basis. It has a higher priority than the domain-level setting. `Pass`, `yes` or `no` | | `o:sending-ip` | `X-Mailgun-Sending-Ip` | Used to specify an IP Address to send an email that is owned by your account | | `o:sending-ip-pool` | `X-Mailgun-Sending-Ip-Pool` | If an IP Pool ID is provided, the email will be delivered with an IP that belongs in that pool | | `o:require-tls` | `X-Mailgun-Require-TLS` | Use this header to control TLS connection settings. If set, Mailgun will only deliver the message over a secure TLS connection with the ESP. If TLS is not available, the delivery will fail | | `o:skip-verification` | `X-Mailgun-Skip-Verification` | Use this header to control TLS (Transport Layer Security) connection settings. | | `o:secondary-dkim` | `X-Mailgun-Secondary-DKIM` | Specify a second domain key to sign the email with. The value is formatted as `signing_domain,selector`, e.g. `example.com,s1`. This tells Mailgun to also sign the message with the signing domain `example.com` using the selector `s1`. Note: the domain key specified must have been created and activated. | | `o:secondary-dkim-public` | `X-Mailgun-Secondary-DKIM-Public` | This header specifies an alias of the domain key specified in `X-Mailgun-Secondary-DKIM`. Also formatted as `public_signing_domain/selector`. The `X-Mailgun-Secondary-DKIM` header must also be provided if this header is used. Mailgun will sign the message with the provided key of the secondary DKIM, but use the public secondary DKIM name and selector. Note: We will perform a DNS check prior to singing the message to ensure the public keye matches the secondary DKIM | | `o:deliverytime` | `X-Mailgun-Deliver-By` | Specifies the scheduled delivery time in [RFC-2822 format](https://documentation.mailgun.com/docs/mailgun/api-reference/api-overview#date-format). Depending on your billing plan, you can schedule messages up to 3 or 7 days in advance. If your domain has a custom message_ttl (time-to-live) setting, this value determines the maximum scheduling duration. Example: 'Fri, 14 Oct 2011 12:00:00 0000' | | `o:deliverytime-optimize-period` | `X-Mailgun-Delivery-Time-Optimize-Period` | Toggles STO on a per-message basis. The string should be set to the number of hours in `[0-9]+h` format. | | `o:deliver-within` | `X-Mailgun-Deliver-Within` | Specifies the maximum time window for delivering the message. Accepts values in format `[0-9]h[0-9]m` (e.g., `1h30m`, `30m`, `24h`), with a minimum of `5m` and maximum of `24h`. For scheduled messages, the delivery window starts from the scheduled time. The standard retry schedule applies within this window, so shorter timeframes may result in fewer delivery attempts. | | `o:time-zone-localize` | `X-Mailgun-Time-Zone-Localize` | Toggles TZO on a per-message basis. The string should be set to the preferred delivery time in `HH:mm` or `hh:mmaa` format, where `HH:mm` is used for a 24-hour format without AM/PM, and `hh:mmaa` is used for 12-hour format with AM/PM. | | `recipient-variables` | `X-Mailgun-Recipient-Variables` | Use this header to provide a JSON dictionary of variables to substitute for Batch messages. | | `template` | `X-Mailgun-Template-Name` | Name for the template to be rendered as the message body. | | `t:version` | `X-Mailgun-Template-Version` | Optional: Version of the template to be used, if different from the current active template. | | `v:key=value` | `X-Mailgun-Variables` | If sending with a Template, the provided data will be treated as the values to substitute with the templates variables. Note that `X-Mailgun-Template-Variables`/`t:variables` will override these if also provided. If a template is not used, the provided data will be treated as metadata and appended to the user-variabled field in events / webhooks. NOTE: These variables are visible in the email MIME! | | `t:variables` | `X-Mailgun-Template-Variables` | A valid JSON-encoded dictionary used as the input for template variable expansion. See Templates docs for more information. Note: These variables will be preferred over X-Mailgun-Variables, e.g. user variables | | `o:tracking-pixel-location-top` | `X-Mailgun-Track-Pixel-Location-Top` | If you send long emails that experience truncation or other rendering issues at the recipient, you can ensure opens are being tracked accurately with placement of the tracking pixel at the top of your emails | ### A common gotcha with Templates If you send an email with, only, a `text/plain body` *and* use the `X-Mailgun-Template-Name` header: this will *not* result in a template-rendered email. `text/plain` bodies are, typically, what you get when you send with Swaks! To get around this issue, add the correct `Content-Type` header accordingly: ``` --add-header 'Content-Type: text/html; charset="utf-8"' ``` You do *not* have to add this header explicitly via the HTTP API! --- # Source: https://documentation.mailgun.com/docs/mailgun/sdk/php_sdk.md # PHP a img Official Mailgun PHP SDK ### Installation **Required minimum php version** - minimum php version 7.3 To install the SDK, you will need to be using [Composer](http://getcomposer.org/) in your project. If you aren't using Composer yet, it's really simple! Here's how to install composer: ```bash curl -sS https://getcomposer.org/installer | php ``` The Mailgun API Client is not hard coupled to Guzzle, Buzz or any other library that sends HTTP messages. Instead, it uses the [PSR-18](https://www.php-fig.org/psr/psr-18/) client abstraction. This will give you the flexibility to choose what [PSR-7 implementation](https://packagist.org/providers/psr/http-factory-implementation) and [HTTP client](https://packagist.org/providers/psr/http-client-implementation) you want to use. If you want to get started quickly use PHP's package manager, [Composer](https://getcomposer.org/doc/00-intro.md) to get the SDK pulled into your project. If you have Composer installed globally run: ```bash composer require mailgun/mailgun-php symfony/http-client nyholm/psr7 ``` If Composer is not installed globally or if you are using a local version of Composer ```bash php composer.phar require mailgun/mailgun-php symfony/http-client nyholm/psr7 ``` ### Usage Here's a simple example on how to send an email. As always, please consult the repository readme for full details. You should always use Composer autoloader in your application to automatically load your dependencies. All the examples below assume you've already included this in your file: ```php require 'vendor/autoload.php'; use Mailgun\Mailgun; ``` Here's how to send a message using the SDK: ```php // First, instantiate the SDK with your API credentials $mg = Mailgun::create('MAILGUN_API_KEY'); // For US servers $mg = Mailgun::create('MAILGUN_API_KEY', 'https://api.eu.mailgun.net'); // For EU servers // Now, compose and send your message. // $mg->messages()->send($domain, $params); $mg->messages()->send('example.com', [ 'from' => 'bob@example.com', 'to' => 'sally@example.com', 'subject' => 'The PHP SDK is awesome!', 'text' => 'It is so simple to send a message.' ]); ``` --- # Source: https://documentation.mailgun.com/docs/mailgun/sdk/python_sdk.md # Python a img Official Mailgun Python SDK ## Installation ### pip install Use the below code to install the Mailgun SDK for Python: ```bash pip install mailgun-python ``` #### git clone & pip install locally Use the below code to install it locally by cloning this repository: ```bash git clone https://github.com/mailgun/mailgun-python cd mailgun-python ``` ```bash pip install . ``` #### conda & make Use the below code to install it locally by `conda` and `make` on Unix platforms: ```bash make install ``` ### For development #### Using conda on Linux or macOS: ```bash git clone https://github.com/mailgun/mailgun-python cd mailgun-python ``` - A basic environment with a minimum number of dependencies: ```bash make dev conda activate mailgun ``` - A full dev environment: ```bash make dev-full conda activate mailgun-dev ``` ### Usage Here's a simple example of how to send an email. As always, please consult the repository readme for full details. #### Send an email Pass the components of the messages such as To, From, Subject, HTML and text parts, attachments, etc. Mailgun will build a MIME representation of the message and send it. Note: In order to send you must provide one of the following parameters: 'text', 'html', 'amp-html' or 'template' ```python import os from pathlib import Path from mailgun.client import Client key: str = os.environ["MAILGUN_API_KEY"] domain: str = os.environ["DOMAIN"] client: Client = Client(auth=("api", key)) def post_message() -> None: # Messages # POST //messages data = { "from": os.getenv("MESSAGES_FROM", "test@test.com"), "to": os.getenv("MESSAGES_TO", "recipient@example.com"), "subject": "Hello from python!", "text": "Hello world!", "o:tag": "Python test", } req = client.messages.create(data=data, domain=domain) print(req.json()) ``` --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/events/query-options.md # Query Options URL parameters allow you to manipulate the results of your query. | Parameter | Description | | --- | --- | | begin | The beginning of the search time range. It can be specified as a string (see date-format) or linux epoch seconds. Refer to Time Range for details. | | end | The end of the search time range. It can be specified as a string (see `date-format`) or linux epoch seconds. Refer to Time Range for details. | | ascending | Defines the direction of the search time range and must be provided if the range end time is not specified. Can be either `yes` or `no`. Refer to Time Range for details. | | limit | Number of entries to return. (300 max) | | field | `field` is the name of the Filter Field. The value of the parameter should be a valid Filter Expression. Several field filters can be specified in one request. If the same field is mentioned, more than once, then all its filter expressions are combined with AND operator. | --- # Source: https://documentation.mailgun.com/docs/mailgun/quickstart.md # Quickstart: Send Your First Email Send an email in under two minutes using your sandbox domain ## Step 1: Sign up 1. [Sign up for Mailgun](https://signup.mailgun.com/new/signup) (free) Info After creating your account, follow the guided setup in your [Mailgun Dashboard](https://app.mailgun.com/welcome-guide) to activate your account and create your first API key. Both of these things will need to be done during this setup in order for you to continue. You can then choose to continue with the dashboards guide to quickly send your first email, or you can grab your API key and continue below. 1. Go to [API Keys](https://app.mailgun.com/settings/api_security) in your dashboard 2. Copy your **Private API key** ## Step 2: Add Authorized Recipient First, add your email as an authorized recipient. This will send a verification email to that address. cURL ```bash curl -X POST \ "https://api.mailgun.net/v5/sandbox/auth_recipients?email=your-email@example.com" \ --user 'api:YOUR_API_KEY' ``` Node.js ```javascript fetch('https://api.mailgun.net/v5/sandbox/auth_recipients?email=your-email@example.com', { method: 'POST', headers: { 'Authorization': 'Basic ' + Buffer.from('api:YOUR_API_KEY').toString('base64') } }) .then(res => console.log('Status:', res.status)) .catch(err => console.log('Error:', err.message)); ``` Python ```python import requests response = requests.post( "https://api.mailgun.net/v5/sandbox/auth_recipients?email=your-email@example.com", auth=("api", "YOUR_API_KEY") ) print(f"Status: {response.status_code}") ``` Java ```java import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.util.Base64; public class Main { public static void main(String[] args) throws Exception { String auth = Base64.getEncoder().encodeToString("api:YOUR_API_KEY".getBytes()); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://api.mailgun.net/v5/sandbox/auth_recipients?email=your-email@example.com")) .header("Authorization", "Basic " + auth) .POST(HttpRequest.BodyPublishers.noBody()) .build(); HttpResponse response = HttpClient.newHttpClient() .send(request, HttpResponse.BodyHandlers.ofString()); System.out.println("Status: " + response.statusCode()); } } ``` C# ```csharp using System; using System.Net.Http; using System.Text; var client = new HttpClient(); var auth = Convert.ToBase64String(Encoding.ASCII.GetBytes("api:YOUR_API_KEY")); client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", auth); var response = await client.PostAsync( "https://api.mailgun.net/v5/sandbox/auth_recipients?email=your-email@example.com", new StringContent("")); Console.WriteLine($"Status: {response.StatusCode}"); ``` PHP ```php ``` Go ```go package main import ( "fmt" "net/http" ) func main() { req, _ := http.NewRequest("POST", "https://api.mailgun.net/v5/sandbox/auth_recipients?email=your-email@example.com", nil) req.SetBasicAuth("api", "YOUR_API_KEY") client := &http.Client{} resp, _ := client.Do(req) fmt.Println("Status:", resp.Status) } ``` Rust ```rust use reqwest; #[tokio::main] async fn main() { let response = reqwest::Client::new() .post("https://api.mailgun.net/v5/sandbox/auth_recipients?email=your-email@example.com") .basic_auth("api", Some("YOUR_API_KEY")) .send() .await .unwrap(); println!("Status: {}", response.status()); } ``` Important Check the authorized recipients email inbox and click the verification link before proceeding to Step 2B. You must verify your email address to receive emails from this sandbox domain. ## Step 3: Send Your First Email Once you've clicked the verification link in your email, you can now send an email to that recipient. cURL ```bash curl --user 'api:YOUR_API_KEY' \ https://api.mailgun.net/v3/YOUR_SANDBOX_DOMAIN/messages \ -F from='Test ' \ -F to='your-email@example.com' \ -F subject='Hello!' \ -F text='Test message' ``` Node.js ```javascript const form = new FormData(); form.append('from', 'Test '); form.append('to', 'your-email@example.com'); form.append('subject', 'Hello!'); form.append('text', 'Test message'); fetch('https://api.mailgun.net/v3/YOUR_SANDBOX_DOMAIN/messages', { method: 'POST', headers: { 'Authorization': 'Basic ' + Buffer.from('api:YOUR_API_KEY').toString('base64') }, body: form }) .then(res => console.log('Status:', res.status)); ``` Python ```python import requests response = requests.post( "https://api.mailgun.net/v3/YOUR_SANDBOX_DOMAIN/messages", auth=("api", "YOUR_API_KEY"), data={ "from": "Test ", "to": "your-email@example.com", "subject": "Hello!", "text": "Test message" } ) print(f"Status: {response.status_code}") ``` Java ```java import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.util.Base64; public class Main { public static void main(String[] args) throws Exception { String auth = Base64.getEncoder().encodeToString("api:YOUR_API_KEY".getBytes()); String data = "from=Test " + "&to=your-email@example.com" + "&subject=Hello!" + "&text=Test message"; HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://api.mailgun.net/v3/YOUR_SANDBOX_DOMAIN/messages")) .header("Authorization", "Basic " + auth) .header("Content-Type", "application/x-www-form-urlencoded") .POST(HttpRequest.BodyPublishers.ofString(data)) .build(); HttpResponse response = HttpClient.newHttpClient() .send(request, HttpResponse.BodyHandlers.ofString()); System.out.println("Status: " + response.statusCode()); } } ``` C# ```csharp using System; using System.Collections.Generic; using System.Net.Http; using System.Text; var client = new HttpClient(); var auth = Convert.ToBase64String(Encoding.ASCII.GetBytes("api:YOUR_API_KEY")); client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", auth); var data = new FormUrlEncodedContent(new[] { new KeyValuePair("from", "Test "), new KeyValuePair("to", "your-email@example.com"), new KeyValuePair("subject", "Hello!"), new KeyValuePair("text", "Test message") }); var response = await client.PostAsync( "https://api.mailgun.net/v3/YOUR_SANDBOX_DOMAIN/messages", data); Console.WriteLine($"Status: {response.StatusCode}"); ``` PHP ```php 'Test ', 'to' => 'your-email@example.com', 'subject' => 'Hello!', 'text' => 'Test message' ])); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); echo "Status: $status\n"; curl_close($ch); ?> ``` Go ```go package main import ( "fmt" "net/http" "net/url" "strings" ) func main() { data := url.Values{ "from": {"Test "}, "to": {"your-email@example.com"}, "subject": {"Hello!"}, "text": {"Test message"}, } req, _ := http.NewRequest("POST", "https://api.mailgun.net/v3/YOUR_SANDBOX_DOMAIN/messages", strings.NewReader(data.Encode())) req.SetBasicAuth("api", "YOUR_API_KEY") req.Header.Set("Content-Type", "application/x-www-form-urlencoded") client := &http.Client{} resp, _ := client.Do(req) fmt.Println("Status:", resp.Status) } ``` Rust ```rust use reqwest; use std::collections::HashMap; #[tokio::main] async fn main() { let mut params = HashMap::new(); params.insert("from", "Test "); params.insert("to", "your-email@example.com"); params.insert("subject", "Hello!"); params.insert("text", "Test message"); let response = reqwest::Client::new() .post("https://api.mailgun.net/v3/YOUR_SANDBOX_DOMAIN/messages") .basic_auth("api", Some("YOUR_API_KEY")) .form(¶ms) .send() .await .unwrap(); println!("Status: {}", response.status()); } ``` You're response will look like 200 ok { "id": "[message-id@your-domain.com](mailto:message-id@your-domain.com)", "message": "Queued. Thank you." } ## Step 4: Check Your Inbox - **Check your inbox** - email should arrive in seconds - **Didn't get it?** Check spam folder or [view logs](https://app.mailgun.com/mg/reporting/logs) **🎉 That's it!** You just sent an email through Mailgun. ## Step 5: Get production ready Now that you've sent your first email, here's how to level up: Set up your own domain Move from sandbox to your custom domain.. Domain verification guide DNS setup and verification process. #### Send more email Send to multiple people Batch sending with personalization variables. Use HTML templates Create beautiful, branded emails. Track opens & clicks Monitor engagement with detailed analytics. #### Go beyond basic sending Set up webhooks Get real-time notifications for email events. Receive emails Parse and route incoming emails to your app. Manage mailing lists Build and maintain subscriber lists. Email validation Verify email addresses before sending. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/reporting/rate-definitions.md # Rate Definitions html table tr th Rate Label th API Variable Name th Calculation th Definition (Used in tooltip) tr td Bounced td bounce_rate td bounced_count / processed_count td Bounce rate measures the percentage of emails that bounce back, or the number of emails that couldn’t be delivered to users over the total number of emails sent. tr td Clicked td clicked_rate td clicked_count / delivered_count td The rate at which delivered emails are clicked. This calculation uses total clicks, not unique clicks. Use the unique click rate if percentages exceed 100%. tr td Complained td complained_rate td complained_count / delivered_count td Complaint rate measures the percentages of delivered emails reported as spam by recipients. This rate should be kept below 0.1%. Please note that Gmail does not provide complaints, to see Gmail complaint data, sign up for Google Postmaster Tools. tr td Delayed td delayed_rate td delivered_two_plus_attempts_count / delivered_count td The percentage of emails that were delivered with two or more delivery attempts. This rate does not include delayed emails that could not be delivered. tr td Delivered td delivered_rate td delivered_count / sent_count td The rate at which sent emails are delivered to recipient addresses. This calculation does not include suppressed emails. tr td Failed td permanent_fail_rate td permanent_failed_count / processed_count td The percentage of sent emails that resulted in a permanent failure. These emails could not be delivered and will not be retried. tr td Opened td opened_rate td opened_count / delivered_count td The rate at which delivered emails are opened. This calculation uses total opens, not unique opens. Use the unique open rate if percentages exceed 100%. tr td Unique clicked td unique_clicked_rate td unique_clicked_count / delivered_count td The percentage of delivered emails that resulted in a unique click event. This calculation will exceed 100% if your date filter excludes a large amount of delivery events. tr td Unique opened td unique_opened_rate td unique_opened_count / delivered_count td The percentage of delivered emails that resulted in a unique open event. This calculation will exceed 100% if your date filter excludes a large amount of delivery events. tr td Unsubscribed td unsubscribed_rate td unsubscribed_count / delivered_count td The unsubscribe rate accounts for the total number of unsubscribes divided by the total number of emails delivered and multiplied by 100, expressed as a percentage. --- # Source: https://documentation.mailgun.com/docs/mailgun/api-reference/razor.md # Razor Error Codes Razor is Mailgun's reputation system for detecting spammers and phishers as well as improving deliverability for legitimate customers. Razor uses a host of signals to algorithmically detect messages that either look like spam or have been marked as spam, and shut them down. If your account has been shutdown by Razor, the below table will explain why Razor has shut your account down and the steps you can take to reactivate your account. If you believe Razor has deactivated your account in error, please contact [Mailgun Support](https://app.mailgun.com/app/support) and reference the Razor error code you received to speed up account reactivation. Code | Reason rzr01 | Your domain has been disabled in order to protect your email reputation. Mailgun has detected content that is labeled as spam or a large amount of incorrect email addresses and/or spam complaints. These issues will cause poor deliverability of your emails and need to be resolved before we can enable your account.| rzr02 | No longer in use.| rzr03 | Suspicious activity has been detected on your account. Business verification is required.| rzr04 | Suspicious activity has been reported on your account. Business verification is required.| --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/api-key-mgmt/rbac-mgmt.md # API Management and Security Email API keys provide secure access to email services and data. They enable access to our APIs and allow integrating email functionalities into applications. At Mailgun, we prioritize security through granular access controls and role based authentication, ensuring that each API key has precisely the permissions it needs and nothing more. Proper management of these keys ensures smooth operation, protects against unauthorized access, and maintains the security of sensitive information. Mailgun provides two types of API keys for authenticating against the API: ## Account API Keys When you sign up for Mailgun, you can generate one or more API keys depending on your plan which allow you to perform all CRUD operations via our various API endpoints and for any of your sending domains. These keys have complete access to your account, so they should be stored securely and never shared publicly. With most plans, you can add additional API keys with a specific role via [Role Based Access Control (RBAC)](https://help.mailgun.com/hc/en-us/articles/4406099964059-Changing-an-account-user-s-role-and-permissions#h_01HWR65G3PE12TF4T1RJDT73YP). **To view and create your account API key(s):** 1. Navigate to the **Mailgun Dashboard** 2. Select **Account Settings** on the right side 3. On the **API keys** page click the "Create key" button and fill in the form fields in the modal as needed. 4. When ready, click the modal's "Create Key" button and record the generated key secret for safekeeping. Security Notice Your API key(s) provides full access to your Mailgun account. Store it securely using environment variables or a secrets management system. Never commit this key to version control or share it in public forums. ## Domain Sending Keys Domain Sending Keys are API keys that only allow sending messages via a POST call on /messages and /messages.mime endpoints for the specific domain in which they are created. These keys provide a secure way to enable sending functionality without exposing your full account access. This is ideal for production applications that only need to send email. **To create a sending API key:** 1. Navigate to the **Mailgun Dashboard** 2. Select the **Sending** tab on the left side of the Mailgun dashboard 3. Select the **Domains** tab and choose the domain for which you want to add a sending key 4. Navigate to the **Sending keys** tab 5. Click **Add Sending Key** Domain Sending Keys are recommended for production applications as they limit potential security exposure by restricting access to only the sending functionality. # Managing Role Based Access Control (RBAC) API Keys Role Based Access Control (RBAC) API Keys empower admin users to generate API keys using predefined roles that dictate the access level of each key. This feature allows you to implement the principle of least privilege, ensuring team members and applications have only the permissions they need. Availability Role Based Access Control is available on Enterprise and certain Business plans. See our [Pricing page](https://www.mailgun.com/pricing/) for more details about plan features. Important Limitations Assigned roles cannot be updated after creation. If you need to change a key's permissions, you must create a new key with the desired role and revoke the old one. Be sure to save the key in a secure location immediately upon creation, as you will only be able to view it once. ## Understanding Roles Each role is designed to align with common organizational functions and access requirements: - **Admin:** Full administrative access across all endpoints. Ideal for account owners and senior technical leadership who need complete control over the Mailgun account. - **Analyst:** Read only access to data and metrics. Perfect for data analysts, business intelligence teams, and stakeholders who need to review email performance without making changes. - **Developer:** Full access to technical endpoints needed for building and maintaining email integrations. Designed for engineering teams who implement and manage email functionality in applications. - **Support:** Read access to most endpoints with write access to specific management endpoints. Tailored for customer support teams who need to investigate issues and manage email deliverability without broader administrative privileges. ## API Permissions Framework During the API key creation process, you select a predefined role that assigns specific access levels to various public API endpoints. Understanding these permission types helps you choose the appropriate role for each use case. | Permission Type | Description | | --- | --- | | **No Access** | The API key cannot access these endpoints. Any attempt to call these endpoints will return an authentication error. | | **Read** | Allows the API key to access `GET` endpoints within the selected permission category. Ideal for monitoring, reporting, and auditing purposes. | | **Read/Write** | Allows the API key to access `GET`, `PATCH`, `PUT`, `DELETE`, and `POST` endpoints within the selected permission category. Provides full operational control within that category. | ## RBAC API Key Permissions by Role The table below details each role's specific permissions across all public API endpoints. Use this reference when determining which role best fits your security and operational requirements. | Endpoints | Admin | Analyst | Developer | Support | | --- | --- | --- | --- | --- | | Domains | Read/Write | Read | Read/Write | Read | | Messages | Read/Write | Read | Read/Write | Read | | Webhooks | Read/Write | Read | Read/Write | Read | | Logs | Read/Write | Read | Read/Write | Read | | Tags | Read/Write | Read | Read/Write | Read | | Metrics | Read/Write | Read | Read/Write | Read | | Unsubscribes (suppressions) | Read/Write | No Access | Read/Write | Read/Write | | Complaints (suppressions) | Read/Write | No Access | Read/Write | Read/Write | | Bounces (suppressions) | Read/Write | No Access | Read/Write | Read/Write | | Whitelist (suppressions) | Read/Write | Read | Read/Write | Read/Write | | Routes | Read/Write | Read | Read/Write | Read | | Mailing Lists | Read/Write | Read | Read/Write | Read/Write | | Templates | Read/Write | Read | Read/Write | Read/Write | | IPs | Read/Write | Read | Read/Write | Read | | IP Pools | Read/Write | Read | Read/Write | Read | | Sub-Accounts | Read/Write | Read | Read/Write | Read | | Validations | Read/Write | Read | Read/Write | Read | | Secure Tracking | Read/Write | Read | Read/Write | Read | | Custom Message Limit | Read/Write | Read | Read | Read | | Credentials | Read/Write | No Access | Read | No Access | | Keys | Read/Write | No Access | Read | No Access | | IP Allowlist | Read/Write | Read | Read/Write | Read | | Account Management | Read/Write | Read | Read/Write | Read | | Users on an account | Read | No Access | No Access | No Access | | Another user's details on an account | Read | No Access | No Access | No Access | | Own user details | Read | Read | Read | Read | ## Custom Message Limits The Custom Message Limit feature imposes a hard limit on how many messages your account can send during a calendar month. This is a protective measure that helps prevent unexpected overages and provides budget control for high volume senders. When message limits are enabled: - The primary account holder receives an email notification at 50% of the limit - A second notification is sent at 75% of the limit - After reaching 100% of the limit, the account will be temporarily disabled until the beginning of the following month You can re-enable your account before the next month begins by either adjusting the message limit via the dashboard or through the API, or by upgrading your plan. ## Sending Limits for Subaccounts Primary account admins, developers, and billing users can set individual message sending limits for each subaccount. This provides granular control over resource allocation across your organization or client base. To configure subaccount sending limits use the [Set a custom sending limit API endpoint](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/subaccounts/put-v5-accounts-subaccounts-subaccount_id-limit-custom-monthly) Subaccount limits are particularly useful for: - Agencies managing multiple client accounts - Organizations with multiple departments or business units - Platforms providing email services to end users # Best Practices for API Key Management ## Key Storage and Security **Never expose API keys in client side code.** API keys should only be used in server side applications where they cannot be accessed by end users. Store keys using: - Environment variables in production environments - Secrets management systems like AWS Secrets Manager, HashiCorp Vault, or Azure Key Vault - Encrypted configuration files with restricted access permissions **Implement key rotation policies.** Regularly rotate your API keys to minimize the risk of compromised credentials. We recommend rotating keys at least quarterly, or immediately if you suspect a key has been exposed. **Use the most restrictive role possible.** Always assign the minimum permissions required for each use case. If an application only needs to send email, use a Domain Sending Key rather than a primary account key. ## Monitoring and Auditing Monitor your API key usage regularly through the Mailgun dashboard. Watch for: - Unexpected spikes in API calls that might indicate compromised credentials - Failed authentication attempts - API calls from unfamiliar IP addresses or geographic regions ## Responding to Compromised Keys If you suspect an API key has been compromised: 1. Immediately revoke the compromised key in your Mailgun dashboard 2. Generate a new key with the appropriate role 3. Update all applications and services using the old key 4. Review your account activity logs for unauthorized usage 5. Consider implementing IP allowlisting for additional security ## IP Allowlisting For enhanced security, configure IP allowlisting to restrict API access to specific IP addresses or ranges. This adds an additional layer of protection by ensuring that even if a key is compromised, it cannot be used from unauthorized locations. # Related Resources - [Mailgun API Reference Documentation](https://documentation.mailgun.com/docs/mailgun/api-reference/api-overview) - [Email Best Practices Guide](https://www.mailgun.com/resources/) - [Mailgun Security Features](https://www.mailgun.com/security/) - [Contact Mailgun Support](https://www.mailgun.com/support/) --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/receive-forward-store/receive-forward-store.md # Introduction to Receiving, Forwarding and Storing Messages Mailgun will allow you to receive emails sent to your Mailgun Domain using the Routes feature, which will perform action that can include: - Forwarding emails to a different email address - Send the data to a configured webhook/URL (http POST to a URL) - Storing the email on Mailgun's servers temporarily to allow retrieval at a different time --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/receive-forward-store/receive-http.md ## Receiving Messages via HTTP through a forward() action When a URL is specified as a route destination through a forward() action, Mailgun will perform an HTTP POST request to the URL which contains a parsed version of the received email. The POST will be, either, `Content-Type: application/x-www-form-urlencoded` or `Content-Type: multipart/form-data`. We send `multipart/form-data` when the email has `attachments`. The base set of fields we send include: | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `signature` | string | A signed HMAC256 string (See [Securing Webhooks](https://documentation.mailgun.com/docs/mailgun/user-manual/events/webhooks#securing-webhooks)). | | `timestamp` | int | The number of seconds passed since January 1, 1970 (See [Securing Webhooks](https://documentation.mailgun.com/docs/mailgun/user-manual/events/webhooks#securing-webhooks)) | | `token` | string | A randomly generated string with a length of 50 (See [Securing Webhooks](https://documentation.mailgun.com/docs/mailgun/user-manual/events/webhooks#securing-webhooks)) | | `subject` | string | Received email Subject | | `sender` | string | The sender of the message as reported by MAIL FROM during SMTP chat. Note: this value *may differ* from From MIME header | | `from` | string | The sender of the message as reported by from message header, for example "Bob " | | `recipient` | string | The recipient of the message as reported by MAIL TO during SMTP chat | | `message-headers` | string | A list of MIME headers dumped to a JSON string (*order of headers is preserved*) | | `body-plain` | string | The text version of the email. This field is always present. If the incoming message only has HTML body, Mailgun will attempt to create a text representation for you. | | `body-html` | array | An array of all `text/html` MIME parts, if any, encoded as UTF-8 | ### Stripped Message Body Fields By default, Mailgun also attempts to provide a parsed version of each text body which, if successful, are present in the `stripped-*` fields. There are many reasons why this process may fail due to poorly-constructed HTML documents but we make our best effort. If this process *does* fail: these fields are not present in the payload: | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `stripped-text` | string | The text version of the message without quoted parts and signature block (if found) | | `stripped-signature` | string | The signature block stripped from the plain text message (if found) | | `stripped-html` | string | The HTML version of the message, without quoted parts. | Info *Consider using **http:/bin.mailgun.net** to debug and play with your routes. This tool allows you to forward incoming messages to a temporary URL and inspect the posted data. Info Not all web frameworks support multi-valued keys parameters, so the message-headers parameter was added. **Note**: The `message-headers` field can contain duplicate values for mandatory payload fields like `subject` vs. `Subject`. **Example:** Ruby on Rails requires a special syntax to post params like that: you need to add [] to a key to collect its values on the server side as an array. ### Attachments As mentioned above, if the received email contains attachments AND the forward URL does not end in `mime`, we instead POST with `Content-Type: multipart/form-data`. We add the following fields in addition to the ones listed above: | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `attachment-count` | int | The number of attachments the message has. | | `attachment-` | string | A unique field name for each attachment received, suffixed with an incrementing-integer, starting at 1 | | `content-id-map` | object | A JSON map which maps the `Content-ID` header to the correlated attachment name, if present in the MIME | ### Message Body Parsing If your forward URL ends in `mime` or `raw-mime`: we include a `body-mime` field with the **raw** MIME content and **omit the `body-plain` and `body-html` fields**. This allows you to have a raw copy of the MIME we received while still having the other base fields parsed out. The payload would come as `application/x-www-form-urlencoded` with the above base fields. Example: **http://myhost/post_mime** would receive the `body-mime` field *instead* of a `body-plain` or `body-html` field ### Response Codes for Retries For Route POSTs, Mailgun listens to response codes from your server and reacts accordingly: | **Received by Mailgun** | **Code description** | | --- | --- | | `200 (Success)` | A HTTP 200 marks the webhook POST is successful and will not be retried. | | `406 (Not Applicable)` | A HTTP 406 means the POST is rejected and it will not be retried. | | `Any other code` | Mailgun will retry POST attempts according to the schedule below for webhooks other than the delivery notification. | If a 406 error code is not returned and your application is unable to process the webhook request, Mailgun will attempt to retry (other than for delivery notification) in intervals for a total of 8 hours before stopping retries. The intervals are 10 minutes, 15 minutes, 30 minutes, 1 hour, 2 hours, and 4 hours. --- # Source: https://documentation.mailgun.com/docs/mailgun/faq/receiving.md # FAQ: Receiving ### Do you provide spam filtering for incoming mail? Yes. Click on your domain in the [Control Panel](https://app.mailgun.com/app/domains) and enable our spam filtering service. ### How do you handle quotations from replies and signatures when receiving mail? We parse them and provide parameters for you to handle them as you wish. Please take a look at our `user-manual`(https://documentation.mailgun.com/docs/mailgun/user-manual/get-started) or `api-reference`(https://documentation.mailgun.com/docs/mailgun/api-reference/intro) to see more details on the parameters we provide. ### Why am I not receiving an email when sending via the route with the sending address as a destination? You're most likely using GMail for sending your message. From GMail's documentation ([https://support.google.com/mail/troubleshooter/2935079?rd=1](https://support.google.com/mail/troubleshooter/2935079?rd=1)): Finally, if you're sending mail to a mailing list that you subscribe to, those messages will only appear in 'Sent Mail.' This behavior also occurs when sending to an email address that automatically forwards mail back to your Gmail address. To test forwarding addresses or mailing lists, use a different email address to send your message. When a message from, say, `bob@gmail.com` goes through a route: test@mailgun-domain.com -> bob@gmail.com When this message arrives to GMail, it will have `bob@gmail.com` as both sender and recipient, therefore GMail will not show it. In other words GMail does not show you messages you sent to yourself. The other possibility is that the address had previously experienced a Hard Bounce and is on the 'do not send' list. Check the `Suppressions` tab of your Control Panel for a list of these addresses and remove the address in question if it is there. ### How do I know if HTTP POST callbacks are coming from Mailgun, and not forged? Mailgun allows you to check the authenticity of its requests by providing three additional parameters in every HTTP POST request it makes. Please take a look at our [webhooks documentation](https://documentation.mailgun.com/docs/mailgun/user-manual/tracking-messages/#webhooks) for more information. ### How do I know if the sender of an email is spoofed? There is no 100% guarantee. However, there are some good clues. Mailgun provides DKIM and SPF verification for incoming mail, which is shown in the MIME headers once spam filtering is enabled in the [Control Panel](https://login.mailgun.com/login). This way you can at least know if the message is coming from an authenticated server. ### Can I use Mailgun for my personal email address? It's not recommended. Honestly, there are plenty of hosted email services better suited for this than Mailgun: Gmail, Google Apps, Outlook, etc. Mailgun is meant to be a tool for developers and their applications. --- # Source: https://documentation.mailgun.com/docs/mailgun/email-best-practices/recipient_eng.md # Recipient Engagement In addition to processing bounces, complaints and unsubscribes, MBPs (Mailbox Providers) measure your reputation through the engagement of your recipients. If recipients are opening, forwarding and replying to your emails, it will improve your reputation. This is what makes 'do-not-reply' emails so offensive. At many MBPs, it is also helpful if recipients add your email address to their address books. Mailgun allows you to track opens and link clicks with our Tracking and Tagging functionality (see our `user-manual`{.interpreted-text role="ref"} for more information). You are free to create up to 4,000 tags and use them simultaneously for A/B testing. In addition, Mailgun is built to receive and parse emails efficiently. So there is no excuse to not allow your recipients to reply to your emails. Email is not a billboard - it is a conversant technology. --- # Source: https://documentation.mailgun.com/docs/mailgun/release/release-notes.md # Release Notes Release notes refers to recent changes, feature enhancements, or bug fixes. You can find out what's new or check for the latest Mailgun updates by vising the [Release Notes page](https://www.mailgun.com/release-notes/). --- # Source: https://documentation.mailgun.com/docs/mailgun/email-best-practices/reputation.md # Reputation Reputation is one of the most important assets you have, even when sending email. If you do not have a good reputation tied to your domain and your IP address, your email will not reach your recipients' inboxes, as it may come across as spam. A good analogy for your email reputation is your personal credit score. Obviously, a bad reputation will hurt you. However, not having a reputation will also hurt you. If MBPs (Mailbox Provider) don't know you (or more specifically your IP and domain) they will assume the worst and filter you, at least initially. It's tough to blame them, given all the spam out there. Due to the importance of reputation, a significant portion of our discussion on best practices revolves around building and maintaining your email reputation. Because of email's popularity and unique ability to push information to users, it has been overrun with spammers. According to [MAAWG](http://www.maawg.org/sites/maawg/files/news/MAAWG_2010_Q3Q4_Metrics_Report_14.pdf), approximately 90% of all email is spam. Due to this overabundance of spam activity, mailbox providers ("MBPs") like Gmail, AOL, Yahoo and Outlook/Hotmail have declared an all-out war on spammers, making our inboxes a more pleasant place. This emphasizes the importance of managing your email reputation; If it is not impeccable, you will get caught in the MBPs' spam filters. Our goal with respect to your email reputation is to make sure that the infrastructure is optimized for emails reaching the inbox and doesn't get in your way. We test all of our IPs' reputation before we allocate them and we use the authentication methods that major MBPs require. Beyond making sure that the infrastructure is properly set up, we also provide the tools to answer some important questions: - Are emails being delivered and if not, why? - Is a recipient MBP throttling your traffic and why? - Are messages bouncing due to incorrect domains or stale addresses? - Are recipients unsubscribing or complaining of spam? - Are recipients engaging with your emails by opening them and/or clicking on links? You should use all of this data to make sure that you are complying with MBPs guidelines and adjust your email sending to stay in their good graces. Although We give you all the tools for establishing a good sending reputation, it's ultimately up to you to send emails appropriately. However, if you follow a couple rules (along with properly authenticating your email), you will most likely build up a great email sending reputation: - Only send emails to people that have signed-up to receive them from your website/application/service and always first send a confirmation link to confirm their address is correct (aka, "double opt-in") - Track your email and adjust your sending based on feedback from MBPs and recipients (eg., don't send additional emails to recipients that have unsubscribed or complained of spam). --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/tls-connection-settings/require-tls.md # Require tls TLS sending connection settings ensure your emails are securely transmitted by encrypting the connection between your email server and recipients, protecting your messages from interception during delivery. If set to *True*, messages can only be sent over a TLS connection. If the TLS connection cannot be established, Mailgun will not deliver the message. If set to *False*, Mailgun will try to upgrade the connection. If Mailgun cannot upgrade the connection, the message will be delivered over a plaintext SMTP connection. The default is False. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/receive-forward-store/route-actions.md # Route Actions If a route expression is evaluated to *true,* Mailgun executes the corresponding action. Currently you can use the following three actions in your routes: forward(), store() and stop(). ### Forward(destination) Forwards the message to a specified destination, which can be another email address or a URL. A few examples: ```JSON forward("mailbox@myapp.com") forward("http://myapp.com/messages") ``` You can combine multiple destinations by separating them with a comma. ```JSON forward("http://myapp.com/messages, mailbox@myapp.com") ``` Info When forwarding messages to another email address, you should disable click tracking, and open tracking and unsubscribes, by editing your domain settings in the Control Panel. If these features are enabled, the content of each message is modified by Mailgun before forwarding, which invalidates the DKIM signature. If the message comes from a domain publishing a DMARC policy (like Yahoo! Mail), the message will be rejected as spam by the forwarding destination. ### Store(notification endpoint) This temporarily stores the message (for up to 3 days) on Mailgun's servers so that you can retrieve it later. This is helpful for large attachments that may cause time-outs, or if you want to retrieve them later to reduce the frequency of hits on your server. When you specify a URL, Mailgun will notify you when the email arrives along with a URL which you can use to retrieve the message: ```JSON store(notify="http://mydomain.com/callback") ``` If you don't specify a URL with the notify parameter, the message will still be stored and you can get the message later through the [Messages API](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/messages/post-v3--domain-name--messages). You can see a full list of parameters we will post/return to you below. ### Stop() Without a stop() action executed, all lower priority Routes will also be evaluated. This simply stops the priority waterfall so the subsequent routes won't be evaluated. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/receive-forward-store/route-filters.md # Route Filters Route filters are expressions that decide when an action is triggered. A filter is created based on the recipient of the incoming email, the headers in the incoming email or use a catch-all filter. Filters support regular expressions in the pattern to give you a lot of flexibility when creating them. ### Match Recipient(pattern) Matches the SMTP recipient of the incoming message against the regular expression pattern. For example, this filter will match messages going to foo@bar.com: ```JSON match_recipient("foo@bar.com") ``` You can use Python-style regular expressions in your filter. For example, this will match all messages coming to any recipient at @bar.com: ```JSON match_recipient(".*@bar.com") ``` Another example, handling plus addressing for a specific recipient: ```JSON match_recipient("^chris\+(.*)@example.com$") ``` Mailgun supports regexp captures in filters, which allows you to use captured values inside of your actions. The example below captures the local name (the part of email before @) and passes it as a mailbox parameter to an application URL: ```JSON route filter : match_recipient("(.*)@bar.com") route action : forward("http://myhost.com/post/?mailbox=\1") ``` You can use named captures as well: ```JSON route filter : match_recipient("(?P.*?)@(?P.*)") route action : forward("http://mycallback.com/domains/\g/users/\g") ``` ### Match Header(header,pattern) This is similar to match-recipient, only instead of looking at a message recipient, it applies the pattern to an arbitrary MIME header for the message. The example below matches any message with a word "support" in its subject: ```JSON match_header("subject", ".*support") ``` The example below matches any message against several keywords: ```JSON match_header('subject', '(.*)(urgent|help|asap)(.*)') ``` The example below will match any messages deemed spam (if spam filtering is enabled): ```JSON match_header('X-Mailgun-Sflag', 'Yes') ``` ### match_recipient(pattern) AND match_header(header, pattern) The example below will match any recipient for a domain, then match if the message is in English: ```JSON match_recipient('^(.*)@example.com$') and match_header("Content-Language", "^(.*)en-US(.*)$") ``` ### catch_all() Will create matches if no proceeding routes matched. Usually, you need to use it in a route with a lowest priority, to make sure it evaluates last. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/receive-forward-store/routes.md # Routes You can define a list of routes to handle incoming emails. This idea of routes is borrowed from MVC web frameworks like Django or Ruby on Rails. If a message matches a route expression, Mailgun can perform an action, such as forward the email, or store the email. You can define routes visually by clicking the **Receiving** tab in the Control Panel, or programmatically using the [Routes API](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/routes). For more on setting up Routes, see How Do I Setup a Route?. A Route is a pair of **filter + action**. Each incoming message is passed to a filter expression, and if it evaluates to true, the action is executed. Each Route can be assigned a priority, and are evaluated in the order of priority, with lower numbers having a higher priority. By default, all Routes are evaluated (even if a higher priority Route is triggered). To avoid this action, you can use a stop() action (see below). **Route Properties** | **Route** | **Description** | | --- | --- | | `Priority` | Integer showing the priority of route execution. Lower numbers have higher priority. | | `Filter` | Filters available in routes - match_recipient() match_header() catchall() (see Route Filters for description). | | `Actions` | Type of action to take when a filter is triggered - forward() store() stop() (see below for description). | | `Description` | Arbitrary string to describe the route (shown in the Control Panel UI) | Info The length of the **Filter** or **Action** fields cannot exceed 4k. If you need more actions or filters than is allowed under the 4k limit, you can add additional routes. Multiple routes with the same Filter expression are allowed. This will allow you to add many more Actions for the same Filter but spread across multiple route entries. --- # Source: https://documentation.mailgun.com/docs/mailgun/sdk/ruby_sdk.md # Ruby a img Official Mailgun Ruby Gem On Github This is the Mailgun Ruby Library. This library contains methods for easily interacting with the Mailgun API. Below are examples to get you started. For additional examples, please see our repository on GitHub. Happy Coding! Installation Via RubyGems ```ruby gem install mailgun-ruby ``` Gemfile: ```ruby gem 'mailgun-ruby', '~>1.2.14' ``` Usage Here's a simple example on how to send an email. As always, please consult the repository readme for full details. ```ruby require 'mailgun-ruby' # First, instantiate the Mailgun Client with your API key mg_client = Mailgun::Client.new 'MAILGUN_API_KEY' # Define your message parameters message_params = { from: 'bob@sending_domain.com', to: 'sally@example.com', subject: 'The Ruby SDK is awesome!', text: 'It is really easy to send a message!' } # Send your message through the client mg_client.send_message 'sending_domain.com', message_params ``` --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/sending-messages/schedule-delivery.md # Scheduling Delivery Mailgun allows you to request a specific time for delivering messages. Use `o:deliverytime` parameter if sending via the API. Use the MIME header `X-Mailgun-Deliver-By` when sending via SMTP. Info If your billing plan supports 7 or more days of storage capability, you can now schedule emails out up to 7 days. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/sending-messages/send-amp.md # Sending an AMP Message Google's Accelerated Mobile Pages (AMP) for email is a web component framework that you can use to easily create user-first websites, stories, emails, and ads. The AMP email format provides a subset of AMPHTML components for use in email messages, that allows recipients of AMP emails to interact dynamically with content directly in the message. Mailgun allows senders to include AMP components within their email message(s) using the `amp-html` parameter. This allows recipients to interact within the email message. Some examples include: - Answering surveys - Replying to documents - Viewing inventory in real-time - Submitting updates ### AMP Requirements While AMP is a really exciting email tool, it takes a bit of setup before you can successfully send an AMP email message to your recipients. #### Registration Here's what you'll need to know to register: - In order to send AMP emails to mailboxes that support it (Gmail for now), you’ll need to register your sending domain with Google.[Click here](https://support.google.com/mail/answer/81126) to register. #### Content - Your AMP email content must comply with Google's requirements. Be sure to look at Google's [Bulk Senders Guidelines](https://support.google.com/mail/answer/81126) before composing your email. - AMP messages must follow the [AMP for Email Specifications](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format). Specifically, the required markup, AMP components, and CSS requirements. - To ensure your content will pass the validation process, use Gmail's [AMP for Email Playground](https://amp.gmail.dev/playground/) Note: If you follow the AMP requirements set by Google, you should be well on your way to sending AMP messages. #### HTTPS URLs All URLs must use HTTPS, including tracking and unsubscribe URLs. If you're using Mailgun for your open/click tracking and unsubscribe UR:s, you'll need to [Follow these steps](https://help.mailgun.com/hc/en-us/articles/360011566033-How-to-Enable-HTTPS-Tracking-Links) to enable HTTPS on your Mailgun tracking URLs. ### Sending AMP emails Mailgun has made it easy to send an AMP email using our API by providing the optional `amp-html` parameter along with your AMP content. Mailgun will take care of building the proper `text/x-amp-html` MIME portion. As long as you’re following the AMP requirements set by Google, you should be well on your way to sending your AMP messages. ### Testing your AMP email messages Note: You can build and test your AMP email messages even while you're waiting for Google to register your domain. ### AMP Best Practices 1. Visit your Gmail settings page (*GSuite users will need their admins to enable the Dynamic Email Option*) 2. Click the **Dynamic Email** section, check the box to **Enable Dynamic Email**. 3. Click **Developer Settings** 4. Enter your sending address in the field – This will whitelist your sending address. 5. Click **OK** Following the proper requirements and these steps for sending AMP messages will allow you to be able to receive an AMP email from your sending address to your Gmail account. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/sending-messages/send-http.md # Send via HTTP When sending an email via HTTP on our platform, Mailgun offers two options: - You can [submit the individual parts](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/messages/post-v3--domain-name--messages) (text, HTML, attachments, etc.) of your messages - You can [send a pre-built MIME](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/messages/post-v3--domain-name--messages-mime). This assumes you've built an RFC-compliant MIME in your choice of tooling Some things to consider when sending emails: - If your domain exists in our EU region, be sure to substitute “https://api.mailgun.net” with “https://api.eu.mailgun.net” - The maximum message size Mailgun supports is 25MB - An error will be returned with `"parameter is not a valid address"` if the provided email address fails syntax checks in accordance with RFC5321, RFC5322, RFC6854 - Mailgun *does* support receiving GZIP-compressed HTTP bodies if the `Content-Encoding: gzip` header is present - Bodies must be gzip-compressed as defined by [RFC1952](https://www.rfc-editor.org/rfc/rfc1952.html) - Compressing message bodies does *not* bypass the above limit. This limit is enforced on the *uncompressed* body - Mailgun does have rate limits in place to protect our system. In the unlikely case you encounter them and need them raised, please reach out to our support team. We understand email is complicated, and have provided many options to tailor your request to your personal needs. Please see all our [sending options](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/messages/post-v3--domain-name--messages) here! **Here are a few examples to get you familiar with interacting with the API (using cURL)** ### Sending Basic Text Sending a simple text-based email using Mailgun's HTTP API requires a few parameters at minimum: ```bash curl -s --user 'api:YOUR_API_KEY' \ https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \ -F from='Excited User ' \ -F to=recipient-1@example.com \ -F to=recipient-2@example.com \ -F subject='Hello there!' \ -F text='Testing some Mailgun awesomeness!' ``` What actually happened: - Mailgun assembled a valid MIME message based on your input parameters - Delivered the email to both recipients listed with the `to` parameters - Added log entries to our full text index that we Accepted the email, and if delivered successfully, added a Delivered event. (See the Events API for more details) ### Send With Text and HTML Versions By including both the 'text' and 'html' parameters, you can offer two different versions of your email to the user: ```bash curl -s --user 'api:YOUR_API_KEY' \ https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \ -F from='Excited User ' \ -F to=recipient@example.com \ -F subject="Hello there!" \ -F text='This will be the text-only version' \ --form-string html='

This is the HTML version

' ``` info A common gotcha: note the use of `--form-string` in this example for the HTML part. Without this, your cURL command may fail to execute properly! ### Send a Single Message With Tracking While tracking can be enabled for all messages in your Dashboard, you can also selectively enable tracking on a per-message basis. To enable all tracking types you use the 'o:tracking="yes"' parameter. Otherwise, you can enable only specific tracking for opens ('o:tracking-opens') or clicks ('o:tracking-clicks'): ```bash curl -s --user 'api:YOUR_API_KEY' \ https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \ -F from='Excited User ' \ -F to=recipient@example.com \ -F subject="Hello there!" \ -F text='Testing some Mailgun awesomeness!' \ -F o:tracking-opens="yes" ``` ### Send a Message using a Template with variable substitution Not all templates use variables, but assuming it has variable called "name", here are two ways of going about the substitution. The first is recommended since it will hide the variables from the MIME and not show in events. ```bash curl -s --user 'api:YOUR_API_KEY' \ https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \ -F from="Excited User " \ -F to="recipient@example.com" \ -F subject="Mailgun is awesome" \ -F template="My Great Template Name" \ -F t:variables="{\"name\":\"Foo Bar\"}" ``` Or, the old way, which will include the variables in the MIME under `X-Mailgun-Variables` and they will appear in the events / webhooks under `user-variables` ```bash curl -s --user 'api:YOUR_API_KEY' \ https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \ -F from="Excited User " \ -F to="recipient@example.com" \ -F subject="Mailgun is awesome" \ -F template="My Great Template Name" \ -F v:name="Foo Bar" ``` ### Send a Customized Batch Message Batch messages are a great way to send emails to multiple people, while still being able to customize the content for each recipient. ```bash curl -s --user 'api:YOUR_API_KEY' \ https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \ -F from="Excited User " \ -F to="recipient@example.com, recipient-two@example.com" \ -F subject="Mailgun is awesome" \ -F text="Hello %recipient.fname% %recipient.lname%! Enjoy a free %recipient.gift%" \ -F recipient-variables="{\"recipient@example.com\": {\"fname\":\"Bob\", \"lname\":\"Mailgun\", \"gift\":\"high five\"}, \"recipient-two@example.com\": {\"fname\":\"Foo\", \"lname\":\"Bar\", \"gift\":\"fist bump\"}}" ``` ### Send a Message With Specified Delivery Time The 'o:deliverytime' option allows you to specify when an email should be sent. It uses RFC822 date formatting and can be no more than 3 days in the future: ```bash curl -s --user 'api:YOUR_API_KEY' \ https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \ -F from='Excited User ' \ -F to=recipient@example.com \ -F subject="Hello there!" \ -F text='Testing some Mailgun awesomeness!' \ -F o:deliverytime='Fri, 14 Oct 2011 23:10:10 -0000' ``` Info If your billing plan supports 7 or more days of storage capability, you can schedule emails out up to 7 days. ### Send a Message using Tags Mailgun allows you to Tag emails for further analytics within our platform: ```bash curl -s --user 'api:YOUR_API_KEY' \ https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \ -F from='Excited User ' \ -F to=recipient@example.com \ -F subject="Hello there!" \ -F text='Testing some Mailgun awesomeness!' \ -F o:tag='September newsletter' \ -F o:tag='newsletters' ``` See [Tags](https://documentation.mailgun.com/docs/mailgun/user-manual/tracking-messages/track-tagging) for more information! ### Re-Delivering a Previously-Sent Email By default: emails sent through our APIs are stored for 72 hours. If you navigate to your Dashboard, check the Logs page and find a message sent within this time frame that you wish to resend, you should have a 'storage.url' field. Using that exact URL in your POST request, along with one or more 'to' parameters, you can deliver that MIME to the provided recipients: ```bash curl -s --user 'api:YOUR_API_KEY' {{STORAGE.URL}} \ -F to='bob@example.com, john@example.com' ``` --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/sending-messages/send-smtp.md ## Send via SMTP First you'll need to grab your SMTP credentials (user and password). SMTP credentials are set and managed on a per-domain basis. You can view and modify them via our HTTP API or UI. To access them in our UI, navigate on the sidebar to `Sending` -> `Domain Settings`, select your domain from the dropdown, then select the `SMTP Credentials` tab. Go to the article Can I Customize My SMTP Credentials? for more information. To send an email via SMTP you can utilize Swaks via your command line. ```bash # Swaks is the cURL equivalent for SMTP, install it first: curl http://www.jetmore.org/john/code/swaks/files/swaks-20130209.0/swaks -o swaks # Set the permissions for the script so you can run it chmod +x swaks # It's based on perl, so install perl sudo apt-get -y install perl # now send! ./swaks --auth \ --server smtp.mailgun.org \ --au YOUR-SMTP-USER \ --ap YOUR-SMTP-PASSWORD \ --to recipient@example.com \ --h-Subject: "Hello" \ --body 'Testing some Mailgun awesomness!' ``` Mailgun SMTP servers listen on ports `25`, `465`, `587`, and `2525`. Port 465 requires a TLS connection. Ports `25`, `587`, and `2525` require a non-TLS connection but may be upgraded to TLS using the STARTTLS command. We offer many different ports due to some ISPs blocking / throttling certain SMTP ports. Learn more about ports by reading our article, Which SMTP Port Should I Use? Undertsanding Ports 25, 465,& 587. | **Port** | **Requirements** | | --- | --- | | `25` | Requires a non-TLS connection but may be upgraded to TLS using the STARTTLS command. | | `465` | Requires a TLS connection | | `587` | Requires a non-TLS connection but may be upgraded to TLS using the STARTTLS command. | | `2525` | Requires a non-TLS connection but may be upgraded to TLS using the STARTTLS command. | Info * Some ISPs are blocking or throttling SMTP port 25. Using port 587 is recommended. * Google Compute Engine allows port 2525 for SMTP submission. * SMTP send will error with "Cannot parse to address" or "cannot parse from address" if the provided email address fails syntax checks in accordance with RFC5321, RFC5322, RFC6854 Warning! IP addresses for HTTP and SMTP API endpoints will change frequently and be subjected to change without notice. Be sure there are no IP-based ACLs that would prevent communication to new IP addresses that may be added or removed at any time. ## Passing Sending Options | SMTP Header | Description | | --- | --- | | `X-Mailgun-Tag` | The Tag string is used for aggregating stats. You can make a message with several categories by setting multiple X-Mailgun-Tag headers. | | `X-Mailgun-Dkim` | Enables/disables DKIM signatures on a per-message basis. Use `yes` or `no` | | `X-Mailgun-Drop-Message` | Enables sending in test mode. Note: Sending in Test Mode will not actually deliver an email but will emit a `delivered` event with a 650 status code `Pass`, `yes`, or `no` if needed. | | `X-Mailgun-Track` | Toggles tracking on a per-message basis. `Pass`, `yes` or `no`. | | `X-Mailgun-Track-Clicks` | Toggles clicks tracking on a per-message basis. It has a higher priority than the domain-level setting. Pass, yes, no | | `X-Mailgun-Track-Opens` | Toggles opens tracking on a per-message basis. It has a higher priority than the domain-level setting. Pass, yes or no | | `X-Mailgun-Sending-Ip` | Used to specify an IP Address to send an email that is owned by your account | | `X-Mailgun-Sending-Ip-Pool` | If an IP Pool ID is provided, the email will be delivered with an IP that belongs in that pool | | `X-Mailgun-Require-TLS` | Use this header to control TLS connection settings. If set, Mailgun will only deliver the message over a secure TLS connection with the ESP. If TLS is not available, the delivery will fail. | | `X-Mailgun-Skip-Verification` | Use this header to control TLS (Transport Layer Security) connection settings. | | `X-Mailgun-Secondary-DKIM` | Specify a second domain key to sign the email with. The value is formatted as `signing_domain,selector`, e.g. `example.com,s1`. This tells Mailgun to also sign the message with the signing domain `example.com` using the selector `s1`. Note: the domain key specified must have been created and activated. | | `X-Mailgun-Secondary-DKIM-Public` | This header specifies an alias of the domain key specified in `X-Mailgun-Secondary-DKIM`. Also formatted as public_signing_domain/selector. The X-Mailgun-Secondary-DKIM header must also be provided if this header is used. Mailgun will sign the message with the provided key of the secondary DKIM, but use the public secondary DKIM name and selector. Note: We will perform a DNS check prior to singing the message to ensure the public keye matches the secondary DKIM | | `X-Mailgun-Deliver-By` | Specifies the scheduled delivery time in [RFC-2822 format](https://documentation.mailgun.com/docs/mailgun/api-reference/api-overview#date-format). Depending on your billing plan, you can schedule messages up to 3 or 7 days in advance. If your domain has a custom message_ttl (time-to-live) setting, this value determines the maximum scheduling duration. Example: 'Fri, 14 Oct 2011 12:00:00 0000' | | `X-Mailgun-Deliver-Within` | Specifies the maximum time window for delivering the message. Accepts values in format `[0-9]h[0-9]m` (e.g., `1h30m`, `30m`, `24h`), with a minimum of `5m` and maximum of `24h`. For scheduled messages, the delivery window starts from the scheduled time. The standard retry schedule applies within this window, so shorter timeframes may result in fewer delivery attempts. | | `X-Mailgun-Delivery-Time-Optimize-Period` | Toggles STO on a per-message basis. The string should be set to the number of hours in `[0-9]+h` format. | | `X-Mailgun-Time-Zone-Localize` | Toggles TZO on a per-message basis. The string should be set to the preferred delivery time in `HH:mm` or `hh:mmaa` format, where `HH:mm` is used for a 24-hour format without AM/PM, and `hh:mmaa` is used for 12-hour format with AM/PM. | | `X-Mailgun-Recipient-Variables` | Use this header to provide a JSON dictionary of variables to substitute for Batch messages. | | `X-Mailgun-Template-Name` | Name for the template to be rendered as the message body. | | `X-Mailgun-Template-Version` | Optional: Version of the template to be used, if different from the current active template. | | `X-Mailgun-Variables` | If sending with a Template, the provided data will be treated as the values to substitute with the templates variables. Note that `X-Mailgun-Template-Variables/t:variables` will override these if also provided. If a template is not used, the provided data will be treated as metadata and appended to the user-variabled field in events / webhooks. NOTE: These variables are visible in the email MIME! | | `X-Mailgun-Template-Variables` | A valid JSON-encoded dictionary used as the input for template variable expansion. See Templates docs for more information. Note: These variables will be preferred over X-Mailgun-Variables, e.g. user variables. | | `X-Mailgun-Track-Pixel-Location-Top` | If you send long emails that experience truncation or other rendering issues at the recipient, you can ensure opens are being tracked accurately with placement of the tracking pixel at the top of your emails. | | `X-Mailgun-Archive-To` | Sends a copy of successfully delivered messages to the specified URL via HTTP POST. The request uses Content-Type: application/mime and contains the exact message the recipient's SMTP server received. **NOTE: These are accounted for and billed as delivered messages** | | `X-Mailgun-Suppress-Headers` | Removes the specified `X-Mailgun` header or all `X-Mailgun` headers if `all` is specified as the header value. Can be specified multiple times. | ## SMTP Credentials Mailgun gives you the ability to programmatically manage SMTP credentials which can be used to send mail. Please see the [API documentation](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/credentials) for the complete API reference. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/sending-messages/send-sto.md # Sending a Message with STO Mailgun's **Send Time Optimization** (STO) feature uses machine learning to analyze engagement data (opens and clicks) for a recipient to determine when a user is most engaged with their messages. If there is enough engagement data to determine when the user is most engaged, Mailgun will hold onto the message and deliver it during that optimal period. The idea is to deliver the message to the recipient at a time when they are most likely to be engaged with their messages. ### Sending an STO message via API and SMTP - Send a message via API by passing the parameter: ***o:deliverytime-optimize-period*** - Send an SMTP message using the MIME header: **X-Mailgun-Delivery-Time-Optimize-Period** - The value should be a string in the [0-9]+h format. This format defines the window in which Mailgun will run optimization algorithm against the data that has been delivered to the message. - Using a minimum value of 24h for best results, and the max value is 72h is highly recommended. For more information on STO, see the article, What is Send Time Optimization?. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/sending-messages/send-templates.md # Templates Mailgun allows you to store predefined email templates and use them to send messages by simply referencing the template name. Each domain supports up to 100 templates, with each template allowing up to 40 versions. For comprehensive information about templates, refer to the [Template API documentation](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/templates). To learn about creating templates using the Template Builder interface, see [Email Templates](https://help.mailgun.com/hc/en-us/articles/360021380793-Email-Templates). ## Creating and Using Templates You can create templates either through the Template API or using the Template Builder in the Mailgun UI. ### Creating a Template via API ```bash curl -X POST -s --user 'api:YOUR_API_KEY' \ https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/templates \ --form-string template='

{{title}}

{{body}}
' \ -F name='template.test' \ -F description='Sample template' ``` The response returns stored template information: ```json { "template": { "createdAt": "Wed, 29 Aug 2018 23:31:13 UTC", "description": "Sample template", "name": "template.test" }, "message": "template has been stored" } ``` ### Sending Messages with Templates Once your template is created, you can send messages using it: ```bash curl -s --user 'api:YOUR_API_KEY' \ https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \ -F from='Excited User ' \ -F to=recipient@example.com \ -F subject='Hello there!' \ -F template="template.test" \ -F t:variables='{"title": "API documentation", "body": "Sending messages with templates"}' ``` When sending MIME messages, pass template variables using the `X-Mailgun-Template-Variables` header instead of the `t:variables` parameter. ## Handlebars Template Engine Mailgun templates use a customized version of Handlebars, a popular templating engine. To provide dynamic values for substitution, use the `t:variables` parameter or the `X-Mailgun-Template-Variables` header. Mailgun supports the following Handlebars block helpers: `if`, `unless`, `each`, `with`, and `equal`. ### The `if` Block Helper Use the `if` helper to conditionally render content based on variable values. **Example: Dynamic language selection** ```html {{#if english}}

This text is in the English language.

{{else if spanish}}

Este texto está en idioma español.

{{else if french}}

Ce texte est en langue française.

{{/if}} ``` Pass this data via `t:variables`: ```json {"spanish": true} ``` This renders the Spanish version of the text. ### The `unless` Block Helper The `unless` helper renders a block only when the condition is false. **Example: Payment reminder** ```html {{#unless paid}}

WARNING: Your account is past due and will be suspended shortly. Please contact our billing department for assistance

{{/unless}} ``` Pass this data via `t:variables`: ```json {"paid": false} ``` This displays the warning when the account is unpaid. ### The `each` Block Helper The `each` helper allows you to iterate over arrays or lists. **Example: Listing scheduled services** ```html {{#each user.services}}
  • You scheduled {{this.service}} on {{this.date}}
  • {{/each}} ``` Pass this data via `t:variables`: ```json { "user": { "services": [ { "date": "07/30/2019", "service": "deliverability consultation" }, { "date": "08/05/2019", "service": "sales consultation" } ] } } ``` This renders as: * You scheduled deliverability consultation on 07/30/2019 * You scheduled sales consultation on 08/05/2019 ### The `with` Block Helper The `with` helper shifts the context for a section of your template, making it easier to access nested properties without repeating the parent object name. **Example: Simplifying nested author information** ```html

    {{title}}

    {{#with author}}

    By {{firstName}} {{lastName}}

    Email: {{email}}

    {{/with}}
    ``` Pass this data via `t:variables`: ```json { "title": "My first post!", "author": { "firstName": "Jean", "lastName": "Valjean", "email": "jean@example.com" } } ``` This renders as: ```html

    My first post!

    By Jean Valjean

    Email: jean@example.com

    ``` ### The `equal` Block Helper The `equal` helper renders content when a variable exactly matches a specific value. This is useful for displaying different content based on user attributes like subscription tier, account status, or preferences. **Example: Customizing content by subscription tier** ```html {{#equal subscription "free"}}

    Upgrade to Pro to unlock advanced features!

    Upgrade Now {{/equal}} {{#equal subscription "pro"}}

    Thanks for being a Pro member! Enjoy your premium features.

    {{/equal}} {{#equal subscription "enterprise"}}

    Welcome back! Your dedicated account manager is here to help.

    {{/equal}} ``` Pass this data via `t:variables`: ```json {"subscription": "pro"} ``` This displays the Pro member message. **Note:** The `equal` helper converts both values to strings before comparing, so `{"count": 5}` and `{"count": "5"}` are treated as equal. ## Complete Example: Using All Handlebars Helpers The following example demonstrates all supported Handlebars helpers working together in a single template. This comprehensive template shows how you can combine `with`, `equal`, `unless`, `if`, and `each` to create dynamic, personalized email content. ### Create the Template ```bash curl -X POST -s --user 'api:YOUR_API_KEY' \ https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/templates \ -F name='comprehensive.test' \ -F description='Complete test template with all Handlebars helpers' \ --form-string template='

    Order Confirmation

    {{#with customer}}

    Hello {{firstName}} {{lastName}},

    Email: {{email}}

    {{/with}} {{#equal accountType "premium"}}

    🎉 Premium Member Perk: You have earned 2x points on this order!

    {{/equal}} {{#equal accountType "basic"}}

    Upgrade to Premium for exclusive benefits and rewards!

    {{/equal}} {{#unless paymentReceived}}

    ⚠️ WARNING: Payment pending. Your order will ship once payment is confirmed.

    {{/unless}} {{#if paymentReceived}}

    ✓ Payment confirmed! Your order is being processed.

    {{/if}}

    Order Items:

      {{#each items}}
    • {{this.name}} - Quantity: {{this.quantity}} - ${{this.price}}
    • {{/each}}
    {{#if spanish}}

    Gracias por su compra!

    {{else if french}}

    Merci pour votre achat!

    {{else}}

    Thank you for your purchase!

    {{/if}} ' ``` ### Send a Message Using the Template ```bash curl -s --user 'api:YOUR_API_KEY' \ https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \ -F from='Order System ' \ -F to='recipient@example.com' \ -F subject='Your Order Confirmation #12345' \ -F template="comprehensive.test" \ -F t:variables='{ "customer": { "firstName": "Maria", "lastName": "Garcia", "email": "maria@example.com" }, "accountType": "premium", "paymentReceived": true, "items": [ { "name": "Wireless Headphones", "quantity": 1, "price": "79.99" }, { "name": "Phone Case", "quantity": 2, "price": "24.99" }, { "name": "USB Cable", "quantity": 3, "price": "12.99" } ], "spanish": false, "french": false }' ``` ### Testing Different Scenarios You can modify the JSON data to test different template behaviors: * Change `accountType` to "basic" to see the upgrade message instead of the premium perk * Set `paymentReceived` to false to display the payment warning * Change `spanish` to true to see the Spanish thank you message * Modify the `items` array to add or remove products from the order list * Update customer information within the `customer` object to test the `with` helper --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/sending-messages/send-tzo.md ## Sending a Message with TZO Time Zone Optimization (TZO) allows senders to schedule messages to be delivered in a recipient's local time zone. TZO is like message scheduling, however, the focus is on passing the message on to the desired delivery time based on the recipient's local time zone. Mailgun will convert the message to use the recipient's local time zone, when there is data present for the recipient. If Mailgun does not have data for that recipient, the message will be delivered immediately. - Time zones are based on a recipient's IP address - Mailgun collects IP addresses on click events and uses a geo-location service to translate the IP address into a time zone for the user. - The time zone is hashed and stored in a database, which Mailgun will look up for that user when a TZO message is sent. ### Sending TZO message via API and SMTP - Send a message via API by passing the parameter: **o:time-zone-localize** - Send a message via SMTP using a MIME header: **X-Mailgun-Time-Zone-Localize** - The value (String) should be set to the preferred delivery time in HH:mm or hh:mmaa format, where HH:mm is used for 24 hours format without AM/PM and hh:mmaa is used for 12-hour format with AM/PM. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/sending-messages/sending-messages.md # Sending Messages Info Since Mailgun does not host mailboxes, our service does not use the POP or IMAP protocols. ## How to Start Sending Messages There are two ways to send messages using Mailgun that work great to support the same feature set. - HTTP API - SMTP Choose the one you'd like to use based on your preferences and requirements. ![verifydomain](/assets/mailgunsend2.352e35d133ccd52bf31f17d2a3f9eeee8f9a7a55619e095bde60db488e0c3ead.05e97c23.png) --- # Source: https://documentation.mailgun.com/docs/mailgun/faq/sending.md # FAQ: Sending ### Should I use SMTP or the HTTP API? It's really up to you. Whatever you find easier is fine with us. The HTTP API has some advantages, however. First of all, it's faster. Second, we think it's easier to use - you don't have to deal with MIME because we will assemble it on our side. Just use a request library available for your language of choice. ### Email clients say "sent via mailgun.us" with messages I send. How do I get rid of this? Check the following: - You have a custom domain defined in the `Domains` tab of the Control Panel. - You've setup the DKIM DNS record (provided in the Control Panel, `Domains` tab). - You're authenticating (SMTP) or posting (API) against the custom domain. If you're still seeing "via mailgun.org", please [contact our Support Team](https://app.mailgun.com/app/support) and we'll investigate. ### What is the difference between the "From" and "Sender" Each message you send out has both the sender and from address. Simply put, the sender domain is what the receiving email server sees when initiating the session, and the from address is what your recipients will see. For better deliverability it is recommended to use the same from domain as the sender, but it is not required. You can technically set the from field to be whatever you like. The sender must always be one of your Mailgun domains. ### Where do I specify BCC recipients? BCC functionality works like this: specify a BCC recipient in the recipients list when sending, but do not include their address in the "To" or "CC" fields. You could also use the API, which has a specific BCC parameter. ### How do I send the same message to multiple users using Mailgun? Mailgun supports the ability send to a group of recipients through a single API call or SMTP session. This is achieved by either: - Using Batch Sending by specifying multiple recipient email addresses as to parameters and using Recipient Variables. - Using Mailing Lists with Template Variables. See the `batch-sending`{.interpreted-text role="ref"} section of the `user-manual`{.interpreted-text role="ref"} for more information. ### I am getting timeouts when connecting via SMTP. Why? Most often, this is caused by internet service providers ("ISP") blocking port #25. This tends to happen if you are using a residential ISP. To check this, try running telnet in command line: telnet smtp.mailgun.org 25 If port 25 is not blocked, you should see something like this: Trying 174.37.214.195... Connected to mxa.mailgun.org. Escape character is '^]'. 220 mxa.mailgun.org (Mailgun) If you don't see this, then you are being blocked. There are a couple workarounds: - Send using our HTTP API - Try using port #587 or #2525 ### I have multiple domains at Mailgun. How do I tell Mailgun which domain to send mail from? For SMTP, you have an SMTP username and password for each domain you have registered at Mailgun. To send mail from a particular domain, just use the appropriate credentials. For the API, the domain is one of the parameters in the URI. ### I just submitted a lot of messages. Why is delivery happening so slowly? There are many factors that can affect the speed of delivery. 1. Your established reputation for the domain and IPs on your account. 2. The total number of IPs allocated to your account. 3. The content quality for the emails being sent. For newly allocated IPs, Mailgun protects and improves the reputation by gradually increasing sending rates. This means, as time passes, with high quality traffic, being sent from your IPs, your sending rates will increase automatically. If you're seeing slow delivery, please contact us. We'll evaluate your account configuration to ensure it is configured for handling the volume you require. --- # Source: https://documentation.mailgun.com/docs/validate/single-valid-ir.md # Single Validation Info The Validation feature is rate limited to a set number of active requests at a time. If you receive a 429 error, please wait and try again. ``` GET /v4/address/validate ``` Given an arbitrary address, verifies address based off defined checks. | Parameter | Description | | --- | --- | | address | An email address to verify. (Maximum: 512 characters) | ``` POST /v4/address/validate ``` Given an arbitrary address, verifies address based off defined checks. | Form-Data | Description | | --- | --- | | address | An email address to verify. (Maximum: 512 characters) | ## Request Examples Verify a single email address using the GET method. ```JSON curl -s --user 'api:YOUR_API_KEY' \ 'https://api.mailgun.net/v4/address/validate?address=foo@mailgun.com' ``` Verify a single email address using the POST method. ```JSON curl -s --user 'api:YOUR_API_KEY' -X POST \ 'https://api.mailgun.net/v4/address/validate' \ -d 'address=foo@mailgun.com' } ``` Example of a failed mailbox verification result. ```JSON { "address":"nonexistentemail@realdomain.com", "is_disposable_address":false, "is_role_address":false, "reason":["mailbox_does_not_exist"], "result":"undeliverable", "risk":"high" } ``` Example of successful mailbox verification result. ```JSON { "address":"existingemail@realdomain.com", "is_disposable_address":false, "is_role_address":false, "reason":[], "result":"deliverable", "risk":"low" } ``` ## Field Explanation | Parameter | Type | Description | | --- | --- | --- | | address | string | Email address being verified | | did_you_mean | string | (Optional) Null if nothing, however if a potential typo is made to the domain, the closest suggestion is provided | | engagement | object | Contains the boolean fields is_bot and engaged as well as, the string field engagement which lists the type of engagment with the given email | | is_disposable_address | boolean | If the domain is in a list of disposable email addresses, this will be appropriately categorized | | is_role_address | boolean | Checks the mailbox portion of the email if it matches a specific role type ('admin', 'sales', 'webmaster') | | reason | array | List of potential reasons why a specific validation may be unsuccessful. | | result | string | Either deliverable, undeliverable, do_not_send, catch_all, or unknown. Please see the Result Types section below for details on each result type. | | risk | string | high, medium, low, or unknown Depending on the evaluation of all aspects of the given email. | | root_address | string | (Optional) If the address is an alias; this will contain the root email address with alias parts removed. | The provider lookup query parameter provides users with the control to allow or prevent Mailgun from reaching out to the mailbox provider. ``` GET /v4/address/validate?address=test123@test.com&provider_lookup=true ``` ``` POST /v4/address/validate?provider_lookup=true ``` 'true' (default state) - A provider lookup will be performed if Mailgun's internal analysis is insufficient. 'false' - A provider lookup will not be performed. If Mailgun does not have information on the recipient address, the API will return the following response: ```JSON { "address":"address@domain.com", "is_disposable_address":false, "is_role_address":false, "reason":["no_data"], "result":"unknown", "risk":"unknown" } ``` ## Reason Explanation | Reason | Description | | --- | --- | | unknown_provider | The MX provider is an unknown provider. | | no_mx / No MX host found | The recipient domain does not have a valid MX host. *Note: this reason will be consolidated to only "no_mx" in the future.* | | high_risk_domain | Information obtained about the domain indicates it is high risk to send email to. | | subdomain_mailer | The recipient domain is identified to be a subdomain and is not on our exception list. Subdomains are considered to be high risk as many spammers and malicious actors utilize them. | | immature_domain | The domain is newly created based on the WHOIS information. | | tld_risk | The domain has a top-level-domain (TLD) that has been identified as high risk. | | mailbox_does_not_exist | The mailbox is undeliverable or does not exist. | | mailbox_is_disposable_address | The mailbox has been identified to be a disposable address. Disposable address are temporary, generally one time use, addresses. | | mailbox_is_role_address | The mailbox is a role based address (ex. support@…, marketing@…). | | catch_all | The validity of the recipient address cannot be determined as the provider accepts any and all email regardless of whether or not the recipient's mailbox exists. | | accept_all | The validity of the recipient address cannot be determined because the mail server accepts all email addresses regardless of whether the mailbox exists. Invalid addresses may generate delayed bounce notifications after delivery is attempted. | | long_term_disposable | The mailbox has been identified as a long term disposable address. Long term disposable addresses can be quickly and easily deactivated by users, but they will not expire without user intervention. | | failed custom grammar check | The mailbox failed our custom ESP local-part grammar check. | | mailbox_quota_exceeded | The mailbox is full and cannot accept more mail. | | smtp_error | An error was returned while attempting to validate the address. | | smtp_timeout | The MX host did not respond within our expected timeframe. | ## Result Types | Result | Description | | --- | --- | | deliverable | The recipient address is considered to be valid and should accept email. | | undeliverable | The recipient address is considered to be invalid and will result in a bounce if sent to. | | do_not_send | The recipient address is considered to be highly risky and will negatively impact sending reputation if sent to. | | catch_all | The validity of the recipient address cannot be determined as the provider accepts any and all email regardless of whether or not the recipient's mailbox exists. | | unknown | The validity of the recipient address cannot be determined for a variety of potential reasons. Please refer to the associated 'reason' array returned in the response. | --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/tls-connection-settings/skip-verification.md # Skip verification The skip verification option in TLS sending connection settings allows you to bypass certificate validation during email transmission, which can be useful for testing but may reduce connection security. If set to *True*, the certificate and hostname will not be verified when trying to set up a TLS connection, and Mailgun will accept any certificate during delivery. If set to *False*, Mailgun will verify the certificate and hostname. If either one cannot be verified, a TLS connection will not be set up. The default is False. Look at the table below to help you better understand the configuration possibilities and potential issues. Info Consider the type of threat you are concerned with when deciding how to configure sending settings. ** By default, *require-tls* and *skip-verification* are *false.* | **Require-tls** | **Skip-verification** | **TLS** | **TLS Active Attack (MITM)** | **TLS Passive Attack (Capture)** | **Passive Plaintext Capture** | | --- | --- | --- | --- | --- | --- | | false | false | Attempt | Not Possible | Not Possible | Possible via downgrade | | false | true | Attempt | Posible | Not Possible | If STARTTLS not offered | | true | false | Required | Not Possible | Not Possible | Not Possible | | true | true | Required | Possible | Not Possible | Not Possible | Additionally, the following fields are available in your logs under *delivery-status* to indicate how the message was delivered: | **Field** | **Description** | | --- | --- | | `tls` | Indicates if a TLS connection was used or not when delivering the message | | `Certificate-verified` | Indicates if Mailgun verified the certificate or not when delivering the message | | `mx-host` | Tells you the MX server Mailgun connected to deliver the message | --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/smtp-protocol/smtp-protocol.md # SMTP Protocol Introduction In addition to the HTTP API, Mailgun servers also support the standard SMTP protocol. You can send email using SMTP with or without TLS. You will need to refer to the standard library documentation for the language of your choice to learn how to you the SMTP protocol. Below are some links for a few popular languages: - [Ruby SMTP](http://ruby-doc.org/stdlib/libdoc/net/smtp/rdoc/classes/Net/SMTP.html) - [Python SMTP](http://docs.python.org/library/smtplib.html) - [JavaMail API](http://java.sun.com/products/javamail/javadocs/index.html) --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/smtp-protocol/smtp-relay.md # SMTP Relay You can configure your own mail server to relay mail via Mailgun (example below). To do so, you will need the following three variables on the Control Panel. - Your SMTP username - Your SMTP password - SMTP host name mail server (these instructions will use smtp.mailgun.org as an example) You have an SMTP username and password for each domain you have at Mailgun. To send mail from a particular domain, use the proper credentials. ## Postfix Instructions You must configure a relay host with SASL authentication, as shown: ```JSON # /etc/postfix/main.cf: mydestination = localhost.localdomain, localhost relayhost = [smtp.mailgun.org]:587 smtp_sasl_auth_enable = yes smtp_sasl_password_maps = static:postmaster@mydomain.com:password smtp_sasl_security_options = noanonymous # TLS support smtp_tls_security_level = may smtpd_tls_security_level = may smtp_tls_note_starttls_offer = yes ``` When using TLS encryption, make sure Postfix knows where to locate the CA database for your Linus distribution: ```JSON smtpd_tls_key_file = /etc/ssl/private/smtpd.key smtpd_tls_cert_file = /etc/ssl/certs/smtpd.crt smtpd_tls_CApath = /etc/ssl/certs ``` Note: You can use SMTP Credentials, but not your Control Panel password. ## Exim Instructions For more information, see [Exim's documentation authenticated by outgoing SMTP](https://www.exim.org/exim-html-current/doc/html/spec_html/ch-smtp_authentication.html). You will need to configure "smarthost" for your Exim setup. Also make sure to configure login credentials (in your /etc/exim/passwd.clinet): ```JSON # In your exim.conf: # In routes configuration: mailgun: driver = manualroute domains = ! +local_domains transport = mailgun_transport route_list = * smtp.mailgun.org byname # In transports configuration: mailgun_transport: driver=smtp hosts_require_auth = <; $host_address hosts_require_tls = <; $host_address ``` Also make sure to cinfigure login credentials (in your /etc/exim/passwd.client): ```JSON *.mailgun.org:username:password ``` ## Sendmail Instructions Define the smarthost in your sendmail.mc before mailer definitions: ```JSON ## Mailgun define(`SMART_HOST', `smtp.mailgun.org')dnl FEATURE(`authinfo', `hash /etc/mail/authinfo')dnl # optional, see http://www.sendmail.org/m4/features.html before enabling: # FEATURE(`accept_unresolvable_domains')dnl # FEATURE(`accept_unqualified_senders')dnl # execute: make -C /etc/mail ## Mailgun ``` Specify login credentials in your authinfo: ```JSON AuthInfo:smtp.mailgun.org "U:" "P:" "M:PLAIN" ``` Run the following command and then restart sendmail: ```JSON make -C /etc/mail ``` --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/receive-forward-store/spam-filter.md # Spam Filter A spam filter is necessary when receiving email. Mailgun is powered by an army of SpamAssassin machines. Mailgun gives you three ways to configure spam filtering. Click the Domains tab on the Control Panel and select from one of the following three options: - Disabled (default) - Delete Spam (spam is removed and you won't see it) - Mark spam with MIME headers (You decide what to do with it) If you choose to mark spam with MIME headers, Mailgun provides you with these four: - **X-Mailgun-Sflag** - Inserted with the value `Yes` if the message was classified as spam. - **X-Mailgun-Sscore** **-** A 'spamicity' score that you can use to calibrate your own filter. Inserted for every message checked for spam. The score ranges from low negative digits (very unlikely to be spam) to 20 and occasionally higher (very likely to be spam). - **X-Mailgun-Dkim-Check-Result** - If DKIM is used to sign an inbound message, Mailgun will attempt DKIM validation, the results will be stored in this header. Possible values are: `Pass` or `Fail` - **X-Mailgun-Spf -Mailgun** will perform an SPF validation, and results will be stored in this header. Possible values are: `Pass`, `Neutral`, `Fail` or `SoftFail`. --- # Source: https://documentation.mailgun.com/docs/inboxready/spam-trap-ir.md # Spam Trap Monitoring Our [spam trap monitoring](https://help.mailgun.com/hc/en-us/articles/4413151071515-What-are-Spam-Traps) service surfaces how much of your email is being sent to known spam traps. To add and remove domains from our spam trap monitoring service, see the [domain management](/docs/inboxready/domains-ir) API docs. ## Get Counts Use this endpoint to understand how much of your mail being sent to known spam traps. This endpoint returns daily spam trap hit counts for a provided timerange, categorized by trap type. **NOTE** : You must provide a timerange via `start` and `end` query params. If any date(s) at the start and/or end boundaries of your provided timerange contain zero spam trap hits, those dates will be excluded from the response. ``` GET /v1/spamtraps?start=2022-01-01&end=2022-01-31 ``` The available request fields are as follows: | Field | Description | | --- | --- | | `start` | Required. The start date in UTC (format YYYY-MM-DD) of the timeframe for which you wish to see data. | | `end` | Required. The end date in UTC (format YYYY-MM-DD) of the timeframe for which you wish to see data. | | `sortby` | Optional. Acceptable values include `date`, `totals`, `domain`, `subject`, `ip`, and `from`. Defaults to `date`. | | `groupby` | Optional. Use this field to group results. Acceptable values include domain, subject, ip, and from. | Example 200 response: ```JSON { "items": [ { "date": "2022-01-01", "pristine": 34, "recycled": 258, "typo": 178, "total": 470 }, ... ], "paging": { ... } } ``` For more details on the data returned by this API endpoint such as trap types, see our [help documentation](https://help.mailgun.com/hc/en-us/articles/4413151071515-What-are-Spam-Traps). ### Filtered Results** The request fields below can be used to filter spam trip hit counts: | Field | Description | | --- | --- | | `ip` | Optional. Use this field to filter results by ip(s). | | `domain` | Optional. Use this field to filter results by domain(s). | | `subject` | Optional. Use this field to filter results by email subject. | | `from` | Optional. Use this field to filter results by sender email address. | Example request of results grouped by IP *and* filtered by multiple IP addresses: ``` GET /v1/spamtraps?start=2022-01-01&end=2022-01-31&groupby=ip&ip=208.75.123.183&ip=208.75.123.186 ``` Example 200 response: ```JSON { "items": [ { "208.75.123.183": [ { "date": "2022-01-01", "pristine": 2, "recycled": 85, "typo": 32, "total": 119 }, ... ] }, { "208.75.123.186": [ ... ] }, ], "paging": { ... } } ``` --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/smtp-protocol/standard-email-clients.md # Using Standard Email Clients Standard email clients like Thunderbird or Outlook can also be used to send mail. Settings for sending mail: ```JSON SMTP server: smtp.mailgun.org ``` Info Use a full address like "user@mymailgundomain.com" as a login for SMTP. SSL or TLS are supported. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/receive-forward-store/store-retreive.md # Storing and Retrieving Messages When storing an email through a store() action in a Route, you can choose to be notified when the message is stored by including a URL with the notify parameter when setting up the store action or you can retrieve the message later by searching for the message through the [Logs API](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/logs/post-v1-analytics-logs) and retrieving it through the [Messages API](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/messages/get-v3-domains--domain-name--messages--storage-key-). When you set a URL to be posted when the message is received: (store(notify="http://mydomain.com/callback") or retrieve the message later through a GET request to the Messages API, the following parameters are posted/returned in JSON. If at least one attachment is written, then the resulting body will have a multipart/form-data content type, otherwise it will have an application/x-www-form-urlencoded content type. | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `domain` | String | The domain name this message was received from. | | `recipient` | string | The recipient of the message as reported by MAIL TO during SMTP chat | | `sender` | string | The sender of the message as reported by MAIL FROM during SMTP chat. *(This value may differ from the MIME header)* | | `from` | string | The sender of the message as reported by from message header, for example "Bob Lee ". | | `subject` | string | The subject string | | `body-plain` | string | The text version of the email. This field is always present. If the incoming message only has HTML body, Mailgun will create a text representation for you. | | `stripped-text` | string | The text version of the message without the quoted parts and signature block (if found) | | `stripped-signature` | string | The signature block stripped from the plain text message (if found) | | `body-html` | string | The HTML version of the message, if message was multipart. Note that all parts of the message will be posted, not just text/html. For instance, if a message arrives with "foo" part it will be posted as "body-foo" | | `stripped-html` | string | The HTML version of the message, without the quoted parts | | `attachments` | string | The string that contains a JSON list of metadata objects, one for each attachment. | | `message-url` | string | A URL that you can use to get and/or delete the message. Only present in the payload posted to the notification URL | | `timestamp` | int | The number of seconds passed since January 1, 1970 *(See Securing Webhooks)* | | `token` | string | A randomly generated string with a length of 50 *(See Securing Webhooks)* | | `signature` | string | A string with hexadecimal digits generated by HMAC algorithm *(See securing webhooks)*. | | `message-headers` | string | A list of MIME headers dumped to a JSON string (The o_rder of headers is preserved)_ | | `Content-id-map` | string | | Alternatively, you can choose the following parameters when the Accept header is set to message/rfc2822 | Parameter | type | Description | | --- | --- | --- | | `recipient` | string | The recipient of the message | | `sender` | string | The sender of the message | | `from` | string | The sender of the message as reported by the from message header. Example: " | | `subject` | string | The subject string | | `Body-mime | string | The Full MIME envelope. You will need a MIME parsing library to process this data | --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/receive-forward-store/storing-and-retrieving-messages.md # Storing and Retrieving Messages When storing an email through a store() action in a Route, you can choose to be notified when the message is stored by including a URL with the notify parameter when setting up the store action or you can retrieve the message later by searching for the message through the Events API and retrieving it through the Messages API When you set a URL to be posted when the message is received: (store(notify="http://mydomain.com/callback") or retrieve the message later through a GET request to the Messages API, the following parameters are posted/returned in JSON. If at least one attachment is written, then the resulting body will have a multipart/form-data content type, otherwise it will have an application/x-www-form-urlencoded content type. | **Parameter** | **Type** | **Description** | | --- | --- | --- | | `domain` | String | The domain name this message was received from. | | `recipient` | string | The recipient of the message as reported by MAIL TO during SMTP chat | | `sender` | string | The sender of the message as reported by MAIL FROM during SMTP chat. *(This value may differ from the MIME header)* | | `from` | string | The sender of the message as reported by from message header, for example "Bob Lee ". | | `subject` | string | The subject string | | `body-plain` | string | The text version of the email. This field is always present. If the incoming message only has HTML body, Mailgun will create a text representation for you. | | `stripped-text` | string | The text version of the message without the quoted parts and signature block (if found) | | `stripped-signature` | string | The signature block stripped from the plain text message (if found) | | `body-html` | string | The HTML version of the message, if message was multipart. Note that all parts of the message will be posted, not just text/html. For instance, if a message arrives with "foo" part it will be posted as "body-foo" | | `stripped-html` | string | The HTML version of the message, without the quoted parts | | `attachments` | string | The string that contains a JSON list of metadata objects, one for each attachment. | | `message-url` | string | A URL that you can use to get and/or delete the message. Only present in the payload posted to the notification URL | | `timestamp` | int | The number of seconds passed since January 1, 1970 *(See Securing Webhooks)* | | `token` | string | A randomly generated string with a length of 50 *(See Securing Webhooks)* | | `signature` | string | A string with hexadecimal digits generated by HMAC algorithm *(See securing webhooks)*. | | `message-headers` | string | A list of MIME headers dumped to a JSON string (The o_rder of headers is preserved)_ | | `Content-id-map` | string | | Alternatively, you can choose the following parameters when the Accept header is set to message/rfc2822 | Parameter | type | Description | | --- | --- | --- | | `recipient` | string | The recipient of the message | | `sender` | string | The sender of the message | | `from` | string | The sender of the message as reported by the from message header. Example: " | | `subject` | string | The subject string | | `Body-mime | string | The Full MIME envelope. You will need a MIME parsing library to process this data | ## Spam Filter A spam filter is necessary when receiving email. Mailgun is powered by an army of SpamAssassin machines. Mailgun gives you three ways to configure spam filtering. Click the Domains tab on the Control Panel and select from one of the following three options: - Disabled (default) - Delete Spam (spam is removed and you won't see it) - Mark spam with MIME headers (You decide what to do with it) If you choose to mark spam with MIME headers, Mailgun provides you with these four: - **X-Mailgun-Sflag** - Inserted with the value `Yes` if the message was classified as spam. - **X-Mailgun-Sscore** **-** A 'spamicity' score that you can use to calibrate your own filter. Inserted for every message checked for spam. The score ranges from low negative digits (very unlikely to be spam) to 20 and occasionally higher (very likely to be spam). - **X-Mailgun-Dkim-Check-Result** - If DKIM is used to sign an inbound message, Mailgun will attempt DKIM validation, the results will be stored in this header. Possible values are: `Pass` or `Fail` - **X-Mailgun-Spf -Mailgun** will perform an SPF validation, and results will be stored in this header. Possible values are: `Pass`, `Neutral`, `Fail` or `SoftFail`. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/subaccounts/subaccounts-features.md # Summary of Subaccount Features As the primary account, you will have the ability to: - Create and manage access of individual subaccounts, including API keys, sending domains, features and users specific to subaccounts - View/create reporting filtered on or grouped by your subaccounts - View event data/logs filtered by subaccount - Create/manage assign dedicated IP pools to subaccounts including setting the sending IP pool at send time - View usage data filtered by subaccount - The ability to add a DYIPP (Dynamic IP Pool) to their subaccount when they enable the feature for their subaccount As a subaccount user, you will have the ability to: - send messages via API (using subaccount level API key) - send messages via SMTP - set sending domains - set webhooks - view sending statistics via UI and API - view event logs via UI and API - create/edit templates via UI and API Info Subaccount API keys have no restrictions and can be used on all available endpoints at the subaccount level. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/subaccounts/subaccounts-ip-pools.md # Subaccounts and IP Pools As a primary account admin you can manage the IP Pools that will be used by your subaccounts in one of three ways. 1. Define IP pool at send time - The primary account can use the header X-Mailgun-Sending-Ip-Pool and the pool ID of the IP pool contained on the primary account. 2. Delegate IP Pool to subaccount - During either the creation or later editing the details of the subaccount from the primary account UI, an admin can define a single IP pool for use by the subaccount. The IP pool can then be assigned to any sending domain contained on the subaccount. 3. Add DYIPP (Dynamic IP Pools) to their subaccount - The primary account admin has the option to enable and assign DYIPP for the entire subaccount or assign to individual domains within a subaccount. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/subaccounts/subaccounts-terms.md # Terminology | Term | Definition | | --- | --- | | **Primary Account** | The top-level organizational Mailgun account where subaccounts originate. | | **Subaccount** | The separate-but-linked entities used to organize various use-cases, customers, etc. | | **RBAC Permissions** | Primary account admin users and developers can create/manage subaccounts. Primary account RBAC user types with access to reporting and logs can view subaccount data. | ### Name and Status Additionally primary account admins can edit name and status of subaccounts: | Subaccount Status | Description | | --- | --- | | Enabled | Default, subaccount has all available access via API and UI. | | Disabled | API access suspended, UI access limited to read-only state. | | Closed | Subaccount is deleted all data specific to that subaccount including API keys users and sending domains and sending history/stats are removed and cannot be recovered. | ### Use Cases As subaccounts are designed for full segmentation of account assets, they can be used to support a number of business cases. The most common would be the need to give a separate business unit, project, or even a customer separate access to Mailgun including the separate of sending assets and data/reporting. Other potential use cases include: - You are a marketing platform that needs to segment your end-users into their own separate subaccounts. - A cross-functional team also needs email capabilities but you need to ensure their sending assets and data is separate from your own. - You have a specific mail stream or project that needs separate assets and reporting. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/subaccounts/subaccounts.md # Subaccounts Overview Mailgun’s subaccount functionality allows account admins and developers the ability to create and manage a new Mailgun account that is linked to the primary account, but with wholly separate assets such as sending domains, IPs, API keys, and if necessary, users. From a billing and administrative standpoint, all usage on the subaccount level is tracked and rolled into the usage of the primary account. At this time subaccounts cannot be billed separately. Info - Subaccount access is based on plan features. To see available plans visit https://www.mailgun.com/pricing/ - At this time Mailgun Optimize is not available on subaccounts --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/sending-messages/test-mode.md # Sending in Test Mode You can send messages in test mode by setting the `o:testmode` parameter to either `yes` or `true`. When you do this, Mailgun will accept the message but will not send it. This is useful for testing purposes. Info You are charged for messages sent in test mode! --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/events/time-range.md # Time Range When making a request, you need to specify a time range, which consists of a starting timestamp. Additionally, you must include either an ending timestamp or indicate a search direction. If you don't provide an ending timestamp, you must specify a search direction. When you provide a range end timestamp, the relationship between the beginning and end timestamps determines the traversal direction of events—either ascending or descending. For instance, if the end timestamp is less (older) than the beginning timestamp, the result pages are returned from newer to older, and events on these pages are sorted in descending order based on their timestamps. If the end timestamp is not provided, the direction must be specified, and based on this direction, the behavior of result page traversal behaves differently: - If the range is descending, then the end timestamp is determined by the user tariff plan retention period. - If the range is ascending, events will continue to be recorded, however, the request time range won't be displayed on the provided pages. After retrieving the latest events and reaching an empty result page, requesting the next page URL later will show events that happened afterward. This process can continue indefinitely. Warning! Although it may appear that real-time event polling can be achieved by continuously traversing the next URLs of an ascending time range without an explicit end timestamp, the process is not as straightforward as it seems. Please refer to the guidelines outlined in the Event Polling section for the correct approach. If both the end range dates and the direction of the search are specfied, then they should agree with each other, otherwise the request will return an error. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/tls-connection-settings/tls-sending.md # TLS Sending Connection Settings Mailgun exposes flags for mail delivery that will work at the Domain or per Message level. This allows you to control how messages are delivered. ***Note: The Message level/setting will OVERRIDE the Domain level/setting.*** --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/tracking-messages/track-stats.md # Stats You can view stats aggregated by tag within the Analytics portion of the Mailgun UI. Additionally the [Stats API](https://documentation.mailgun.com/docs/mailgun/api-reference/openapi-final/tag/Stats/) can provide this detail in your own application. You can also filter by tags in the [Reporting Dashboard](https://help.mailgun.com/hc/en-us/articles/4402703701019-Reporting-Dashboard). --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/tracking-messages/track-tagging.md # Tags Mailgun allows you to tag your email with unique identifiers. They can help segment your email into relevant categories for later analysis and optimization. Tags are visible via event data and will be included in webhook payloads. Examples of when to use a tag: - Identifying mail type, like “password reset” or “welcome” - Identifying campaign or audience, like “Black Friday” or “new signup” Tags are further enhanced when using Mailgun for open and click tracking. You can understand the full performance of your tag via Analytics in the Mailgun UI, including comparison to other tags. ### Tagging Code Sample ``` curl -s --user 'api:YOUR_API_KEY' \ https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \ -F from='Excited User ' \ -F to=recipient@example.com \ -F subject="Hello there!" \ -F text='Testing some Mailgun awesomeness!' \ -F o:tag='September newsletter' \ -F o:tag='newsletters ``` Note: - By default, each account is allowed a maximum of 20,000 tags per domain. If more tags are needed, please go [here](https://app.mailgun.com/support/list) to create a ticket for Mailgun's Support Team. - A single message may be marked with up to 3 tags. Tags are case insensitive and should be ascii only. The maximum length of characters is 128. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/tracking-messages/tracking-clicks.md # Tracking Clicks Mailgun can track every time a recipient clicks on a link included in your email. When you enable Click tracking, links will be overwritten and point to Mailgun's servers, giving us the ability to track. These events can be viewed in the Control Panel in the **Logs** tab. You can also see counters of opens aggregated by tags by visiting the **Analytics** tab on the Control Panel. In addition, you can be notified through a webhook, or get the data programmatically through the Events API. Click tracking can be enabled two ways - on a per-domain basis: toggled in the **Tracking Settings** which can be found on your domain's settings page - on a per-message basis using the parameters, `o:tracking`, or `o:tracking-clicks` when sending an email. This will override the domain setting. You can specify that you only want links rewritten in the HTML part of the message with the parameter `o:tracking-clicks` and passing `htmlonly`. See the [API documentation](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/messages/post-v3--domain-name--messages) for more details. You can also disable click tracking for a specific link by including the HTML attribute `disable-tracking=true` in the HTML tag of the link. With this HTML attribute in the link's HTML tag, Mailgun will not rewrite the URL. **Example** : `Mailgun\` --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/tracking-messages/tracking-deliveries.md # Tracking Deliveries Mailgun tracks all successful deliveries that occur when the recipient email server responds that it has accepted the message. You can see when a message has been successfully sent by clicking on the Logs tab found on the Control Panel. You can also be notified when a message has been delivered through a webhook or get the data programmatically through the Events API. Do note that, for messages that get routed to an HTTP endpoint, we *do not* send a Delivered webhook to your configured URL(s). We *do* emit the delivered event for the message itself so that the Routed delivery shows up in the Events API. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/tracking-messages/tracking-failures.md # Tracking Failures Mailgun tracks all delivery failures, which consists of both hard bounces (permanent failures), and soft bounces (temporary failures). When an email message is said to "bounce", this means that it was rejected by the recipient SMTP server. Bounced addresses are found on the "Bounces" table, which is found on the **Suppressions** tab on the Control Panel. With respect to failure persistence, Mailgun classifies bounces into two categories: - **Hard bounces** (permanent failure): This based on these criteria: - The recipient is not found - The recipient email server specifies that the recipient does not exist - **Soft bounces** (temporary failure): - Email is not delivered because the mailbox is full or for other reasons. **Permanent and Temporary Failure Webhooks** There may be a few reasons why Mailgun needs to stop trying to deliver messages. The most common reason being that Mailgun has received a hard bounce or repeatedly received soft bounces. Continually attempting to deliver the message may affect the sender's reputation with the receiving ESP. When the address is on one of the 'Do Not Send" lists because the recipient has previously bounced, unsubscribed, or reported spam, Mailgun will drop the message and stop trying to send it. If one of these events occurs, Mailgun will POST the following webhooks payload to your permanent_fail URLs. You can specify webhook URLs programmatically using the Webhook API. With respect to when the recipient SMTP server has rejected incoming messages, Mailgun will classify bounces into the following categories: - **Immediate bounce** : - An email message is rejected by the recipient SMTP server during the SMTP session. - **Delayed** (asynchronous) **bounce:** - The recipient SMTP server accepts an email message during the SMTP session. After some time, it will send a Non-Delivery Report email message to the message sender. Note: In case of a bounce, Mailgun will retry to deliver the message only if the bounce was both immediate and soft. After several unsuccessful attempts, Mailgun will quit trying to preserve your sending reputation. Warning! Mailgun can track delayed bounces, but only if the domain that the email message was sent from has MX records pointing to Mailgun; Otherwise, NDR email messages will not reach Mailgun. Please refer to Verifying Your Domain for details on how to do that.e --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/tracking-messages/tracking-messages.md # Introduction to Email Events Mailgun provides comprehensive email tracking tools that offer insights through **Events**, **Stats**, and **Tagging** in order to help you optimize your email strategy by providing detailed insights into the performance and engagement of your emails. You can monitor various aspects of your emails, including: - Tagging: Categorize and filter your emails for better management. - Tracking Open Messages: See when recipients open your emails. - Tracking Clicks: Monitor links clicked within your emails. - Tracking Unsubscribes: Track when recipients opt-out from your mailing list. - Tracking Spam Complaints: Identify when your emails are marked as spam. - Tracking Failures: Understand when and why email deliveries fail. - Tracking Deliveries: Confirm successful delivery of your emails. Mailgun provides a variety of methods to access this data: - To see every event that happened to every message, view and search Events through the **Logs** tab in the Control Panel. You can search by fields, like recipient, subject line, and even fields that don't use up in the Logs, such as message-id. Data is stored for at least 30 days for paid accounts, and at least 2 days for free accounts. - Access data on Events programmability through the Events API. Data is stored for at least 30 days for paid accounts and at least 2 days for free accounts. - View, search, and edit tables for Bounces, Unsubscribes, and Spam Complaints in the **Suppressions** table of the Control Panel of their retrospective APIs (Bounces API, Unsubscribes API, Complaints API). Data is stored indefinitely. - Access statistics aggregated by tags in the **Analytics** tab of the Control Panel or the Stats API. Data is stored for at least six months. - Receive notifications of events through he Webhook each time an Event happens and store the data on your side. In addition to tracking messages, Mailgun permanently stores them when they cannot be delivered due to a hard bounce (permanent failure), or when a recipient unsubscribes or marks the message as spam. In these cases, Mailgun will not attempt to deliver messages to those recipients in the future. This is to protect your sending reputation. ### Enable Tracking Event tracking is automatically enabled, with the exception for **Unsubscribes** , **Opens** , and **Clicks**. You can enable these for your domain's via the **Domains** tab of the **Control Panel**. Opens and Clicks tracking can be enabled on two levels – per sending domain (as mentioned above) and per message. Please see [Open Tracking](#tracking-open-messages) and [Click Tracking](#tracking-clicks) for more details There are two critical components to get tracking working properly - You will need to point CNAME records to mailgun.org for Mailgun to rewrite links and track opens. These records can be found in your domains DNS records `Tracking records` section. - There needs to be an HTML part of the message for Mailgun to track opens. (See Tracking Opens and Tracking Clicks for more details.) #### Tracking Protocol (HTTP vs HTTPS) By default, all tracking is performed over HTTP. If you want secure links to be used, you can set the `tracking protocol` to HTTPS via our control panel under your domains settings. When set to HTTPS Mailgun will generate a Let's Encrypt TLS certificate for your tracking domain and use the HTTPS protocol for all tracking links. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/tracking-messages/tracking-opens.md # Tracking Opens Mailgun uses tracking pixels and URL redirects to track every time a recipient opens a message. These events can be viewed in the Control Panel in the **Logs** tab. You can also see counters of opens aggregated by tags by visiting the **Analytics** tab on the Control Panel. In addition, you can be notified through a webhook, or get the data programmatically through the Events API. Open tracking can be enabled two ways - on a per-domain basis: toggled in the **Tracking Settings** which can be found on your domain's settings page - on a per-message basis using the parameters, `o:tracking`, or `o:tracking-opens` when sending an email. This will override the domain setting. See the [API documentation](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/messages/post-v3--domain-name--messages) for more details By default, the open tracking pixel is added at the bottom of your email to mitigate possible impacts to email design. If you send long emails that experience truncation or other rendering issues at the recipient, you can ensure opens are being tracked accurately with placement of the tracking pixel at the top of your emails. This can be done on a domain level or a per-message level. - on a per-domain basis: `Place open tracking pixel at top of message` can be toggled in the **Tracking Settings** which can be found on your domain's settings page (Same as where you enable open tracking) - on a per-message basis using the parameters, `o:X-Mailgun-Track-Pixel-Location-Top`when sending an email. This will override the domain setting. See the [API documentation](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/messages/post-v3--domain-name--messages) for more details Info Text only emails will not track opens. Opens are tracked by including a transparent `.png` file which will only work if there is an HTML component added to the email. It's also worth mentioning that many email service providers disable images by default, meaning this data will only show up if the recipient clicks on the display images button in the recipient's email. As mentioned earlier on in this article, you will have to add the appropriate CNAME records to your DNS as specified in the **Domain Verification & DNS section** in order for this feature to work properly. # Open Webhook You can specify webhook URLs programmatically using the Webhooks API. When a user opens an email that you have sent, your **opened** URLs will be called with the following webhooks payload. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/tracking-messages/tracking-spam-complaints.md # Tracking Spam Complaints Email service providers (ESP) are very sensitive to users clicking on spam complaint buttons. It's important to monitor that activity to maintain a good sending reputation. While not all ESP supports Feedback Loop (FBL) notifications, Mailgun makes sure that you get data on all the ones that you do, will not remove recipients from future messages if the complaint has been filed by the recipient, Mailgun automatically tracks all messages recipients report as spam. You can view spam complaints on the control panel by clicking on the **logs** tab or by clicking on the **Analytics** tab to see counters of complaints aggregated by tags. You can also be notified through a webhook. When a recipient report one of your emails as spam, Mailgun will invoke the complained webhook with the following payload. Another way to track complaints is to get the data programmatically through the Events API or the Complaints API. You can Mailgun provides the Spam Complaint API to programmatically manage lists of users who have complained. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/tracking-messages/tracking-unsubscribes.md # Tracking Unsubscribes ### Auto-Handling Mailgun will automatically prevent future emails from being sent to recipients who have unsubscribed when you enable the Unsubscribe functionality by going to the settings in your domain area on the Control Panel. You can also edit the unsubscribed address list from the Control Panel or through the API. Note: Before enabling the Unsubscribe feature, you will need to configure the required DNS entries provided in your Control Panel. ### Unsubscribe Variables Mailgun provides you with several unsubscribe variables: | **Variable** | **Description** | | --- | --- | | `%unsubscribe_url%` | Link to unsubscribe recipient from all messages sent by given domain. | | `%tag_unsubscribe_url%` | Link to unsubscribe from all tags provided in the message. | | `%mailing_list_unsubscribe_url%` | Link to unsubscribe from future messages sent to a mailing list. | When these variables are included in your emails, any recipient who clicks on the URL will be automatically unsubscribed, and those email addresses will be blocked from receiving future emails from that domain or message tag. Mailgun can automatically provide a customizable unsubscribe footer in each email you send. You can edit the unsubscribe footer by editing the settings in your control panel. To enable/disable unsubscribes programmatically, you can do the following: - Enable the Unsubscription feature for your domain. - Remove text in the HTML and text footer so they won't be appended automatically. - Insert a variable in the HTML and text bodies of your email when you need unsubscribe links. - This variable will be replaced by the corresponding unsubscribe link. When you go to the **Suppressions** tab of the Control Panel or through the API, you can also: - View/get a list of unsubscribed addresses - Remove an unsubscribed address from the list - Add a new unsubscribed address Learn how to programmatically manage lists of unsubscribed users by visiting the Unsubscribes section of the API reference. **Unsubscribe Webhook** You can specify webhook URLs programmatically using Webhooks API. When a recipient unsubscribes, Mailgun will invoke the unsubscribed webhook with the following webhooks payload. --- # Source: https://documentation.mailgun.com/docs/mailgun/faq/tracking.md # FAQ: Tracking ### Can I use Mailgun to track what happens with my emails? Yep, Mailgun tracks all of the typical events that occur with emails: Opens, Link Clicks, Bounces, Unsubscribes and Spam Complaints. We make that data available to you via the Control Panel or through the API. In addition, you can set up webhooks and we will post events to your URL. Take a look at our [tracking documentation](https://documentation.mailgun.com/docs/mailgun/user-manual/tracking-messages) for more information. ### What about Email List Management? Mailgun does have features to help you with list management. First of all, we will not deliver again to recipients that have hard bounced, unsubscribed, or complained of spam. This is to maintain your email reputation. You can remove emails from these do not send lists if it was a temporary issue. You can always access this information via the API or Control Panel to update your lists. ### What is the difference between hard and soft bounces and how do you handle them? You can think of hard bounces like permanent errors and soft bounces as temporary errors. We will stop attempting delivery after one hard bounce. With soft bounces, we keep trying to deliver but eventually we will stop trying to delivery in accordance with the receiving ESP's feedback. ### Do I control the unsubscribe handling or do you? It's up to you. You can use Mailgun's unsubscribe handling. You can include our unsubscribe variables: `%unsubscribe_url%` (for the entire domain) and `%tag_unsubscribe_url%` (for just emails with this tag) and we will take care of the unsubscribe handling for you. Take a look at our [unsubscribe documentation](https://documentation.mailgun.com/docs/mailgun/user-manual/sending-messages/#unsubscribing) for more information. ### How do I create Campaigns in Mailgun? It's very simple, just tag your emails with the appropriate `o:tag` parameter and Mailgun will group all of the events that occur to emails with that tag. Our analytics reports include those tags as one of the dimensions by which you can view and filter data. You can have multiple tags per email and up to 4,000 total tags. Take a look at our [tagging documentation](https://documentation.mailgun.com/docs/mailgun/user-manual/tracking-messages/#tagging) for more information. ### Do you support A/B testing? Since creating a campaign is as easy as including an arbitrary tag, yes. You can easily view which campaign is performing best by viewing the data grouped by tag in the `Analytics` tab of the Mailgun control panel. ### How do I track which email a recipient has replied to? This has been a popular question, so we wrote a [blog post](https://www.mailgun.com/blog/tracking-replies-in-mailgun-or-any-other-email/) about it. Basically, the Message-ID in the original email is included in the In-Reply-To header in the reply email. So you can use that to track which specific email was replied to. Mailgun will automatically include a unique Message-ID or you can set your own. --- # Source: https://documentation.mailgun.com/docs/mailgun/email-best-practices/unsubscribe.md # Unsubscribe Handling It is important to give your recipients the ability to unsubscribe from emails. First, it is required by the [CAN-Spam Act](https://www.ftc.gov/business-guidance/resources/can-spam-act-compliance-guide-business). Second, if you don't give them this option, they are more likely to click on the spam complaint button, which will cause more harm than allowing them to unsubscribe. Finally, many MBPs (Mailbox Providers) look for unsubscribe links and are more likely to filter your email if they don't have them. Mailgun gives you the ability to include an unsubscribe link or email automatically in your email. We give you the ability to link the unsubscribe to a certain campaign, mailing list or make the request global to your domain. You can access this data through the Control Panel, API or via Webhooks. In addition, we will automatically stop sending to email addresses that have unsubscribed. It is possible to remove addresses from the flagged list in your Control Panel or through the API. --- # Source: https://documentation.mailgun.com/docs/validate/validate_engagement.md # Engagement Validation ## What is Engagement Validation? Validate’s engagement results are a macro-level view that explain an email recipient’s propensity to engage. For contract customers, when an email list is validated, we assign a behavior type to each email recipient based on the email recipient’s engagement activity over the last 30-days. These results are included with every bulk validations and single validations job. For self-serve customers, we provide a modified version of engagement results. ## Engagement Results for Contract Customers Contract customers will see the following engagement behavior types assigned to each email recipient. For customers using the UI, in addition to the results that are included in the .csv file, a third chart will display the breakdown of engagement behavior types. ### For engaging behavior types | Behavior Type | Description | | --- | --- | | Bot | An unreasonably high number of clicks in a 30-day period. | | Complainer | Recipient has complained, reported to spam, in a 30-day period. | | High Engager | Recipient has clicked on or opened several emails in a 30-day period (excludes automatic opens). | | Engager | Recipient has clicked on or opened emails but not enough to identify the recipient as a High Engager. | ### For non-engaging behavior types | Behavior Type | Description | | --- | --- | | Disengaged | Recipient only has delivered emails. | | No data | No data because the email was validated via 'provider lookup' in the last 30 days. | ## Engagement Results for Self-Service Customers Self-serve customers will receive Boolean results for engagement and whether the email recipient is a bot. The results are available in the downloadable `.csv` or `json` file. | Type | Settings | | --- | --- | | Engaging | true or false | | Bot | true or false | Note: We ignore automatic opens and clicks when calculating the validate email’s behavior type. ## What is the value of Validate’s engagement results? Validate’s engagement results can help segment your email list more effectively. Not only do we provide information on whether a validated email address exists and is deliverable, we provide additional information as to whether the email recipient has engaged with their emails in the last 30-days. Senders can now segment their lists based on engagement behavior and adjust the content and tone of their email campaigns according to the behavior type for best results. This will help the sender maximize their opens, clicks, conversions, and ultimately their reputation as a sender. --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/receive-forward-store/view-stored-messages.md ## Viewing Stored Messages To access the contents of the stored messages (including raw MIME) you'll need the email's storage URL. This can be found on a Domains Accepted/Delivered/Failed event. The event can be found through the [Logs API](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/logs) or through the UI in the expanded log entry under the Send->Logs section. ### Sample code Run the following python script with the storage key as a parameter. The script will retrieve the message from Mailgun. In the script the message is saved to "message.eml", which can then be opened in Mozilla Thunderbird for analysis. ``` """View a message using its Mailgun storage key.""" import os import sys import requests if len(sys.argv) != 2: print "Usage: retrieve.py message_key" sys.exit(1) api_key = YOUR_API_KEY # output filename filename = "message.eml" # url for retrieval domain = "mailgun.com" key = sys.argv[1] url = "https://api.mailgun.net/v3/domains/%s/messages/%s" url = url % (domain, key) headers = {"Accept": "message/rfc2822"} # request to API r = requests.get(url, auth=("api", api_key), headers=headers) if r.status_code == 200: with open(filename, "w") as message: message.write(r.json()["body-mime"]) os.system("thunderbird -file %s" % filename) else: print "Oops! Something went wrong: %s" % r.content ``` --- # Source: https://documentation.mailgun.com/docs/mailgun/user-manual/events/webhooks.md # Webhooks Webhooks allows you to programmatically handle events that happen with your messages sent through Mailgun. By configuring URL(s) in the **Webhooks** tab of the **Control Panel**, Mailgun can send HTTP/HTTPS POST requests to specified endpoints when certain events occur. Webhooks are configured at the domain level, enabling you to set unique endpoints for each domain via the domain drop-down selector. Supported Webhook types: - Accepted, Delivered, Clicks, Spam Complaints, Unsubscribes, Permanent Failures, Temporary Failures, Spam Complaints | **Note:** If you want to include an HTTPS endpoint, it must be configured with a trusted CA (Certificate Authority) signed SSL certificate, not a self-signed certificate. You can read more about the data that is posted in the appropriate section below (Tracking Opens, Tracking Clicks, Tracking Unsubscribes, Tracking Spam Complaints, Tracking Failures, Tracking Deliveries). We recommend using [http://bin.mailgun.net/](http://bin.mailgun.net/) for creating temporary URLs to test and debug your webhooks. | | --- | For Webhook POSTs, Mailgun listens for the following codes from your server and reacts accordingly: - If Mailgun receives a 200 (Success) code, it will determine the webhook POST is successful and not retried. - If Mailgun receives a 406 (Not Acceptable) code, Mailgun will determine the POST is rejected and not retry. - For any other code, Mailgun will retry POSTing according to the schedule below for Webhooks other than the delivery notification. If your application is unable to process the webhook request, but you do not return a 406 error code, Mailgun will retry (other than for delivery notification) during 8 hours at the following intervals before stopping to try: 5 minutes, 10 minutes, 15 minutes, 1 hour, 2 hours, and 4 hours. The Webhooks API endpoint allows you to programmatically manipulate the webhook URLs defines for a specific domain. See the Webhooks API for more details. ### Payload When something happens to your email, your URL will be called with application/JSON payload with the following data: ```JSON { “signature”: { "timestamp": "1529006854", "token": "a8ce0edb2dd8301dee6c2405235584e45aa91d1e9f979f3de0", "signature": "d2271d12299f6592d9d44cd9d250f0704e4674c30d79d07c47a66f95ce71cf55" } “event-data”: { "event": "opened", "timestamp": 1529006854.329574, "id": "DACSsAdVSeGpLid7TN03WA", // ... } } ``` The 'signature' parameters are described in [Securing Webhooks](#securing-webhooks) and the 'event-data' parameters are the same as described in Event Structure. ### Securing Webhooks To ensure the authenticity of event requests, Mailgun signs them and posts the signature alongside the webhook's event-data. A signature takes the following form: | **Parameter** | **Type** | **Description** | | --- | --- | --- | | timestamp | int | Number of seconds passed since January 1, 1970. | | token | string | Randomly generated string with length of 50. | | signature | string | String with hexadecimal digits generated by an HMAC algorithm | To verify the webhook originated from Mailgun, you will need to: - Concatenate timestamp and token values together with no separator. - Encode the resulting string with the HMAC algorithm, using your Webhook Signing Key as a key and SHA256 digest mode. - Compare the resulting hexdigest to the signature. If they do not match then the webhook is not from Mailgun! - Optionally, you can cache the token value locally and not honor any subsequent request with the same token. This will prevent replay attacks. - Optionally, you can check if the timestamp is not too far from the current time. - There can be delays in webhook processing that are outside of Mailgun's control so you don't want to be too aggressive with this check. To visualize, here's a sample NodeJS snippet that checks the Webhook signature: ```javascript const crypto = require('crypto') const verify = ({ signingKey, timestamp, token, signature }) => { const encodedToken = crypto .createHmac('sha256', signingKey) .update(timestamp.concat(token)) .digest('hex') return (encodedToken === signature) } ``` #### TLS Client Authentication If your receiving server uses valid TLS configuration - Mailgun includes a TLS client certificate with our Webhook requests. This allows customers to use transport-level validation by inspecting the TLS certificate provided in the request to perform additional validation for whether the request originated from Mailgun. How it works: - Mailgun includes our TLS client certificate in webhook requests, which is owned and managed by Mailgun and is issued by DigiCert - Your server should be configured to only accept requests from clients with valid TLS certificates issued by a trusted CA (e.g., DigiCert) - Once you've confirmed the certificate is valid: then verify that the certificate's Common Name (CN) is `webhooks.mgsend.net` Warning! We do not support validation of server certificates issued by custom CA’s on Mailgun's side before sending, i.e mutual TLS (mTLS) You can download the current certificate for inspection from our [US](https://api.mailgun.net/v1/webhooks/tls_cert) or [EU](https://api.eu.mailgun.net/v1/webhooks/tls_cert) API.