API Reference Guide

This is the documentation for ImprovMX HTTP REST API endpoints, which let you fully programmatically manage your domains and aliases for email forwarding.

Base URL

The base URL is: https://api.improvmx.com/v3

The v3 api was released on April 30th, 2020.

The v2 api has been marked as deprecated and was removed on June 1st 2024.

Authentication

First, retrieve your API Key from the API page of the ImprovMX app dashboard.

Authentication is done via basic access authentication.

Pass the string api as the username and your API key as the password, like in the following curl request:

export API_KEY="your_api_key_here"
curl https://api.improvmx.com/v3/domains \
  -H "Authorization: Basic api:$API_KEY"

Error codes

Here are the main error codes you will encounter:

CODE DESCRIPTION
200 Success - The request was successful.
400 Bad Request - You passed an incorrect or missing parameter.
401 Authentication required - You tried to access an endpoint that requires authentication but you are not properly authenticated.
403 Forbidden - You don't have permissions to access or edit this endpoint, e.g. a premium account is required.
500 Server error - We ran into 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 the reason for the failure. This should help you understand and fix your subsequent requests.

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 details

GET /account

curl -X GET https://api.improvmx.com/v3/account \
  -H "Authorization: Basic api:$API_KEY"

Returns JSON 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": "[email protected]",
        "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
}

List whitelabel domains

GET /account/whitelabels

Retrieves the list of whitelabels for your domain.

curl -X GET https://api.improvmx.com/v3/account/whitelabels \
  -H "Authorization: Basic api:$API_KEY"

Returns JSON like the following:

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

Domains

List domains

GET /domains

curl -X GET https://api.improvmx.com/v3/domains \
  -H "Authorization: Basic api:$API_KEY"
PARAMETER TYPE REQUIRED? DESCRIPTION
q String False Search the domains starting from this value.
is_active Boolean False Returns only active (1) or inactive (0) domains.
limit Integer False Number of domains returned. Defaults 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 this endpoint to 200 aliases per domain. If your domain has more aliases, we recommend the list aliases endpoint.

Returns JSON 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": "[email protected]",
                    "alias": "sergey",
                    "id": 1
                },
                {
                    "created": 1702393755000,
                    "forward": "[email protected]",
                    "alias": "larry",
                    "id": 2
                }
            ]
        },
        {
            "active": false,
            "domain": "piedpiper.com",
            "display": "piedpiper.com",
            "dkim_selector": "dkimprovmx",
            "notification_email": null,
            "whitelabel": null,
            "added": 1559639733000,
            "aliases": [
                {
                    "created": 1702393755000,
                    "forward": "[email protected]",
                    "alias": "richard",
                    "id": 4
                },
                {
                    "created": 1702393755000,
                    "forward": "[email protected]",
                    "alias": "jared",
                    "id": 5
                }
            ]
        }
    ],
    "total": 3,
    "limit": 50,
    "page": 1,
    "success": true
}

You can also use the q parameter to search for domains that start with the given value.

curl -X GET https://api.improvmx.com/v3/domains?q=pied \
  -H "Authorization: Basic api:$API_KEY"

Returns JSON like the following:

{
    "domains": [
        {
            "active": true,
            "domain": "piedpiper.com",
            "display": "piedpiper.com",
            "dkim_selector": "dkimprovmx",
            "notification_email": null,
            "webhook": null,
            "whitelabel": null,
            "added": 1559639727000,
            "daily_quota": 500,
            "aliases": [
                {
                    "created": 1702393755000,
                    "forward": "[email protected]",
                    "alias": "*",
                    "id": 3
                }
            ]
        }
    ],
    "total": 1,
    "limit": 50,
    "page": 1,
    "success": true
}

Add domain

POST /domains

curl -X POST https://api.improvmx.com/v3/domains \
  -H "Authorization: Basic api:$API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"domain": "piedpiper.com"}'
PARAMETER TYPE REQUIRED? DESCRIPTION
domain String True Name of the domain
notification_email String False Email to send notifications to.
whitelabel String False Parent's domain that will be displayed for the DNS settings.

