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

https://api.improvmx.com/v3/

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:

CodeDescription
200Success
This means the request was successfully made
400Bad Request
This means you passed a wrong or missing parameter
401Authentication required
You tried to access an endpoint that requires authentication and you are not properly authenticated.
403Forbidden
You don’t have the permissions to access or edit this endpoint. For instance, a premium account or business account is required.
500Server 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,
            "domains": 10000,
            "ratelimit": 10,
            "redirections": 50,
            "subdomains": 2
        },
        "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 whiltelabels for your account:

{
    "whitelabels": [
        {
            "name": "piedpiper.com"
        }
    ],
    "success": true
}

Domains

GET /domains/

Retrieve a list of all your domains

GET /domains/

ParameterTypeRequired?Description
qStringFalseSearch the domains starting by this value.
is_activeBooleanFalseReturns only active (1) or inactive (0) domains.
limitIntegerFalseNumber of domains returned. Default to 50. Allowed values between 5 and 100.
pageIntegerFalseCurrent 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,
            "whitelabel": null,
            "added": 1559639697000,
            "aliases": [
                {
                    "forward": "sergey@gmail.com", 
                    "alias": "sergey", 
                    "id": 1
                },
                {
                    "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": [
                {
                    "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": [
                {
                    "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
                }
            ]
        }
    ], 
    "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,
            "whitelabel": null,
            "added": 1559639727000, 
            "daily_quota": 500, 
            "aliases": [
                {
                    "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”}

ParameterTypeRequired?Description
domainStringTrueName of the domain
notification_emailStringFalseEmail to send the notifications to.
whitelabelStringFalseParent’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,
        "whitelabel": null,
        "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
}

PUT /domains/:domain

This endpoint allows you to edit a domain by modifying the notification email or the whitelabel entries.

It’s not possible to change the domain name.

PUT /domains/piedpiper.com -H application/json {“whitelabel”: “hooli.com”}

ParameterTypeRequired?Description
notification_emailStringFalseEmail where the notifications related to this domain will be sent.
whitelabelStringFalseThe 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": null,
        "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/

ParameterTypeRequired?Description
qStringFalseSearch the domains starting by this value.
is_activeBooleanFalseReturns only active (1) or inactive (0) domains.
pageIntegerFalseCurrent page to load. 1-based (The first, default page is at page = 1).

This will return the following JSON response:

{
    "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
        }
    ],
    "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“}

ParameterTypeRequired?Description
aliasStringTrueAlias to be used in front of your domain, like “contact”, “info”, etc
forwardString (email)TrueDestination 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

GET /domains/:domain/aliases/:alias

{
    "alias": {
        "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“}

ParameterTypeRequired?Description
forwardString (email)TrueDestination email to forward the emails to
{
    "alias": {
        "forward": "richard.hendricks@protonmail.com", 
        "alias": "richard", 
        "id": 11
    }, 
    "success": true
}

DELETE /domains/:domain/aliases/:alias

Delete the given alias

DELETE /domains/piedpiper.com/aliases/nelson

{
    "success": true
}

Logs

GET /domains/:domain/logs

Retrieve the logs for a given domain

GET /domains/piedpiper.com/logs

ParameterTypeRequired?Description
next_cursorStringFalseLoads 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:

QUEUEDThe email was accepted to be processed
REFUSEDThe email was refused at the SMTP connection
DELIVEREDThe email was successfully delivered to the end destination
SOFT-BOUNCEThe end destination refused the email temporarily. We will try again multiple time with increased delay in between.
HARD-BOUNCEThe 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

ParameterTypeRequired?Description
next_cursorStringFalseLoads 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”}

ParameterTypeRequired?Description
usernameTrueStringLeft part of the mailbox, like bighead for the email bighead@piedpiper.com
passwordTrueStringThe 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
}