Our email forwarding API
This is the documentation of our API endpoint at ImprovMX.com. This lets you list, create, edit and remove domains and email aliases that you can forward to programmatically.
Base URL
The base URL of ImprovMX’s API can be accessed at
This v3
has been released on April 30th, 2020. And we recommend you to update as soon as possible.
The v2
has been marked as deprecated and will be removed in June 1st.
Authentication
First, you need to retrieve your API Key by visiting the API page on your ImprovMX app dashboard.
Authentication is done via the “Basic auth mechanism”.
Simply pass the string “api” as the username and your API key as the password, like the following:
Authorization: Basic api:{your_api_key}
That’s it, you are now ready to communicate with our API!
Error codes
Here are the main error codes you will encounter:
Code | Description |
---|---|
200 | Success This means the request was successfully made |
400 | Bad Request This means you passed a wrong or missing parameter |
401 | Authentication required You tried to access an endpoint that requires authentication and you are not properly authenticated. |
403 | Forbidden You don’t have the permissions to access or edit this endpoint. For instance, a premium account or business account is required. |
500 | Server error This happens when we have a bug… Reach out to us and we’ll fix it 🙂 |
When an error occurs, you will always receive a JSON response in the body explaining in detail what was the reason for the failure. This should help you understand and adapt your subsequent requests accordingly.
For instance, here’s an example of a Bad Request
response returned by the server:
{
"errors": {
"email": [
"You cannot use your domain in your email."
]
},
"success": false
}
Account
GET /account/
Get the details about your ImprovMX account
GET /account/
Returns a JSON object like the following:
{
"account": {
"billing_email": null,
"cancels_on": null,
"card_brand": "Visa",
"company_details": "1 Decentralized Street\n92024-
2852 California",
"company_name": "PiedPiper Inc.",
"company_vat": null,
"country": "US",
"created": 1512139382000,
"email": "richard.hendricks@gmail.com",
"last4": "1234",
"limits": {
"aliases": 10000,
"daily_quota": 100000,
"daily_send": 200,
"domains": 10000,
"ratelimit": 10,
"redirections": 50,
"subdomains": 2,
"api": 3,
"credentials": 50,
"destinations": 5
},
"lock_reason": null,
"locked": null,
"password": true,
"plan": {
"aliases_limit": 10000,
"daily_quota": 100000,
"display": "Business - $249",
"domains_limit": 10000,
"kind": "enterprise",
"name": "enterprise249",
"price": 249,
"yearly": false
},
"premium": true,
"privacy_level": 1,
"renew_date": 15881622590000
},
"success": true
}
GET /account/whitelabels/
Get the list of whitelabel domain currently used by your domain
GET /account/whitelabels/
Returns a list of domains used as whitelabels for your account:
{
"whitelabels": [
{
"name": "piedpiper.com"
}
],
"success": true
}
Domains
GET /domains/
Retrieve a list of all your domains
GET /domains/
Parameter | Type | Required? | Description |
---|---|---|---|
q | String | False | Search the domains starting by this value. |
is_active | Boolean | False | Returns only active (1 ) or inactive (0 ) domains. |
limit | Integer | False | Number of domains returned. Default to 50. Allowed values between 5 and 100. |
page | Integer | False | Current page to load. 1-based (The first, default page is at page = 1). |
Note: We limit to 200 aliases returned in each domains in this endpoint. If your domain has more, we recommend you to use the “List aliases” endpoint!
Returns a JSON object like the following:
{
"domains": [
{
"active": true,
"domain": "google.com",
"display": "google.com",
"dkim_selector": "dkimprovmx",
"notification_email": null,
"webhook": null,
"whitelabel": null,
"added": 1559639697000,
"aliases": [
{
"created": 1702393755000,
"forward": "sergey@gmail.com",
"alias": "sergey",
"id": 1
},
{
"created": 1702393755000,
"forward": "larry@gmail.com",
"alias": "larry",
"id": 2
}
]
},
{
"active": true,
"domain": "facebook.com",
"display": "facebook.com",
"dkim_selector": "dkimprovmx",
"notification_email": null,
"whitelabel": null,
"added": 1559639727000,
"aliases": [
{
"created": 1702393755000,
"forward": "mark@facebook-mail.com",
"alias": "*",
"id": 3
}
]
},
{
"active": false,
"domain": "piedpiper.com",
"display": "piedpiper.com",
"dkim_selector": "dkimprovmx",
"notification_email": null,
"whitelabel": null,
"added": 1559639733000,
"aliases": [
{
"created": 1702393755000,
"forward": "richard.hendricks@gmail.com",
"alias": "richard",
"id": 4
},
{
"created": 1702393755000,
"forward": "jared.dunn@gmail.com",
"alias": "jared",
"id": 5
},
{
"created": 1702393755000,
"forward": "monica.hall@gmail.com",
"alias": "monica",
"id": 6
},
{
"created": 1702393755000,
"forward": "dinesh.chugtai@gmail.com",
"alias": "dinesh",
"id": 7
},
{
"created": 1702393755000,
"forward": "bertram.gilfoyle@gmail.com",
"alias": "bertram",
"id": 8
},
{
"created": 1702393755000,
"forward": "nelson.bighetti@gmail.com",
"alias": "nelson",
"id": 9
}
]
}
],
"total": 3,
"limit": 50,
"page": 1,
"success": true
}
You can also use the q
parameter to search domains that starts with the given value.
Eg:
GET /domains/?q=faceb
{
"domains": [
{
"active": true,
"domain": "facebook.com",
"display": "facebook.com",
"dkim_selector": "dkimprovmx",
"notification_email": null,
"webhook": null,
"whitelabel": null,
"added": 1559639727000,
"daily_quota": 500,
"aliases": [
{
"created": 1702393755000,
"forward": "mark@facebook-mail.com",
"alias": "*",
"id": 3
}
]
}
],
"total": 1,
"limit": 50,
"page": 1,
"success": true
}
POST /domains/
Adding a new domain
To add a new domain, send a POST request containing a JSON payload with the following parameters
POST /domains/ -H application/json {“domain”: “newdomain.com”}
Parameter | Type | Required? | Description |
---|---|---|---|
domain | String | True | Name of the domain |
notification_email | String | False | Email to send the notifications to. |
whitelabel | String | False | Parent’s domain that will be displayed for the DNS settings. |
When successful, the server will return the newly created domain as JSON response:
{
"domain": {
"active": false,
"domain": "newdomain.com",
"display": "newdomain.com",
"dkim_selector": "dkimprovmx",
"notification_email": null,
"whitelabel": null,
"added": 1559652806000,
"aliases": [
{
"forward": "contact@your-company.tld",
"alias": "*",
"id": 12
}
]
},
"success": true
}
GET /domains/:domain
Get the details of a domain
GET /domains/piedpiper.com
Note: We limit to 200 aliases returned in each domains in this endpoint. If your domain has more, we recommend you to use the “List aliases” endpoint!
Returns a JSON object like the following:
{
"domain": {
"active": false,
"domain": "piedpiper.com",
"added": 1559639733000,
"display": "piedpiper.com",
"dkim_selector": "dkimprovmx",
"notification_email": null,
"webhook": null,
"whitelabel": null,
"aliases": [
{
"created": 1702393755000,
"forward": "richard.hendricks@gmail.com",
"alias": "richard",
"id": 4
},
{
"created": 1702393755000,
"forward": "jared.dunn@gmail.com",
"alias": "jared",
"id": 5
},
{
"created": 1702393755000,
"forward": "monica.hall@gmail.com",
"alias": "monica",
"id": 6
},
{
"created": 1702393755000,
"forward": "dinesh.chugtai@gmail.com",
"alias": "dinesh",
"id": 7
},
{
"created": 1702393755000,
"forward": "bertram.gilfoyle@gmail.com",
"alias": "bertram",
"id": 8
},
{
"created": 1702393755000,
"forward": "nelson.bighetti@gmail.com",
"alias": "nelson",
"id": 9
}
]
},
"success": True
}
PUT /domains/:domain
This endpoint allows you to edit a domain by modifying the notification email used for technical communication, receive emails events as POST request to your defined endpoint, or customize your whitelabel DNS entries.
It’s not possible to change the domain name.
PUT /domains/piedpiper.com -H application/json {“notification_email”: “email@example.com”, “webhook”: “https://requestbin.com/r/enbwnegkb25v”, “whitelabel”: “hooli.com”}
Parameter | Type | Required? | Description |
---|---|---|---|
notification_email | String (email) | False | Email where the notifications related to this domain will be sent. |
webhook | String (URL) | False | URL where the email events related to this domain will be sent. |
whitelabel | String | False | The parent’s domain owner. |
When successful, the response will contain the following details:
{
"domain": {
"active": false,
"domain": "piedpiper.com",
"added": 1559639733000,
"display": "piedpiper.com",
"dkim_selector": "dkimprovmx",
"notification_email": "email@example.com",
"webhook": "https://requestbin.com/r/enbwnegkb25v",
"whitelabel": "hooli.com",
"aliases": [
{
"forward": "richard.hendricks@gmail.com",
"alias": "richard",
"id": 4
},
{
"forward": "jared.dunn@gmail.com",
"alias": "jared",
"id": 5
},
{
"forward": "monica.hall@gmail.com",
"alias": "monica",
"id": 6
},
{
"forward": "dinesh.chugtai@gmail.com",
"alias": "dinesh",
"id": 7
},
{
"forward": "bertram.gilfoyle@gmail.com",
"alias": "bertram",
"id": 8
},
{
"forward": "nelson.bighetti@gmail.com",
"alias": "nelson",
"id": 9
}
]
},
"success": True
}
DELETE /domains/:domain
Delete a given domain
DELETE /domains/piedpiper.com
{
"success": true
}
GET /domains/:domain/check
Check if the MX entries are valid for a domain
GET /domains/piedpiper.com/check
{
"records": {
"provider": "cloudflare",
"advanced": true,
"dkim1": {
"expected": "dkimprovmx1.improvmx.com.",
"valid": true,
"values": "dkimprovmx1.improvmx.com."
},
"dkim2": {
"expected": "dkimprovmx2.improvmx.com.",
"valid": true,
"values": "dkimprovmx2.improvmx.com."
},
"dmarc": {
"expected": "v=DMARC1; p=none;",
"valid": false,
"values": null
},
"error": null,
"mx": {
"expected": [
"mx1.improvmx.com",
"mx2.improvmx.com"
],
"valid": true,
"values": [
"mx2.improvmx.com",
"mx1.improvmx.com"
]
},
"spf": {
"expected": "v=spf1 include:someservice.org include:spf.improvmx.com ~all",
"valid": false,
"values": "v=spf1 include:someservice.org ~all"
},
"valid": false
},
"success": true
}
The endpoint will return true
in success when the MX are well configured, false
otherwise.
error
might contain a specific reason why the entries are not valid.
Aliases
GET /domains/:domain/aliases/
List aliases for a given domain
GET /domains/piedpiper.com/aliases/
Parameter | Type | Required? | Description |
---|---|---|---|
q | String | False | Search (both alias and destination) starting by this value. |
alias | String | False | Search only the alias value that starts with the given value. |
is_active | Boolean | False | Returns only active (1 ) or inactive (0 ) domains. |
page | Integer | False | Current page to load. 1-based (The first, default page is at page = 1). |
This will return the following JSON response:
{
"aliases": [
{
"created": 1702982672000,
"forward": "richard.hendricks@gmail.com",
"alias": "richard",
"id": 4
},
{
"created": 1702982672000,
"forward": "jared.dunn@gmail.com",
"alias": "jared",
"id": 5
},
{
"created": 1702982672000,
"forward": "monica.hall@gmail.com",
"alias": "monica",
"id": 6
},
{
"created": 1702982672000,
"forward": "dinesh.chugtai@gmail.com",
"alias": "dinesh",
"id": 7
},
{
"created": 1702982672000,
"forward": "bertram.gilfoyle@gmail.com",
"alias": "bertram",
"id": 8
}
],
"limit": 5,
"page": 1,
"total": 6,
"success": true
}
POST /domains/:domain/aliases/
Add a new alias to a given domain
POST /domains/piedpiper.com/aliases/ -H application/json {“alias”: “richard”, “forward”: “richard.hendricks@gmail.com”}
Parameter | Type | Required? | Description |
---|---|---|---|
alias | String | True | Alias to be used in front of your domain, like “contact”, “info”, etc |
forward | String (email) | True | Destination email to forward the emails to |
{
"alias": {
"forward": "richard.hendricks@gmail.com",
"alias": "richard",
"id": 11
},
"success": true
}
GET /domains/:domain/aliases/:alias
Get the details of a given alias
{
"alias": {
"created": 1702982672000,
"forward": "richard.hendricks@protonmail.com",
"alias": "richard",
"id": 11
},
"success": true
}
PUT /domains/:domain/aliases/:alias
Update a given alias
PUT /domains/piedpiper.com/aliases/richard -H application/json {“forward”: “richard.hendricks@protonmail.com”}
Parameter | Type | Required? | Description |
---|---|---|---|
forward | String (email) | True | Destination email to forward the emails to |
{
"alias": {
"forward": "richard.hendricks@protonmail.com",
"alias": "richard",
"id": 11
},
"success": true
}
You can also update an alias based on the “id” which is generated by our system when an alias is created
PUT /domains/piedpiper.com/aliases/11 -H application/json {“alias”: “richardhendricks”, “forward”: “richardhendricks@gmail.com“}
Parameter | Type | Required? | Description |
---|---|---|---|
alias | String | False | Alias to be used in front of your domain, like “contact”, “info”, etc |
forward | String (email) | False | Destination email to forward the emails to |
{
"alias": {
"forward": "richardhendricks@gmail.com",
"alias": "richardhendricks",
"id": 11
},
"success": true
}
DELETE /domains/:domain/aliases/:alias
Delete the given alias
DELETE /domains/piedpiper.com/aliases/nelson
{
"success": true
}
POST /domains/:domain/aliases/bulk
Add aliases in bulk for a given domain
POST /domains/piedpiper.com/aliases/bulk
Parameter | Type | Required? | Description |
---|---|---|---|
aliases | Array | True | An array containing a list of up to 500 objects with “alias” (your alias) and “forward” (the destination email) |
behavior | String | False | Setting it to “add” (default) will cause the request to fail if the alias already exists. Setting to “update” will update an existing alias. |
Example:
{
"aliases": [
{
"forward": "richard.hendricks@gmail.com",
"alias": "richard"
},
{
"forward": "jared.dunn@gmail.com",
"alias": "jared"
},
{
"forward": "monica.hall@gmail.com",
"alias": "monica"
},
{
"forward": "dinesh.chugtai@gmail.com",
"alias": "dinesh"
},
{
"forward": "bertram.gilfoyle@gmail.com",
"alias": "bertram"
}
],
"behavior": "update"
}
Returns a JSON object like the following:
{
"added": [
{
"alias": "richard",
"forward": "richard.hendricks@gmail.com",
"id": 12345
},
{
"alias": "jared",
"forward": "jared.dunn@gmail.com",
"id": 12346
}
],
"failed": [
{
"alias": "monica",
"forward": "monica.hall@gmail.com",
"id": 12347
}
],
"success": true,
"updated": [
{
"alias": "dinesh",
"forward": "dinesh.chugtai@gmail.com",
"id": 12348
},
{
"alias": "bertram",
"forward": "bertram.gilfoyle@gmail.com",
"id": 12349
}
]
}
Logs
GET /domains/:domain/logs
Retrieve the logs for a given domain
GET /domains/piedpiper.com/logs
Parameter | Type | Required? | Description |
---|---|---|---|
next_cursor | String | False | Loads the logs after the given log.id. (Like “20201002014128.7ea8ee59fa894aa7a91415a6659c5b46”) |
Returns a JSON object like the following:
{
"logs": [
{
"created": "2020-01-25 12:19:09+0000",
"created_raw": "Sat, 25 Jan 2020 12:19:09 GMT",
"events": [
{
"code": 250,
"created": "2020-01-25 12:19:11+0000",
"id": "some_random_id",
"local": "mxb.infra.improvmx.com",
"message": "Queued",
"server": "mail-io1-f54.google.com",
"status": "QUEUED"
},
{
"code": 250,
"created": "2020-01-25 12:19:12+0000",
"id": "some_random_id",
"local": "gmail-smtp-in.l.google.com",
"message": "Sent.",
"server": "mail16.mxc.infra.improvmx.com",
"status": "DELIVERED"
}
],
"forward": {
"email": "richard.hendricks@gmail.com",
"name": "Richard Hendricks"
},
"hostname": "mail-io1-f54.google.com",
"id": "20201002014128.5ea8ee59fa894aa7a9141e9665985b46",
"messageId": "some_random_id",
"recipient": {
"email": "richard@piedpiper.com",
"name": "Richard Hendricks"
},
"sender": {
"email": "gavin@hooli.com",
"name": "Gavin Belsonx"
},
"subject": "You are screwed, Piedpiper team!",
"transport": "smtp"
},
{
"created": "2020-01-25 12:18:46+0000",
"created_raw": "Sat, 25 Jan 2020 12:18:46 GMT",
"events": [
{
"code": 250,
"created": "2020-01-25 12:18:47+0000",
"id": "another_random_id",
"local": "mxb.infra.improvmx.com",
"message": "Queued",
"server": "mail-pj1-f54.google.com",
"status": "QUEUED"
},
{
"code": 250,
"created": "2020-01-25 12:18:47+0000",
"id": "another_random_id",
"local": "gmail-smtp-in.l.google.com",
"message": "Sent.",
"server": "mail15.mxb.infra.improvmx.com",
"status": "DELIVERED"
}
],
"forward": {
"email": "monica.hall@gmail.com",
"name": "Monica Hall"
},
"hostname": "mail-pj1-f54.google.com",
"messageId": "another_random_id",
"recipient": {
"email": "monica@piedpiper.com",
"name": "Monica Hall"
},
"sender": {
"email": "russ@threecommas.com",
"name": "Russ Hanneman"
},
"subject": "Series A, bitches!",
"transport": "smtp"
},
{
"created": "2020-01-25 11:30:41+0000",
"created_raw": "Sat, 25 Jan 2020 11:30:41 GMT",
"events": [
{
"code": 550,
"created": "2020-01-25 11:30:42+0000",
"id": "yet_another_random_id",
"local": "mxa.infra.improvmx.com",
"message": "5.7.1 Message considered as SPAM (Score of 5.8/5.0 with BAYES_20, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, HTML_MESSAGE, HTML_TAG_BALANCE_BODY, MIME_HEADER_CTYPE_ONLY, NO_RELAYS, URIBL_ABUSE_SURBL, URIBL_DBL_ABUSE_SPAM, URIBL_DBL_SPAM)",
"server": "mail-wm1-f67.google.com",
"status": "REFUSED"
}
],
"forward": null,
"hostname": "mail-wm1-f67.google.com",
"id": "20201002014128.7ea8ee59fa894aa7a91415a6659c5b46",
"messageId": "yet_another_random_id",
"recipient": {
"email": "richard@piedpiper.com",
"name": null
},
"sender": {
"email": "spam@hooli.com",
"name": "ThinkTeam"
},
"subject": "Enlarge your (pied)piper!",
"transport": "smtp"
}
],
"success": true
}
The logs array will contain all the processed emails. Each entry in the array will contain a list of events, related to all the actions taken by the ImprovMX servers, which are:
QUEUED | The email was accepted to be processed |
REFUSED | The email was refused at the SMTP connection |
DELIVERED | The email was successfully delivered to the end destination |
SOFT-BOUNCE | The end destination refused the email temporarily. We will try again multiple time with increased delay in between. |
HARD-BOUNCE | The end destination couldn’t accept the email definitively. |
GET /domains/:domain/logs/:alias
Retrieve the logs for a given alias in a given domain
GET /domains/piedpiper.com/logs/richard
Parameter | Type | Required? | Description |
---|---|---|---|
next_cursor | String | False | Loads the logs after the given log.id. (Like “20201002014128.7ea8ee59fa894aa7a91415a6659c5b46”) |
This behaves similarly as the general logs but returns results only for the requested alias.
{
"logs": [
{
"created": "2020-01-25 12:19:09+0000",
"created_raw": "Sat, 25 Jan 2020 12:19:09 GMT",
"events": [
{
"code": 250,
"created": "2020-01-25 12:19:11+0000",
"id": "some_random_id",
"local": "mxb.infra.improvmx.com",
"message": "Queued",
"server": "mail-io1-f54.google.com",
"status": "QUEUED"
},
{
"code": 250,
"created": "2020-01-25 12:19:12+0000",
"id": "some_random_id",
"local": "gmail-smtp-in.l.google.com",
"message": "Sent.",
"server": "mail16.mxc.infra.improvmx.com",
"status": "DELIVERED"
}
],
"forward": {
"email": "richard.hendricks@gmail.com",
"name": "Richard Hendricks"
},
"hostname": "mail-io1-f54.google.com",
"id": "20201002014128.5ea8ee59fa894aa7a9141e9665985b46",
"messageId": "some_random_id",
"recipient": {
"email": "richard@piedpiper.com",
"name": "Richard Hendricks"
},
"sender": {
"email": "gavin@hooli.com",
"name": "Gavin Belsonx"
},
"subject": "You are screwed, Piedpiper team!",
"transport": "smtp"
},
{
"created": "2020-01-25 11:30:41+0000",
"created_raw": "Sat, 25 Jan 2020 11:30:41 GMT",
"events": [
{
"code": 550,
"created": "2020-01-25 11:30:42+0000",
"id": "yet_another_random_id",
"local": "mxa.infra.improvmx.com",
"message": "5.7.1 Message considered as SPAM (Score of 5.8/5.0 with BAYES_20, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, HTML_MESSAGE, HTML_TAG_BALANCE_BODY, MIME_HEADER_CTYPE_ONLY, NO_RELAYS, URIBL_ABUSE_SURBL, URIBL_DBL_ABUSE_SPAM, URIBL_DBL_SPAM)",
"server": "mail-wm1-f67.google.com",
"status": "REFUSED"
}
],
"forward": null,
"id": "20201002014128.7ea8ee59fa894aa7a91415a6659c5b46",
"hostname": "mail-wm1-f67.google.com",
"messageId": "yet_another_random_id",
"recipient": {
"email": "richard@piedpiper.com",
"name": null
},
"sender": {
"email": "spam@hooli.com",
"name": "ThinkTeam"
},
"subject": "Enlarge your (pied)piper!",
"transport": "smtp"
}
],
"success": true
}
SMTP Credentials
This is a premium feature
GET /domains/:domain/credentials/
Returns a list of SMTP accounts for the given domain
GET /domains/piedpiper.com/credentials/
{
"credentials": [
{
"created": 1581604970000,
"usage": 0,
"username": "richard"
},
{
"created": 1581607028000,
"usage": 0,
"username": "monica"
}
],
"success": true
}
POST /domains/:domain/credentials/
Add a new SMTP account to send emails.
POST /domains/piedpiper.com/credentials/ -H application/json {“username”: “bighead”, “password”: “12341234”}
Parameter | Type | Required? | Description |
---|---|---|---|
username | True | String | Left part of the mailbox, like bighead for the email bighead@piedpiper.com |
password | True | String | The password for this account. |
{
"credential": {
"created": 1588236952000,
"usage": 0,
"username": "bighead"
},
"requires_new_mx_check": false,
"success": true
}
The indicator requires_new_mx_check
will be set to True
when you create your first SMTP credential.
When setting an domain for setting, we require two new CNAME
entry in your DNS for this domain used for DKIM signature. If these entries are not set, your domain will be marked as invalid until they are added.
PUT /domains/:domain/credentials/:username
Changes the password for the given user.
PUT /domains/piedpiper.com/credentials/bighead -H application/json {“password”: “R3@l_p@$$w0rD”}
The server will respond with the following JSON
{
"credential": {
"created": 1588236952000,
"usage": 0,
"username": "bighead"
},
"success": true
}
DELETE /domains/:domain/credentials/:username
Deletes the given SMTP user.
DELETE /domains/piedpiper.com/credentials/russ
The server will respond with a successful message:
{
"success": true
}