Returns JSON like the following:

{
    "domain": {
        "active": false,
        "domain": "piedpiper.com",
        "display": "piedpiper.com",
        "dkim_selector": "dkimprovmx",
        "notification_email": null,
        "whitelabel": null,
        "added": 1559652806000,
        "aliases": [
            {
                "forward": "[email protected]",
                "alias": "*",
                "id": 12
            }
        ]
    },
    "success": true
}

Get domain

GET /domains/:domain

curl -X GET https://api.improvmx.com/v3/domains/piedpiper.com \
  -H "Authorization: Basic api:$API_KEY"

Note: We limit this endpoint to 200 aliases per domain. If your domain has more aliases, we recommend the list aliases endpoint.

Returns JSON 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": "[email protected]",
                "alias": "richard",
                "id": 4
            },
            {
                "created": 1702393755000,
                "forward": "[email protected]",
                "alias": "jared",
                "id": 5
            }
        ]
    },
    "success": true
}

Update domain

PUT /domains/:domain

NOTE: It's not possible to change the domain name.

curl -X PUT https://api.improvmx.com/v3/domains/piedpiper.com \
  -H "Authorization: Basic api:$API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"notification_email": "[email protected]",
       "webhook": "https://requestbin.com/r/abc123",
       "whitelabel": "hooli.com"}'
PARAMETER TYPE REQUIRED? DESCRIPTION
notification_email String (email) False Email where notifications related to the domain will be sent
webhook String (URL) False URL where email events related to this domain will be sent
whitelabel String False The parent's domain owner

Returns JSON like the following:

{
    "domain": {
        "active": false,
        "domain": "piedpiper.com",
        "added": 1559639733000,
        "display": "piedpiper.com",
        "dkim_selector": "dkimprovmx",
        "notification_email": "[email protected]",
        "webhook": "https://requestbin.com/r/enbwnegkb25v",
        "whitelabel": "hooli.com",
        "aliases": [
            {
                "forward": "[email protected]",
                "alias": "richard",
                "id": 4
            },
            {
                "forward": "[email protected]",
                "alias": "jared",
                "id": 5
            }
        ]
    },
    "success": true
}

Delete domain

DELETE /domains/:domain

curl -X DELETE https://api.improvmx.com/v3/domains/piedpiper.com \
  -H "Authorization: Basic api:$API_KEY"

Returns JSON like the following:

{
    "success": true
}

Check MX of domain

GET /domains/:domain/check

curl -X GET https://api.improvmx.com/v3/domains/piedpiper.com/check \
  -H "Authorization: Basic api:$API_KEY"

Returns JSON like the following:

{
    "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 success: true when MX entries are well configured, success: false otherwise.

error may contain a reason why the entries are not valid.

Aliases

List aliases

GET /domains/:domain/aliases

curl -X GET https://api.improvmx.com/v3/domains/piedpiper.com/aliases \
  -H "Authorization: Basic api:$API_KEY"
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.
page Integer False Current page to load. 1-based (The first, default page is at page = 1).

Returns JSON like the following:

{
    "aliases": [
        {
            "created": 1702982672000,
            "forward": "[email protected]",
            "alias": "richard",
            "id": 4
        },
        {
            "created": 1702982672000,
            "forward": "[email protected]",
            "alias": "jared",
            "id": 5
        }
    ],
    "limit": 5,
    "page": 1,
    "total": 2,
    "success": true
}

Add alias

POST /domains/:domain/aliases

curl -X POST https://api.improvmx.com/v3/domains/piedpiper.com/aliases \
  -H "Authorization: Basic api:$API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"alias": "richard",
       "forward": "[email protected]"}'
PARAMETER TYPE REQUIRED? DESCRIPTION
alias String True Alias to be used in front of your domain, like "contact", "info", etc.
forward String (email) True Comma separated destination email(s) and/or webhooks to forward emails to.

Returns JSON like the following:

