A javascript sdk for Mailgun built with webpack, babel & es6. This can be used in node or in the browser*.
npm install mailgun.jsA javascript sdk for Mailgun built with webpack, babel & es6. This can be used in node or in the browser*.
NOTE: If used in the browser, a proxy is required to communicate with the Mailgun api due to cors limitations. Also, do not publish your private api key in frontend code.
__Table of Contents__
- Documentation
- Install
- Setup Client
- Available Imports
- Types imports
- Interfaces and Enums imports
- Fetch API usage
- Proxy configuration
- SubAccounts
- Generated docs
- Methods
- Pagination
- Browser Demo
- Examples
- Development
- Requirements
- Build
- Tests
- Release Process
- Requires node.js >= 18.x
Install mailgun.js with:
``SH`
npm install mailgun.js
The next step is to import 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 built-in FormData or form-data library.
IMPORTANT: if you use EU infrastructure, you need to also pass url: 'https://api.eu.mailgun.net' together with auth credentials as stated in Mailgun docs
or require approach:`js
const Mailgun = require('mailgun.js');
const mailgun = new Mailgun(FormData); // or const formData = require('form-data');
const mg = mailgun.client({username: 'api', key: process.env.MAILGUN_API_KEY || 'MAILGUN_API_KEY'});
`
`js
import Mailgun from 'mailgun.js';
const mailgun = new Mailgun(FormData); // or import formData from 'form-data';
const mg = mailgun.client({username: 'api', key: process.env.MAILGUN_API_KEY || 'MAILGUN_API_KEY'});
`Be aware that there are four bundles available for usage. All of them are conditionally exported by package.json and separated by environment (Browser/Node.js):
- Node.js environment:
- CommonJS (CJS), a bundle to use with the CommonJS module system in Node.js.
Usage example:
` JS
// In this case, the .dist/CJS/mailgun.node.cjs file is expected to be used
const Mailgun = require('mailgun.js');
const mailgun = new Mailgun(FormData);
` - ECMAScript modules (ESM) a bundle for the Node.js environment
Usage example:
` JS
// In this case, the .dist/ESM/mailgun.node.js file is expected to be used
import Mailgun from 'mailgun.js';
const mailgun = new Mailgun(FormData);
...
`
or with dynamic imports:
` JS
// In this case, the .dist/ESM/mailgun.node.js file is expected to be used
const Mailgun = await import('mailgun.js');
const mailgun = new Mailgun.default(FormData);
...
` - Browser environment:
- Asynchronous Module Definition (AMD), a bundle to use with the
Require.js module loader in the browser. This bundle requires the RequireJS module loader to be present in the environment. Usage example for the case when the distribution is used directly in the browser:
` HTML
` - ECMAScript modules (ESM) a bundle for browser environment.
Usage example for the case the distribution is used directly in the browser:
` HTML
`
or with dynamic imports:
` HTML
`$3
Types defined by SDK can be imported from 'definitions' submodule:
`TS
import { MailgunClientOptions, MessagesSendResult } from 'mailgun.js/definitions';
`$3
Interfaces and Enums defined by SDK can be imported from 'definitions' submodule:
`TS
import { Interfaces, Enums } from 'mailgun.js/definitions';
...
const mailgunClient: Interfaces.IMailgunClient = mailgun.client(clientOptions);
const yes = Enums.YesNo.YES;
...
`
$3
Starting from version
12.1.0, the Fetch API is available for use in environments that do not support XMLHttpRequest.The new
useFetch configuration parameter is responsible for this.Note that proxy configuration and the
form-data NPM package are not supported in this case.Example:
`TS
import Mailgun from 'mailgun.js';
const mailgun = new Mailgun(FormData);const mg = mailgun.client({
username: 'api',
key: process.env.MAILGUN_API_KEY || 'MAILGUN_API_KEY',
useFetch: true,
});
`
$3
By leveraging client configuration options, users can effortlessly establish proxy connections that align with their network requirements.
Example:
`js
import Mailgun from 'mailgun.js';
const mailgun = new Mailgun(FormData);// or import FormData from 'form-data'; const mg = mailgun.client({
username: 'api',
key: process.env.MAILGUN_API_KEY || 'MAILGUN_API_KEY',
proxy: {
protocol: 'https' // 'http' ,
host: '127.0.0.1', // use your proxy host here
port: 9000, // use your proxy port here
auth: { // may be omitted if proxy doesn't require authentication
username: 'user_name', // provide username
password: 'user_password' // provide password
}
},
});
`$3
Primary accounts can make API calls on behalf of their subaccounts. API documentation
`js
import Mailgun from 'mailgun.js';
const mailgun = new Mailgun(FormData); // or import FormData from 'form-data'
const mg = mailgun.client({username: 'api', key: process.env.MAILGUN_API_KEY || 'MAILGUN_API_KEY'});
mg.setSubaccount('subaccount-id');
// then, if you need to reset it back to the primary account:
mg.resetSubaccount();
`
$3
The list of all available Types, Interfaces and Enums is auto-generated and located in the docs folder.Methods
The following service methods are available to instantiated clients. The examples assume you have already created a mailgun client as
mg with valid credentials.- Documentation
- Install
- Setup Client
- Methods
- messages
- create
- retrieveStoredEmail
- resendEmail
- getMessagesQueueStatus
- clearMessagesQueue
- domains
- list
- get
- create
- update
- verify
- destroy
- getTracking
- updateTracking
- getConnection
- updateConnection
- updateDKIMAuthority
- updateDKIMSelector
- getIps
- assignIp
- domain templates
- list
- get
- create
- update
- destroy
- destroyAll
- listVersions
- getVersion
- createVersion
- updateVersion
- destroyVersion
- domain tracking
- getTracking
- updateTracking
- get
- generate
- regenerate
- domain keys
- list
- listAll
- create
- activate
- deactivate
- destroy
- updateDKIMAuthority
- updateDKIMSelector
- events
- get
- Example with Date and Filter field
- logs
- list
- stats
- Stats Options
- getDomain
- getAccount
- metrics
- getAccount
- getAccountUsage
- suppressions
- list
- Bounces Example
- Unsubscribes Example
- Complaints Example
- get
- Bounces Example
- Unsubscribes Example
- Complaints Example
- create
- Bounces Example
- Unsubscribes Example
- Unsubscribe from one tag
- Unsubscribe from particular tags
- Complaints Example
- destroy
- Bounces Example
- Unsubscribes Example
- Complaints Example
- upload
- Bounces list upload example
- Unsubscribes list upload example
- Complaints list upload example
- Whitelists list upload example
- webhooks
- list
- get
- create
- update
- destroy
- routes
- list
- get
- create
- update
- destroy
- validate
- get
- multiple validation
- create
- list
- get
- destroy
- mailing lists
- list
- get
- create
- update
- destroy
- mailing list members
- listMembers
- getMember
- createMember
- createMembers
- updateMember
- destroyMember
- subaccounts
- list
- get
- create
- enable
- disable
- destroy
- setMonthlySendingLimit
- getMonthlySendingLimit
- updateSubaccountFeature
- inbox placements
- SeedsLists
- list
- get
- create
- update
- destroy
- SeedsLists Attributes
- list
- get
- SeedsLists Filters
- list
- Providers
- list
- Results
- list
- get
- destroy
- getResultByShareId
- Results Attributes
- list
- get
- Results Filters
- list
- Sharing
- get
- update
- Run Test
- DKIM Management
- update
- Bounce Classification
- list
- Tags
- list
- limits
- update
- destroy
- Navigation thru lists
- Browser Demo
- Development
- Requirements
- Build
- Tests
- Release Process
- TODO
$3
- get or get{{Item}} - expected response for client is a single object
- list or list{{Items}} - expected response for client is a list of objects
- create or create{{Item}} - expected response for client is a single object
- update or update{{Item}} - expected response is an object with a status message
- destroy or destroy{{Item}} - expected response is an object with a status message$3
- #### create
API Reference
mg.messages.create(domain, data) Options:
Parameter | Description
:---------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
to | Email address of the recipient(s). Example: "Bob ". You can use commas to separate multiple recipients (e.g.: "test@example.com,test@example.com" or ["test@example.com", "test@example.com"]).
cc | Same as
To but for carbon copy
bcc | Same as To but for blind carbon copy
subject | Subject of the message.
html | HTML version of the message.
text | Text version of the message.
message | MIME string of the message. Make sure to use multipart/form-data to send this as a file upload.
attachment | File attachment. You can post multiple attachment values. Important: You must use multipart/form-data encoding when sending attachments. Also you can use {data: file, filename: filename} to define custom filename.
o:tag | Tag string. See Tagging for more information.
o:campaign | Id of the campaign the message belongs to. See um-campaign-analytics for details.
o:deliverytime | Desired time of delivery. See Date Format. Note: Messages can be scheduled for a maximum of 3 days in the future.
o:dkim | Enables/disabled DKIM signatures on per-message basis. Pass yes or no
o:testmode | Enables sending in test mode. Pass yes if needed. See Sending in Test Mode
o:tracking | Toggles tracking on a per-message basis, see Tracking Messages for details. Pass yes or no.
o:tracking-clicks | Toggles clicks tracking on a per-message basis. Has higher priority than domain-level setting. Pass yes, no or htmlonly.
o:tracking-opens | Toggles opens tracking on a per-message basis. Has higher priority than domain-level setting. Pass yes or no.
h:X-My-Header | h: prefix followed by an arbitrary value allows to append a custom MIME header to the message (X-My-Header in this case). For example, h:Reply-To to specify Reply-To address.
v:my-var | v: prefix followed by an arbitrary name allows to attach a custom JSON data to the message. See Attaching Data to Messages for more information.
- HTML/TEXT Example:
`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
` - MIME Example:
`js
mg.messages.create('sandbox-123.mailgun.org', {
from: "Excited User ",
to: ["test@example.com"],
subject: "Hello",
message: ""
})
.then(msg => console.log(msg)) // logs response data
.catch(err => console.error(err)); // logs any error
` - Messages with attachments:
- Node.js example of send file as an attachment
`js
const fsPromises = require('fs').promises;
const path = require('path');
const filepath = path.resolve(__dirname, '../test.pdf');
let messageParams = {
from: "Excited User ",
to: ["test@example.com"],
subject: "Test subject",
text: "Hello here is a file in the attachment"
} fsPromises.readFile(filepath)
.then(data => {
const file = {
filename: 'test-rename.pdf',
data
}
messageParams.attachment = file;
return mg.messages.create('sandbox-123.mailgun.org', messageParams);
})
.then(response => {
console.log(response);
})
`
- Node.js example of send multiple files as an attachment
`js
const fsPromises = require('fs').promises;
const path = require('path');
const filepath = path.resolve(__dirname, '../test.pdf');
const filepath1 = path.resolve(__dirname, '../test.jpg'); let messageParams = {
from: "Excited User ",
to: ["test@example.com"],
subject: "Test subject",
text: "Test message"
}
(async () =>{
try {
const firstFile = {
filename: 'test.pdf',
data: await fsPromises.readFile(filepath)
}
const secondFile = {
filename: 'test.jpg',
data: await fsPromises.readFile(filepath1)
}
messageParams.attachment = [firstFile, secondFile];
const result = await mg.messages.create('sandbox-123.mailgun.org', messageParams);
console.log(result);
} catch (error) {
console.error(error);
}
})()
`
- Node.js example of send file as inline image
`js
const fsPromises = require('fs').promises;
const path = require('path');
const filepath = path.resolve(__dirname, '../test.jpg');
let messageParams = {
from: "Excited User ",
to: ["test@example.com"],
subject: "Test subject",
html: '
Some extra text'
} fsPromises.readFile(filepath)
.then(data => {
const file = {
filename: 'test.jpg',
data
}
messageParams.inline = file;
return mg.messages.create('sandbox-123.mailgun.org', messageParams);
})
.then(response => console.log(response))
`
- Browser example of send file Before sending the file you need to somehow get the Blob of the file.
Usually can get it from the onChange event of input tag with type file.
`js
const handleFileSelected = async (event) => {
const files = Array.from(event.target.files)
const fileBuffer = await files[0];
}
` Then you can use the same approach as shown above for node.js apps.
`js
const file = {
filename: 'test.pdf',
data: fileBuffer
}; let messageParams = {
from: "Excited User ",
to: ["test@example.com"],
subject: "Test subject",
text: "Hello here is a file in the attachment",
attachment: file
};
const res = await mg.messages.create(DOMAIN, messageParams);
`
Promise returns:
`js
{
id: '<20151025002517.117282.79817@sandbox-123.mailgun.org>',
message: 'Queued. Thank you.'
}
`- #### retrieveStoredEmail
API Reference
mg.messages.retrieveStoredEmail(domain, storageKey) storageKey - Storage key from the email's associated events (Example: Accepted/Delivered events storage.key field). Mentioned events can be found on https://app.mailgun.com/ (Send -> logs).
Note: Storage keys are available for the duration of your domain's message retention policy.
Example:
`JS
mg.messages.retrieveStoredEmail('sandbox-123.mailgun.org', 'BABEAAeEDgPUyeFqr-tATLaCfYqyqvLpbg')
.then(storedEmail => console.log(storedEmail)) // logs response data
.catch(err => console.error(err)); // logs any error
` Promise returns:
`JS
{
'Content-Type': 'multipart/alternative; boundary="boundary_12345"',
From: 'postmaster@sandbox.mailgun.org',
'Message-Id': '<123.123@sandbox.mailgun.org>',
'Mime-Version': '1.0',
Subject: 'Hello',
To: 'foo@example.com',
'X-Mailgun-Deliver-By': 'Fri, 28 Nov 2025 18:02:00 +0000',
sender: 'postmaster@sandbox.mailgun.org',
recipients: 'foo@example.com',
from: 'postmaster@sandbox.mailgun.org',
subject: 'Hello',
'body-html': 'Test',
'body-plain': 'Testing some Mailgun awesomness!',
attachments: [],
'content-id-map': {},
'message-headers': [
['Mime-Version', '1.0'],
[
'Content-Type',
'multipart/alternative; boundary="boundary_12345'
],
['Subject', 'Hello'],
['From', 'postmaster@sandbox.mailgun.org'],
['To', 'foo@example.com'],
['X-Mailgun-Deliver-By', 'Fri, 28 Nov 2025 18:02:00 +0000'],
[
'Message-Id',
'<123.123@sandbox.mailgun.org>'
]
],
'stripped-html': 'Test',
'stripped-text': 'Testing some Mailgun awesomness!',
'stripped-signature': ''
}
`- ### resendEmail
API Reference
mg.messages.resendEmail(domain, storageKey, recipient) storageKey - Storage key from the email's associated events (Example: Accepted/Delivered events storage.key field). Mentioned events can be found on https://app.mailgun.com/ (Send -> logs).
Note: Storage keys are available for the duration of your domain's message retention policy.
recipient - Email address of the recipient(s). Supports friendly name format.
Example: "Bob ". Use commas to separate multiple recipients. Duplicate addresses are automatically ignored.
Example:
`JS
mg.messages.resendEmail(
'sandbox-123.mailgun.org',
'BABEAAeEDgPUyeFqr-tATLaCfYqyqvLpbg',
'foo@test.com, bar@test.com'
).then(resendStatus => console.log(resendStatus)) // logs response data
.catch(err => console.error(err)); // logs any error
` Promise returns:
`JS
{
id: '<20151025002517.117282.79817@sandbox-123.mailgun.org>',
message: 'Queued. Thank you.'
}
`- ### getMessagesQueueStatus
API Reference
mg.messages.getMessagesQueueStatus(domain) Example:
`JS
mg.messages.getMessagesQueueStatus('sandbox-123.mailgun.org')
.then(queueStatus => console.log(queueStatus)) // logs response data
.catch(err => console.error(err)); // logs any error
` Promise returns:
`JS
{
regular: {
is_disabled: false,
disabled: {
until: null,
reason: ''
}
},
scheduled: {
is_disabled: true,
disabled: {
until: new Date('2025-11-28T18:02:00Z'),
reason: 'High load'
}
}
}
`- ### clearMessagesQueue
Deletes all scheduled and undelivered mail from the domain queue.
mg.messages.getMessagesQueueStatus(domain, storageUrl) storageUrl - Mail's generated storage URL. e.g. https://storage-us-east4.api.mailgun.net/v3/example.com/envelopes. Can be found on https://app.mailgun.com/ (Send -> logs -> event). Allowed values:
storage-us-east4.api.mailgun.net, storage-us-west1.api.mailgun.net, and storage-europe-west1.api.mailgun.net. Example:
`JS
mg.messages.clearMessagesQueue('sandbox-123.mailgun.org', 'storage-us-east4.api.mailgun.net')
.then(result => console.log(result)) // logs response data
.catch(err => console.error(err)); // logs any error
` Promise returns:
`JS
{
message: "done"
}
`$3
Mailgun’s templates uses a fork of the very popular template engine handlebars.
To provide values for a substitution you need to use
h:X-Mailgun-Variables property in the message description. Make sure that this property is a JSON string like:
`JS
JSON.stringify({
title: "A title",
body: "The body"
})
` You can find few examples of how to use templates below.
- Providing values for title and slug variables to render in template
`JS
...
const {
title,
slug,
} = someDataSource; const mailgunData = {
from: 'mailer@example.com>',
to: 'recipient@example.com',
subject:
Email ${title},
template: 'name-of-the-template-you-made-in-mailgun-web-portal',
'h:X-Mailgun-Variables': JSON.stringify({ // be sure to stringify your payload
title,
slug,
}),
'h:Reply-To': 'reply-to@example.com',
}; try {
const response = await mailgun.messages.create(DOMAIN_NAME, mailgunData);
...
`- Providing an array of objects to render them in the template
`JS
...
const mailgunData = {
from: 'mailer@example.com>',
to: 'recipient@example.com',
subject: Email ${title},
template: 'name-of-the-another-template-you-made-in-mailgun-web-portal',
'h:X-Mailgun-Variables': JSON.stringify({
"arrayItems": [
{
"question": "test_question",
"answer": "test_answer"
},
{
"question": "test_question",
"answer": "test_answer"
}
]})
};
try {
const response = await mailgun.messages.create(DOMAIN_NAME, mailgunData);
...
`$3
Recipient Variables are custom variables that you define, which you can then reference in the message body. They give you the ability to send a custom message to each recipient while still using a single API Call.
`JS
...
const mailgunData = {
from: 'Example.com Mailer ',
to: ['me@example.com', 'you@example.com'],
subject: 'Recipient - %recipient.title%',
html: 'Here\'s %recipient.title% and link',
'recipient-variables': JSON.stringify({
'me@example.com': {
title: 'Me',
link: 'href-var',
},
'you@example.com': {
title: 'You',
link: 'slug-recipient-var-c',
},
}),
}; try {
const response = await mailgun.messages.create(DOMAIN_NAME, mailgunData);
...
`$3
Domains API manages domains, domain keys and DNS verification.- #### list
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.
mg.domains.list(query) Example:
`JS
mg.domains.list()
.then(domains => console.log(domains)) // logs array of domains
.catch(err => console.error(err)); // logs any error
` Promise returns: array of Domain instances
`JS
[{
name: 'testing.example.com',
require_tls: true,
skip_verification: true,
state: 'unverified',
wildcard: true
spam_action: 'disabled',
created_at: 'Sun, 19 Oct 2014 18:49:36 GMT',
smtp_password: undefined,
smtp_login: 'postmaster@testing.example.com',
type: 'custom',
receiving_dns_records: null,
sending_dns_records: null,
id: '697d01d38712cf0322bb24d1',
is_disabled: false,
web_prefix: 'test',
web_scheme: 'https',
use_automatic_sender_security: true
}]
` Query data may have next properties:
| Property | Description |
|:----------|:------------------------------------------------------|
| limit | Maximum number of records to return. (100 by default) |
| skip | Number of records to skip. (0 by default) |
| state | To only get domains with a specific state. Can be either active, unverified or disabled. |
| sort | Valid sort options are name which defaults to asc order, name:asc, or name:desc. If sorting is not specified domains are returned in reverse creation date order. |
| authority | To only get domains with a specific authority. If state is specified then only state filtering will be proceed |
| search | Search domains by the given partial or complete name. Does not support wildcards|
- #### get
Fetches representation of a domain that includes details about the domain's state and settings.
mg.domains.get(domain, query) Example:
`JS
mg.domains.get('testing.example.com', {
extended: true
})
.then(domain => console.log(domain)) // logs domain object
.catch(err => console.error(err)); // logs any error
` Query object may have next properties:
| Property | Description |
|:----------|:------------------------------------------------------|
| extended | Default to false. If set to true, domain payload will include dkim_host, mailfrom_host and pod |
| with_dns | Default to true, domain payload will include sending and receiving dns records payload|
Promise returns: Domain instance
`JS
{
name: 'testing.example.com',
require_tls: true,
skip_verification: true,
state: 'unverified',
wildcard: true,
spam_action: 'disabled',
created_at: new Date('Sun, 19 Oct 2014 18:49:36 GMT'),
smtp_password: undefined,
smtp_login: 'postmaster@testing.example.com',
type: 'custom',
receiving_dns_records: [ // may be null if with_dns is set to false.
{
is_active: true,
cached: [],
priority: '10',
record_type: 'TXT',
valid: "unknown",
value: "dns_record_value"
},
...
],
sending_dns_records: [ // may be null if with_dns is set to false.
{
is_active: true,
cached: [],
name: 'dns_record_name',
record_type: 'CNAME',
valid: 'unknown',
value: 'dns_record_value'
},
...
],
id: '697d01d38712cf0322bb24d1',
is_disabled: false,
web_prefix: 'email',
web_scheme: 'http',
use_automatic_sender_security: true,
dkim_host: 'dkim_host_value', // absent if 'extended' was not set to true.
mailfrom_host: 'mailfrom_host_value', // absent if 'extended' was not set to true.
}
`- #### create
Creates a domain for sending emails
mg.domains.create(data) Example:
`js
mg.domains.create({
name: 'foobar.example.com',
dkim_key_size: 1024,
dkim_selector: 's1',
encrypt_incoming_message: true,
force_dkim_authority: false,
force_root_dkim_host: false,
wildcard: true,
pool_id: 'pool_id',
ips: '',
spam_action: 'tag',
smtp_password: 'smtp_password_value',
use_automatic_sender_security: true,
web_prefix: 'test',
web_scheme: 'https',
})
.then(data => console.log(data)) // logs response data
.catch(err => console.error(err)); // logs any error
` Create method accepts data object with next properties:
| Parameter | Description |
|--- |--- |
| name (required) | Name of the domain (ex. domain.com) |
| dkim_host_name | Set the DKIM host name for the domain that is being created. Note, the value must be a valid domain name, and can be the domain name being created, a subdomain of the domain being created, or the root domain. This parameter cannot be used in conjunction with
force_dkim_authority or force_root_dkim_host. |
| dkim_key_size | 1024 or 2048
Set the length of your domain’s generated DKIM key
The default is 1024 |
| dkim_selector | Explicitly set the value of the DKIM selector for the domain being created. If the domain key does not already exist, one will be created. The selector must be a valid atom per RFC2822. e.g valid value foobar, invalid value foo.bar https://datatracker.ietf.org/doc/html/rfc2822#section-3.2.4|
| encrypt_incoming_message | Enable encrypting incoming messages for the given domain. This cannot be altered via API after being set for security purposes. Reach out to Support to disable if necessary. Default to false|
| force_dkim_authority| If set to true, the domain will be the DKIM authority for itself even if the root domain is registered on the same mailgun account. If set to false, the domain will have the same DKIM authority as the root domain registered on the same mailgun account. Default to false. |
| force_root_dkim_host | If set to true, the root domain will be the DKIM Host for the domain being created even if the root domain itself is not registered with Mailgun. The domain being created will still need to pass domain verification with valid spf records for the domain and valid DKIM record for the root domain. This does not effect the smtp mail-from host for the domain being created. The mail-from host will remain the domain name being created, not the root domain.|
| wildcard | Determines whether the domain will accept email for sub-domains when sending messages. Default to false. |
| pool_id | Requested IP Pool to be assigned to the domain at creation. |
| ips | An optional, comma-separated list of IP addresses to be assigned to this domain. If not specified, all dedicated IP addresses on the account will be assigned. If the request cannot be fulfilled (e.g. a requested IP is not assigned to the account, etc), a 400 will be returned. |
| spam_action | disabled, block, or tag
If disabled, no spam filtering will occur for inbound messages.
If block, inbound spam messages will not be delivered.
If tag, inbound messages will be tagged with a spam header. Spam Filter
The default is disabled. |
| smtp_password | Password for SMTP authentication |
| use_automatic_sender_security | Enable Automatic Sender Security. This requires setting DNS CNAME entries for DKIM keys instead of a TXT record. Defaults to false. |
| web_prefix | Sets your open, click and unsubscribe URLs domain name prefix. Links rewritten or added by Mailgun in your emails will look like ://./... Default to email |
| web_scheme |Sets your open, click and unsubscribe URLs to use http or https. Value either http or https. Defaults to http. In order for https to work, you must have a valid cert created for your domain. See Domain Tracking for TLS cert generation. | Promise returns:
`JS
{
name: 'foobar.example.com',
require_tls: false,
skip_verification: false,
state: 'unverified',
wildcard: true,
spam_action: 'tag',
created_at: 2025-01-08T12:52:29.000Z,
smtp_password: undefined,
smtp_login: new Date('postmaster@foobar.example.com'),
type: 'custom',
receiving_dns_records: [
{
is_active: true,
cached: [],
priority: '10',
record_type: 'MX',
valid: 'unknown',
value: 'dns_record_value'
},
...
],
sending_dns_records: [
{
is_active: false,
cached: [],
name: 'sending_dns_record_name',
record_type: 'CNAME',
valid: 'unknown',
value: 'sending_dns_record_value'
},
...
],
id: '64a4291ebbe4ec7e1d78bc80',
is_disabled: false,
web_prefix: 'test',
web_scheme: 'https',
use_automatic_sender_security: true
}
`- #### verify
Verify the domains DNS records (includes A, CNAME, SPF, DKIM and MX records) to ensure the domain is ready and able to send
mg.domains.verify(domainAddress) Example:
`JS
mg.domains.destroy('foobar.example.com')
.then(data => console.log(data)) // logs response data
.catch(err => console.error(err)); // logs any error
` Promise returns:
`JS
{
name: 'foobar.example.com',
require_tls: false,
skip_verification: false,
state: 'active',
wildcard: false,
spam_action: 'tag',
created_at: new Date('2017-10-05T14:55:20.000Z'),
smtp_password: undefined,
smtp_login: 'postmaster@foobar.example.com',
type: 'custom',
receiving_dns_records: [
{
is_active: true,
cached: [Array],
priority: '10',
record_type: 'MX',
valid: 'valid',
value: 'receiving_dns_record_value'
},
...
],
sending_dns_records: [
{
is_active: true,
cached: [],
name: 'foobar.example.com',
record_type: 'CNAME',
valid: 'unknown',
value: 'sending_dns_record_value'
},
...
],
id: '64a5880eere4eg7e1d85bc69',
is_disabled: false,
web_prefix: 'email',
web_scheme: 'https',
use_automatic_sender_security: true
}
`
- #### update
Update domains configuration like smtp credentials, enable/disable automatic sender security, spam actions, wildcard, or tracking web scheme.
mg.domains.update(domain, options) Example:
`js
mg.domains.update('foobar.example.com',{
mailfrom_host: 'mailfrom_host_value',
message_ttl: 20,
smtp_password: 'smtp_password_value'
spam_action: 'tag',
use_automatic_sender_security: true
web_scheme: 'http',
web_prefix: 'web_prefix_value'
wildcard: 'true',
})
.then(data => console.log(data)) // logs response data
.catch(err => console.error(err)); // logs any error
` Update method accepts data object with next properties:
| Property | Description |
|:--------------|:----------------------------------------------------------------------------------------------------------------------------------------------|
| mailfrom_host | The hostname to update to. Must be in lower case |
| message_ttl | Duration of the message retrieval TTL in seconds |
| smtp_password | Updates the domain's SMTP credentials with the given string |
| spam_action | Can be string with value
disabled, block, or tag. If disabled, no spam filtering will occur for inbound messages. If block, inbound spam messages will not be delivered. If tag, inbound messages will be tagged with a spam header. See Spam Filter.|
| use_automatic_sender_security | enable or disable Automatic Sender Security. If enabled, requires setting DNS CNAME entries for DKIM keys instead of a TXT record. Domain must be reverified after changing this field. Defaults to false|
| web_scheme | Can be string with value http or https. Set your open, click and unsubscribe URLs to use http or https. The default is http|
| web_prefix | Web prefix to be used for tracking. Must be a valid atom. Nothing will be updated if omitted |
| wildcard | Can be string 'true' or 'false' or boolean. Determines whether the domain will accept email for sub-domains. The default is false.| Promise returns:
`JS
{
name: 'foobar.example.com',
require_tls: false,
skip_verification: false,
state: 'unverified',
wildcard: true,
spam_action: 'disabled',
created_at: new Date('2025-01-08T12:52:29.000Z'),
smtp_password: undefined,
smtp_login: 'postmaster@foobar.example.com',
type: 'custom',
receiving_dns_records: [
{
is_active: true,
cached: [],
priority: '10',
record_type: 'MX',
valid: 'unknown',
value: 'receiving_dns_record_value'
},
...
],
sending_dns_records: [
{
is_active: true,
cached: [],
name: 'foobar.example.com',
record_type: 'TXT',
valid: 'unknown',
value: 'sending_dns_record_value'
},
...
],
id: '64a5880eere4eg7e1d85bc69',
is_disabled: false,
web_prefix: 'test',
web_scheme: 'https',
use_automatic_sender_security: true
}
`- #### destroy
The domain must not be disabled or used as an authority for an other domain. Sandbox domain can't be deleted.
mg.domains.destroy(domainAddress) Example:
`JS
mg.domains.destroy('foobar.example.com')
.then(data => console.log(data)) // logs response data
.catch(err => console.error(err)); // logs any error
` Promise returns message:
`JS
{
message: "Domain will be deleted in the background"
}
`- #### getTracking
domains.getTracking method is deprecated, and will be removed. Please use domains.domainTracking.getTracking instead.- #### updateTracking
domains.updateTracking method is deprecated, and will be removed. Please use domains.domainTracking.updateTracking instead.- #### getConnection
Deprecated, and will be removed in the future releases
Returns domain's delivery connection settings.
API Reference.GetDomainConnection-fm-14-0/)
mg.domains.getConnection(domainAddress) Example:
`JS
mg.domains.getConnection(domainAddress)
.then(data => console.log(data)) // logs response data
.catch(err => console.error(err)); // logs any error
` Promise returns:
`JS
{
require_tls: false,
skip_verification: false
}
`- #### updateConnection
Deprecated, and will be removed in the future releases
Update a domain's TLS connection settings.
API Reference.UpdateDomainConnection-fm-15-0/)
mg.domains.updateConnection(domainAddress, data) Example:
`JS
mg.domains.updateConnection(domainAddress, {
require_tls: true;
skip_verification: false;
})
.then(data => console.log(data)) // logs response data
.catch(err => console.error(err)); // logs any error
` Promise returns:
`JS
{
message: 'Domain connection settings have been updated, may take 10 minutes to fully propagate',
require_tls: false,
skip_verification: false
}
`- #### updateDKIMAuthority
domains.updateDKIMAuthority method is deprecated, and will be removed. Please use domains.domainKeys.updateDKIMAuthority instead.- #### updateDKIMSelector
domains.updateDKIMSelector method is deprecated, and will be removed. Please use domains.domainKeys.updateDKIMSelector instead.- #### getIps
Deprecated, and will be removed in the future releases
mg.domains.getIps(domain) Example:
`js
mg.domains.getIps('foobar.example.com')
.then(msg => console.log(msg)) // logs response data
.catch(err => console.error(err)); // logs any error
` Promise returns:
`JS
["192.168.0.1", "192.168.0.2"]
`- #### assignIp
Deprecated, and will be removed in the future releases
mg.domains.assignIp(domain, ip) Example:
`JS
mg.domains.assignIp('foobar.example.com', "192.168.0.3")
.then(msg => console.log(msg)) // logs response data
.catch(err => console.error(err)); // logs any error
`
`JS
{
message: 'success',
status: 200,
}
`- #### deleteIp
Deprecated, and will be removed in the future releases
mg.domains.deleteIp(domain, ip) Example:
`JS
mg.domains.deleteIp('foobar.example.com', "192.168.0.3")
.then(msg => console.log(msg)) // logs response data
.catch(err => console.error(err)); // logs any error
`
`JS
{
message: 'success'
}
`$3
- #### list
Returns a list of templates for the domain.
mg.domains.domainTemplates.list('domainId', query) Example:
`js
mg.domains.domainTemplates.list('domainId',{
limit: 10
})
.then(domainTemplates => console.log(domainTemplates)) // logs array of domain templates
.catch(err => console.error(err)); // logs any error
` Query data object may have next properties:
| Property | Description |
|:----------|:------------------------------------------------------|
| limit | Maximum number of records to return. (100 by default) |
| page | params from previous response's 'paging' object. Value must be stringified as query params. e.g. '?page=first','?page=next&p=name-of-last-item'|
Promise returns: object with domain's templates
`JS
{
items: [
{
name: 'template_name',
description: 'template description ',
createdAt: new Date('2021-08-24T22:26:55.000Z'),
createdBy: '',
id: '48d63154-8c8f-4104-ab14-687d01dbf296'
},
...
]
}
`- #### get
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.
mg.domains.domainTemplates.get('domainId', 'templateName', query) Example:
`js
mg.domains.domainTemplates.get('domainId', 'template_name', {
active: 'yes'
}).then(data => console.log(data)) // logs template
.catch(err => console.error(err)); // logs any error
` Query data object may have next properties:
| Property | Description |
|:----------|:------------------------------------------------------|
| active | If this flag is set to yes the active version of the template is included in the response. |
Promise returns: object with domain template and active version
`JS
{
name: 'template_name',
description: 'This is the description of the template',
createdAt: new Date('2021-08-24T22:26:55.000Z'),
createdBy: '',
id: '46565d87-68b6-4edb-8b3c-34554af4bb77'
version: {
tag: 'tag',
template: 'template content',
engine: 'handlebars',
mjml: '',
createdAt: new Date('2021-08-22T22:26:55.000Z'),
comment: 'Version comment',
active: true,
id: '3efd2b85-0f41-4a1d-9898-05d7e7459c4a',
headers: {
From: 'from value'
}
}
}
`- #### create
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.
mg.domains.domainTemplates.create(domainId, templateData) Example:
`js
mg.domains.domainTemplates.create('domainId', {
name: 'template_name',
createdBy: '',
tag: 'tag',
template: 'template content',
description: 'template description',
comment: 'Version comment',
headers: JSON.stringify({
From: 'from value'
}),
engine: 'handlebars'
}).then(data => console.log(data)) // logs created template
.catch(err => console.error(err)); // logs any error
` Template data object may have next properties:
| Property | Description |
|:----------|:------------------------------------------------------|
| name (required) | Name of the template being stored. Supports utf-8 characters and name will be down cased. |
| createdBy | Optional metadata field api user can indicate who created the template. |
| tag | Initial tag of the created version. If the template parameter is provided and the tag is missing, the default value initial is used. |
| template | Content of the template. |
| description | Description of the template being stored |
| comment | Version comment. This is valid only if a new version is being created. (template parameter is provided.) |
| headers | Key Value json dictionary of headers to be stored with the template. Where key is the header name and value is the header value. The header names From, Subject, and Reply-To are the only ones currently supported. These headers will be inserted into the mime at the time we attempt delivery.Headers set at the message level will override headers set on the template. e.g. Setting the From header at the time of sending will override the From header saved on the template. Additionally, headers generated by templates are not reflected on the accepted event as they are not prepended to the message until the message is prepped for delivery. if a From header is not provided either in the message or template, we will default to postmaster@your-sending-domain.tld |
| engine | The template engine to be used when rendering the template. Supported value are handlebars and go (golang template). The default if parameter is not provided is handlebars. |
Promise returns: created domain template and active version
`JS
{
name: 'template_name',
description: 'template description',
createdAt: new Date('2025-01-03T12:33:10.000Z'),
createdBy: '',
id: '46565d87-68b6-4edb-8b3c-34554af4bb77',
version: {
tag: 'tag',
template: 'template content',
engine: 'handlebars',
mjml: '',
createdAt: new Date('2025-01-03T12:33:10.000Z'),
comment: 'Version comment',
active: true,
id: '3efd2b85-0f41-4a1d-9898-05d7e7459c4a',
headers: { From: 'from value' }
}
}
`- #### update
Update the description of a template.
mg.domains.domainTemplates.update('domainId', 'templateName', data) Example:
`js
mg.domains.domainTemplates.update('domainId', 'templateName', {
description: 'new template description',
}).then(data => console.log(data)) // logs data
.catch(err => console.error(err)); // logs any error
` Data object may have next properties:
| Property | Description |
|:----------|:------------------------------------------------------|
| description | Update description of the template being updated. |
Promise returns:
`JS
{
status: 200,
message: 'template has been updated',
templateName: 'template_name'
}
`- #### destroy
Delete the template specified in the url. NOTE: This method deletes all versions of the specified template.
mg.domains.domainTemplates.destroy('domainId', 'templateName') Example:
`js
mg.domains.domainTemplates.destroy('domainId', 'templateName')
.then(data => console.log(data)) // logs data
.catch(err => console.error(err)); // logs any error
` Promise returns:
`JS
{
status: 200,
message: 'template has been deleted',
templateName: 'template_name'
}
`- #### destroyAll
Delete all templates and their versions for the domain.
mg.domains.domainTemplates.destroyAll('domainId') Example:
`js
mg.domains.domainTemplates.destroyAll('domainId')
.then(data => console.log(data)) // logs data
.catch(err => console.error(err)); // logs any error
` Promise returns:
`JS
{
status: 200,
message: "templates have been deleted"
}
`- #### listVersions
Returns a paginated list of template versions.
mg.domains.domainTemplates.listVersions('domainId', 'template_name', queryData) Example:
`js
mg.domains.domainTemplates.listVersions('domainId', 'template_name', {
limit: 10,
})
.then(data => console.log(data)) // logs data
.catch(err => console.error(err)); // logs any error
` Query data object may have next properties:
| Property | Description |
|:----------|:------------------------------------------------------|
| limit | Maximum number of records to return. (100 by default) |
| page | params from previous response's 'paging' object. Value must be stringified as query params. e.g. '?page=first','?page=next&p=name-of-last-item'|
Promise returns:
`JS
{
template: {
name: 'template_name',
description: 'template description',
createdAt: new Date('2025-01-03T12:33:10.000Z'),
createdBy: '',
id: '46565d87-68b6-4edb-8b3c-34554af4bb77',
versions: [
{
tag: 'tag',
engine: 'handlebars',
mjml: '',
createdAt: new Date('2025-01-03T12:33:10.000Z'),
comment: 'Version comment',
active: true,
id: 'b3f09533-a03f-4e10-9aac-a91115297b6c'
}
]
}
}
`- #### getVersion
Retrieve the information and content of the specified version of a template.
mg.domains.domainTemplates.getVersion('domainId', 'template_name', 'tag') Example:
`js
mg.domains.domainTemplates.getVersion('domainId', 'template_name','tag')
.then(data => console.log(data)) // logs data
.catch(err => console.error(err)); // logs any error
` Promise returns:
`JS
{
template: {
name: 'template_name',
description: 'template description',
createdAt: new Date('2025-01-03T12:33:10.000Z'),
createdBy: '',
id: '46565d87-68b6-4edb-8b3c-34554af4bb77',
versions: [
{
tag: 'tag',
template: 'template content',
engine: 'handlebars',
mjml: '',
createdAt: new Date('2025-01-03T12:33:10.000Z'),
comment: 'Version comment',
active: true,
id: 'b3f09533-a03f-4e10-9aac-a91115297b6c',
headers: {
From: 'from value'
}
}
]
}
}
`- #### createVersion
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.
mg.domains.domainTemplates.createVersion('domainId', 'template_name', versionData) Example:
`js
mg.domains.domainTemplates.createVersion('domainId', 'template_name',{
{
template: template content,
tag: 'v1',
engine: 'handlebars',
comment: 'comment',
active: 'yes',
headers: JSON.stringify({
From: 'from value'
})
}
})
.then(data => console.log(data)) // logs data
.catch(err => console.error(err)); // logs any error
` Template version data object may have next properties:
| Property | Description |
|:----------|:------------------------------------------------------|
| template | Content of the template. |
| tag | Initial tag of the created version. If the template parameter is provided and the tag is missing, the default value initial is used. |
| engine | The template engine to be used when rendering the template. Supported value are handlebars and go (golang template). The default if parameter is not provided is handlebars. |
| comment | Version comment. This is valid only if a new version is being created. (template parameter is provided.) |
| active | If this flag is set to yes, this version becomes active. |
| headers | Key Value json dictionary of headers to be stored with the template. Where key is the header name and value is the header value. The header names From, Subject, and Reply-To are the only ones currently supported. These headers will be inserted into the mime at the time we attempt delivery.Headers set at the message level will override headers set on the template. e.g. Setting the From header at the time of sending will override the From header saved on the template. Additionally, headers generated by templates are not reflected on the accepted event as they are not prepended to the message until the message is prepped for delivery. if a From header is not provided either in the message or template, we will default to postmaster@your-sending-domain.tld |
Promise returns:
`JS
{
status: 200,
message: 'new version of the template has been stored',
template: l {
name: 'template_name',
description: 'new template description',
createdAt: new Date('2025-01-03T12:33:10.000Z'),
createdBy: '',
id: '46565d87-68b6-4edb-8b3c-34554af4bb77',
version: {
tag: 'v1',
template: 'template content',
engine: 'handlebars',
mjml: '',
createdAt: new Date('2025-01-03T13:41:26.000Z'),
comment: 'comment',
active: true,
id: '3efd2b85-0f41-4a1d-9898-05d7e7459c4a',
headers: [Object]
}
}
}
`- #### updateVersion
Update information or content of the specific template version.
Existing fields not included in the request will not be changed
mg.domains.domainTemplates.updateVersion('domainId', 'template_name', 'tag' , versionData) Example:
`js
mg.domains.domainTemplates.updateVersion('domainId', 'template_name', 'v1',{
{
template: template content,
engine: 'handlebars',
comment: 'comment',
active: 'yes',
headers: JSON.stringify({
From: 'from value'
})
}
})
.then(data => console.log(data)) // logs data
.catch(err => console.error(err)); // logs any error
` Template version data object may have next properties:
| Property | Description |
|:----------|:------------------------------------------------------|
| template | Content of the template. |
| engine | The template engine to be used when rendering the template. Supported value are handlebars and go (golang template). The default if parameter is not provided is handlebars. |
| comment | Version comment. This is valid only if a new version is being created. (template parameter is provided.) |
| active | If this flag is set to yes, this version becomes active. |
| headers | Key Value json dictionary of headers to be stored with the template. Where key is the header name and value is the header value. The header names From, Subject, and Reply-To are the only ones currently supported. These headers will be inserted into the mime at the time we attempt delivery.Headers set at the message level will override headers set on the template. e.g. Setting the From header at the time of sending will override the From header saved on the template. Additionally, headers generated by templates are not reflected on the accepted event as they are not prepended to the message until the message is prepped for delivery. if a From header is not provided either in the message or template, we will default to postmaster@your-sending-domain.tld |
Promise returns:
`JS
{
status: 200,
message: 'version has been updated',
templateName: 'template_name',
templateVersion: {
tag: 'v1'
}
}
`- #### destroyVersion
Delete a specific template version.
mg.domains.domainTemplates.destroyVersion(domainId, templateName, tag) Example:
`js
mg.domains.domainTemplates.destroyVersion('domainId', 'template_name', 'v1')
.then(data => console.log(data)) // logs data
.catch(err => console.error(err)); // logs any error
`
Promise returns:
`JS
{
status: 200,
message: 'version has been deleted',
templateName: 'template_name',
templateVersion: {
tag:'v1'
}
}
`$3
- #### getTracking
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.
mg.domains.domainTracking.getTracking(domainAddress) Example:
``JS