{
    "alias": {
        "forward": "[email protected]",
        "alias": "richard",
        "id": 11
    },
    "success": true
}

Get alias

GET /domains/:domain/aliases/:alias

NOTE: alias can be the string (richard) or the int id (11) returned at alias creation time.

curl -X GET https://api.improvmx.com/v3/domains/piedpiper.com/aliases/richard \
  -H "Authorization: Basic api:$API_KEY"

Returns JSON like the following:

{
    "alias": {
        "created": 1702982672000,
        "forward": "[email protected]",
        "alias": "richard",
        "id": 11
    },
    "success": true
}

Update alias

PUT /domains/:domain/aliases/:alias

NOTE: alias can be the string (richard) or the int id (11) returned at alias creation time.

curl -X PUT https://api.improvmx.com/v3/domains/piedpiper.com/aliases/richard \
  -H "Authorization: Basic api:$API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"forward": "[email protected]"}'
PARAMETER TYPE REQUIRED? DESCRIPTION
forward String (email) True Comma separated destination email(s) and/or webhooks to forward emails to.

Returns JSON like the following:

{
    "alias": {
        "forward": "[email protected]",
        "alias": "richard",
        "id": 11
    },
    "success": true
}

Delete alias

DELETE /domains/:domain/aliases/:alias

NOTE: alias can be the string (richard) or the int id (11) returned at alias creation time.

curl -X DELETE https://api.improvmx.com/v3/domains/piedpiper.com/aliases/richard \
  -H "Authorization: Basic api:$API_KEY"

Returns JSON like the following:

{
    "success": true
}

Delete all aliases

DELETE /domains/:domain/aliases/aliases-all

curl -X DELETE https://api.improvmx.com/v3/domains/piedpiper.com/aliases/aliases-all \
  -H "Authorization: Basic api:$API_KEY"

Returns JSON like the following:

{
    "success": true
}

Bulk modify aliases

POST /domains/:domain/aliases/bulk

curl -X POST https://api.improvmx.com/v3/domains/piedpiper.com/aliases/bulk \
  -H "Authorization: Basic api:$API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"aliases":[
         {"alias":"richard","forward":"[email protected]"},
         {"alias":"jared", "forward":"[email protected]"}]
      "behavior": "update"}'
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 it to "update" will update an existing alias. Setting it to "delete" will delete specified aliases.

For add and update, returns JSON like the following:

{
    "added": [
        {
            "alias": "richard",
            "forward": "[email protected]",
            "id": 12345
        },
        {
            "alias": "jared",
            "forward": "[email protected]",
            "id": 12346
        }
    ],
    "failed": [
        {
            "alias": "monica",
            "forward": "[email protected]",
            "id": 12347
        }
    ],
    "success": true,
    "updated": [
        {
            "alias": "dinesh",
            "forward": "[email protected]",
            "id": 12348
        },
        {
            "alias": "bertram",
            "forward": "[email protected]",
            "id": 12349
        }
    ]
}

For delete, returns JSON like the following:

{
    "deleted": [
        {
            "alias": "test",
            "created": 1743462739000,
            "forward": "[email protected]",
            "id": 6
        }
    ],
    "failed": [
        {
            "alias": "test1"
        }
    ],
    "success": true
}

Rules

See the Rules Guide for more information about the rules routing engine.

Alias Rule Config

Use this JSON schema when adding or updating the alias rules.

{
    "alias": "richard",
    "forward": "[email protected]"
}
PARAMETER TYPE REQUIRED? DESCRIPTION
alias String True The alias this rule matches for.
forward String True Comma separated list of forwarding destinations for this rule.

Regex Rule Config

Use this JSON schema when adding or updating the regex rules.

{
    "forward": "[email protected]",
    "regex": ".*jared.*",
    "scopes": [
        "sender",
        "recipient",
        "subject",
        "body"
    ]
}
PARAMETER TYPE REQUIRED? DESCRIPTION
regex String True The regular expression this rule will match on.
scopes String List True The scopes this regex rule will match for. Options: "sender", "recipient", "subject", "body".
forward String True Comma separated list of forwarding destinations for this rule.

CEL Rule Config

Use this JSON schema when adding or updating the CEL rules.

{
    "expression": "subject.contains('finance')",
    "forward": "[email protected]"
}
PARAMETER TYPE REQUIRED? DESCRIPTION
expression String True The CEL expression this rule will match on.
forward String True Comma separated list of forwarding destinations for this rule.

List Rules

GET /domains/:domain/rules

curl -X GET https://api.improvmx.com/v3/domains/piedpiper.com/rules \
  -H "Authorization: Basic api:$API_KEY"
PARAMETER TYPE REQUIRED? DESCRIPTION
search String False Filter rule results by string match.
page Integer False Current page to load. 1-based (The first, default page is at page = 1).

Returns JSON like the following:

{
    "limit": 100,
    "page": 1,
    "rules": [
        {
            "active": true,
            "config": {
                "alias": "richard",
                "forward": "[email protected]"
            },
            "created": 1752026028000,
            "rank": 1.0,
            "id": "447a95d1-bac1-4d6e-8315-22b10f501efb",
            "type": "alias"
        },
        {
            "active": true,
            "config": {
                "forward": "[email protected]",
                "regex": ".*jared.*",
                "scopes": [
                    "sender"
                ]
            },
            "created": 1752467418000,
            "rank": 2.0,
            "id": "fcadc999-0d3f-45f8-9c62-056e1b98e47a",
            "type": "regex"
        }
    ],
    "success": true,
    "total": 2
}

Add Rule

POST /domains/:domain/rules

curl -X POST https://api.improvmx.com/v3/domains/piedpiper.com/rules \
  -H "Authorization: Basic api:$API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
         "type": "regex",
         "config": {
           "regex": ".*important.*",
           "scopes": ["subject", "body"],
           "forward": "[email protected]"
         }
      }'
PARAMETER TYPE REQUIRED? DESCRIPTION
type String True The rule type, choose from 'alias', 'regex', or 'cel'.
config JSON True The JSON config defining the rule, different for each rule type.
rank Float False The rule's rank which determines evaluation priority. If unspecified, server will assign the next largest rank.
active Boolean False Whether this rule is active or not.
id String False The alphanumeric ID of the rule. If unspecified, server will auto-generate a uuid.

Returns JSON like the following:

{
    "rule": {
        "active": true,
        "config": {
            "alias": "richard",
            "forward": "[email protected]"
        },
        "created": 1752026028000,
        "rank": 1.0,
        "id": "447a95d1-bac1-4d6e-8315-22b10f501efb",
        "type": "alias"
    },
    "success": true
}

Get Rule

GET /domains/:domain/rules/:rule

curl -X GET https://api.improvmx.com/v3/domains/piedpiper.com/rules/447a95d1-bac1-4d6e-8315-22b10f501efb \
  -H "Authorization: Basic api:$API_KEY"

Returns JSON like the following:

{
    "active": true,
    "config": {
        "alias": "richard",
        "forward": "[email protected]"
    },
    "created": 1752026028000,
    "rank": 1.0,
    "id": "447a95d1-bac1-4d6e-8315-22b10f501efb",
    "type": "alias"
}

Update Rule

PUT /domains/:domain/rules/:rule

curl -X PUT https://api.improvmx.com/v3/domains/piedpiper.com/rules/e8417681-3a4c-4f9b-ab93-1ca2529036c9 \
  -H "Authorization: Basic api:$API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
         "config": {
           "regex": ".*critical.*",
           "scopes": ["subject", "body"],
           "forward": "[email protected]"
         }
      }'
PARAMETER TYPE REQUIRED? DESCRIPTION
config JSON True The JSON config defining the rule, different for each rule type.
rank Float False The rule's rank which determines evaluation priority. If unspecified, server will assign the next largest rank.
active Boolean False Whether this rule is active or not.

Returns JSON like the following:

{
    "rule": {
        "active": true,
        "config": {
            "regex": ".*critical.*",
            "scopes": ["subject", "body"],
            "forward": "[email protected]"
        },
        "created": 1752026028,
        "id": "447a95d1-bac1-4d6e-8315-22b10f501efb",
        "rank": 1.0,
        "type": "alias"
    },
    "success": true
}

Delete Rule

DELETE /domains/:domain/rules/:rule

curl -X DELETE https://api.improvmx.com/v3/domains/piedpiper.com/rules/e8417681-3a4c-4f9b-ab93-1ca2529036c9 \
  -H "Authorization: Basic api:$API_KEY"

Returns JSON like the following:

{
    "success": true
}

Delete All Rules

DELETE /domains/:domain/rules-all

curl -X DELETE https://api.improvmx.com/v3/domains/piedpiper.com/rules-all \
  -H "Authorization: Basic api:$API_KEY"

Returns JSON like the following:

{
    "success": true
}

Bulk Modify Rules

POST /domains/:domain/rules/:rule

# Add a rule
curl -X POST https://api.improvmx.com/v3/domains/piedpiper.com/rules/bulk \
  -H "Authorization: Basic api:$API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
        "behavior": "add",
        "rules": [
          {
            "type": "cel",
            "config": { "expression": "true", "forward": "[email protected]" }
          }
        ]
      }'

# Update 2 rules
curl -X POST https://api.improvmx.com/v3/domains/piedpiper.com/rules/bulk \
  -H "Authorization: Basic api:$API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
        "behavior": "update",
        "rules": [
          {
            "id": "62f9cf67-9005-41a6-8706-843ca8df8932",
            "config": { "alias": "[email protected]" }
          },
          {
            "id": "5742c992-4378-4412-945b-be2177072fc4",
            "config": { "regex": ".*finance.*" }
          }
        ]
      }'

# Delete 2 rules
curl -X POST https://api.improvmx.com/v3/domains/piedpiper.com/rules/bulk \
  -H "Authorization: Basic api:$API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
        "behavior": "delete",
        "rules": [
          { "id": "62f9cf67-9005-41a6-8706-843ca8df8932" },
          { "id": "48ec8f60-ea1f-4509-9c36-43f5e83170b5" }
        ]
      }'
PARAMETER TYPE REQUIRED? DESCRIPTION
rules List of JSON True The list of JSON configs defining the rules, different for each rule type.
behavior String False Setting it to "add" (default) will cause the request to fail if the rule already exists. Setting it to "update" will update existing rules. Setting it to "delete" will delete specified rules.

Returns JSON like the following:

{
    "errors": [],
    "results": [
        {
            "operation": "update",
            "rule": {
                "active": true,
                "config": {
                    "alias": "[email protected]",
                    "forward": "[email protected]"
                },
                "created": 1752514190,
                "id": "62f9cf67-9005-41a6-8706-843ca8df8932",
                "rank": 50.0,
                "type": "alias"
            },
            "success": true
        },
        {
            "operation": "update",
            "rule": {
                "active": true,
                "config": {
                    "forward": "[email protected]",
                    "regex": ".+",
                    "scopes": [
                        "subject",
                        "body"
                    ]
                },
                "created": 1752510060,
                "id": "5742c992-4378-4412-945b-be2177072fc4",
                "rank": 40.0,
                "type": "regex"
            },
            "success": true
        }
    ],
    "success": true
}

Logs

List domain logs

GET /domains/:domain/logs

curl -X GET https://api.improvmx.com/v3/domains/piedpiper.com/logs \
  -H "Authorization: Basic api:$API_KEY"
PARAMETER TYPE REQUIRED? DESCRIPTION
next_cursor String False Loads the logs after the given log.id. (Like 20201002014128.7ea8ee5b46)

Returns JSON 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": "[email protected]",
                "name": "Richard Hendricks"
            },
            "hostname": "mail-io1-f54.google.com",
            "id": "20201002014128.5ea8ee59fa894aa7a9141e9665985b46",
            "messageId": "some_random_id",
            "recipient": {
                "email": "[email protected]",
                "name": "Richard Hendricks"
            },
            "sender": {
                "email": "[email protected]",
                "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": "[email protected]",
                "name": "Monica Hall"
            },
            "hostname": "mail-pj1-f54.google.com",
            "messageId": "another_random_id",
            "recipient": {
                "email": "[email protected]",
                "name": "Monica Hall"
            },
            "sender": {
                "email": "[email protected]",
                "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": "[email protected]",
                "name": null
            },
            "sender": {
                "email": "[email protected]",
                "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 ImprovMX servers, which are:

Status Description
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 temporarily refused the email. We will retry multiple times with increasing delay.
HARD-BOUNCE The end destination rejected the email.

List alias logs

GET /domains/:domain/logs/:alias

curl -X GET https://api.improvmx.com/v3/domains/piedpiper.com/logs/richard \
  -H "Authorization: Basic api:$API_KEY"

This behaves similarly to the general logs endpoint, but only returns results for the requested alias.

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 ImprovMX servers, which are:

PARAMETER TYPE REQUIRED? DESCRIPTION
next_cursor String False Loads the logs after the given log.id. (Like 20201002014128.15a6659c5b46)

Returns JSON 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": "[email protected]",
                "name": "Richard Hendricks"
            },
            "hostname": "mail-io1-f54.google.com",
            "id": "20201002014128.5ea8ee59fa894aa7a9141e9665985b46",
            "messageId": "some_random_id",
            "recipient": {
                "email": "[email protected]",
                "name": "Richard Hendricks"
            },
            "sender": {
                "email": "[email protected]",
                "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": "[email protected]",
                "name": null
            },
            "sender": {
                "email": "[email protected]",
                "name": "ThinkTeam"
            },
            "subject": "Enlarge your (pied)piper!",
            "transport": "smtp"
        }
    ],
    "success": true
}

Search domain logs

GET /domains/:domain/logs/search

This endpoint lets you filter the results with timestamp parameters. Supply Unix timestamps (seconds) in the after and before query parameters to limit the logs to a specific window. You can combine query parameters to restrict the result set.

curl -X GET https://api.improvmx.com/v3/domains/piedpiper.com/logs/search \
  -H "Authorization: Basic api:$API_KEY" -G \
  --data-urlencode "filter=<filter>" \
  --data-urlencode "text=<keyword>" \
  --data-urlencode "order=<asc_or_desc>" \
  --data-urlencode "after=<unix_timestamp_seconds>" \
  --data-urlencode "before=<unix_timestamp_seconds>"
PARAMETER TYPE REQUIRED? DESCRIPTION
filter String False Choose all (default) to include every status or failure to return only bounced events.
text String False Used for case-insensitive matches against the subject, sender, recipient, or destination address.
order String False Desc (default) shows most-recent logs first, asc reverses the order.
after Integer True Unix timestamp in seconds. Only entries with received_at greater than or equal to this value are returned.
before Integer True Unix timestamp in seconds. Only entries with received_at less than or equal to this value are returned.

NOTE: If you want to pass a human-readable date, convert it e.g. date --date='2024-07-02T12:00:00Z' +%s on Linux or the equivalent in your language) and supply that integer to after/before.

Returns JSON like the following:

{
    "logs": [
        {
            "created": "2025-05-12 09:45:18+0000",
            "created_raw": "Mon, 12 May 2025 09:45:18 GMT",
            "events": [
                {
                    "code": 250,
                    "created": "2025-05-12 09:45:20+0000",
                    "id": "0412c5c8-0",
                    "local": "mx1.improvmx.com",
                    "message": "Queued",
                    "server": "mail-io1-f41.google.com",
                    "status": "QUEUED"
                },
                {
                    "code": 550,
                    "created": "2025-05-12 09:45:23+0000",
                    "id": "0412c5c8-1",
                    "local": "mx1.improvmx.com",
                    "message": "5.2.1 Not sending to previously bounced email: <[email protected]>.",
                    "server": "sender19.psin1.zcsend.in",
                    "status": "REFUSED"
                }
            ],
            "forward": {
                "email": "[email protected]",
                "name": null
            },
            "hostname": "sender19.psin1.zcsend.in",
            "id": "20250512094518.0412c5c8a4f74a82b4d02ea83404a6f1",
            "messageId": "0412c5c8a4f74a82b4d02ea83404a6f1",
            "recipient": {
                "email": "[email protected]",
                "name": null
            },
            "sender": {
                "email": "[email protected]",
                "name": null
            },
            "subject": "Daily delivery report",
            "transport": "smtp"
        },
        {
            "created": "2025-05-12 06:12:04+0000",
            "created_raw": "Mon, 12 May 2025 06:12:04 GMT",
            "events": [
                {
                    "code": 250,
                    "created": "2025-05-12 06:12:05+0000",
                    "id": "9f65bc20-0",
                    "local": "mx2.improvmx.com",
                    "message": "Queued",
                    "server": "mail-pj1-f32.google.com",
                    "status": "QUEUED"
                },
                {
                    "code": 250,
                    "created": "2025-05-12 06:12:07+0000",
                    "id": "9f65bc20-1",
                    "local": "gmail-smtp-in.l.google.com",
                    "message": "Sent.",
                    "server": "mail12.mxa.infra.improvmx.com",
                    "status": "DELIVERED"
                }
            ],
            "forward": {
                "email": "[email protected]",
                "name": "Support Team"
            },
            "hostname": "mail-pj1-f32.google.com",
            "id": "20250512061204.9f65bc20deab4f71bcedad1dfc513e9a",
            "messageId": "9f65bc20deab4f71bcedad1dfc513e9a",
            "recipient": {
                "email": "[email protected]",
                "name": "Contact"
            },
            "sender": {
                "email": "[email protected]",
                "name": "Status Monitor"
            },
            "subject": "Service check passed",
            "transport": "smtp"
        }
    ],
    "success": true
}

SMTP Credentials

NOTE: SMTP is a premium feature.

List credentials

GET /domains/:domain/credentials

curl -X GET https://api.improvmx.com/v3/domains/piedpiper.com/credentials \
  -H "Authorization: Basic api:$API_KEY"

Returns JSON like the following:

{
    "credentials": [
        {
            "created": 1581604970000,
            "usage": 0,
            "username": "richard"
        },
        {
            "created": 1581607028000,
            "usage": 0,
            "username": "monica"
        }
    ],
    "success": true
}

Add credential

POST /domains/:domain/credentials

curl -X POST https://api.improvmx.com/v3/domains/piedpiper.com/credentials \
  -H "Authorization: Basic api:$API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"username": "bighead", "password": "abc123"}'
PARAMETER TYPE REQUIRED? DESCRIPTION
username True String Left part of the mailbox, like bighead for the email [email protected]
password True String The password for this account.

Returns JSON like the following:

{
    "credential": {
        "created": 1588236952000,
        "usage": 0,
        "username": "bighead"
    },
    "requires_new_mx_check": false,
    "success": true
}

The response field requires_new_mx_check will be True when creating your first SMTP credential.

NOTE: When setting up SMTP for the first time, we require two new DKIM CNAME entries and a new DMARC TXT entry in your DNS settings. Your domain will be unable to send SMTP until these are added.

Update credential

PUT /domains/:domain/credentials/:username

curl -X PUT https://api.improvmx.com/v3/domains/piedpiper.com/credentials/bighead \
  -H "Authorization: Basic api:$API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"password": "abcd1234"}'

Returns JSON like the following:

{
    "credential": {
        "created": 1588236952000,
        "usage": 0,
        "username": "bighead"
    },
    "success": true
}

Delete credential

DELETE /domains/:domain/credentials/:username

curl -X DELETE https://api.improvmx.com/v3/domains/piedpiper.com/credentials/russ \
  -H "Authorization: Basic api:$API_KEY"

Returns JSON like the following:

{
    "success": true
}