NAV undefined
undefined

Introduction

Welcome to the Mailsac API, where you can build just about anything with email.

Features and Help

Less technical documentation is available at /docs

Contact Us

Authentication

API keys are used to auth with the API. They can be passed as a header, body parameter, or querystring parameter.

API Key Format

Example Key

eoj1mn7x5y61w0egs25j6xrvs6lwrrld0oh43rj583cgdps10tokp2ceux9s6ri8

API keys are 64 character alphanumeric cryptographically random tokens.

Get an API Key

Purchase a subscription first.

Then go to the API Keys section on the Dashboard to manage your account's API key.

Option 1: HTTP Header

Create a request header for Mailsac-Key.

HTTP/1.x 200 OK
GET /api/addresses/test@example.com/messages
Host: mailsac.com
Mailsac-Key: eoj1mn7x5y61w0egs25j6xrvs6lwrrld0oh43rj583cgdps10tokp2ceux9s6ri8

Option 2: Query String Parameter

In the query section of the URL (after ?) add a parameter for _mailsacKey.

https://mailsac.com/api/addresses/test@example.com/messages?_mailsacKey=eoj1mn7x5y61w0egs25j6xrvs6lwrrld0oh43rj583cgdps10tokp2ceux9s6ri8
Field Description
_mailsacKey your API key

Option 3: Request JSON Body

{
    "_mailsacKey": "eoj1mn7x5y61w0egs25j6xrvs6lwrrld0oh43rj583cgdps10tokp2ceux9s6ri8"
}

During a POST or PUT request, add a JSON field for _mailsacKey.

Field Description
_mailsacKey your API key

Email Addresses API

Example Email Address Object

{
    "_id": "asdf@example.com",
    "created": "2015-04-05T15:10:33.234Z",
    "enablews": true,
    "forward": "bill@example.com",
    "webhook": "https://example.com/email-callback",
    "owner": "jimbo",
    "encryptedInbox": "inbox-efeaefa6e78d9abba34c4"
}
Field Description
_id the unique identifier of this email address is the email address itself
created ISO 8601 date and time string
enablews boolean defaulting false indicating whether to publish messages via web socket when the user owning this inbox is subscribed
forward email address where messages to this inbox will be forwarded
webhook URL where messages to this inbox will be forwarded
owner Account._id that owns the address (owns the privacy)
encryptedInbox an alternate inbox prefix that will result in the message being delivered to this inbox _id

List All Private Addresses

GET /api/addresses

[{
    "_id": "asdf@mailsac.com",
    "created": "2013-02-05T15:10:33.234Z",
    "enablews": true,
    "forward": "asdf@example.com",
    "webhook": "https://example.com/email-callback",
    "owner": "your account._id",
    "encryptedInbox": "inbox-d6da59f7a6e78d9abba34c4"
}, {
    "_id": "somewhere@mailsac.com",
    "created": "2013-02-05T15:10:33.234Z",
    "enablews": false,
    "forward": null,
    "webhook": null,
    "owner": "your account._id",
    "encryptedInbox": "inbox-a6e7a59f7ba34c48d9abd6d"
}]

Get an array of private inbox address objects for the account.

Get a Specific Private Address

GET /api/addresses/:email

{
    "_id": "somewhere@mailsac.com",
    "created": "2013-02-05T15:10:33.234Z",
    "enablews": true,
    "forward": "somewhere@example.com",
    "webhook": "https://example.com/email-callback",
    "owner": "your account._id",
    "encryptedInbox": "inbox-d6da59f7a6e78d9abba34c4"
}

Get a single address object.

Returns an object if owned by the user or not owned.

Returns 401 if owned by other user.

Check Address Ownership

GET /api/addresses/:email/availability

{
    "available": true,
    "email": "ae638ef@mailsac.com",
    "owned": false
}

Check if an address is private (AKA owned).

Reserve a Private Email Address

POST /api/addresses/:email

{
    "_id": "somewhere@mailsac.com",
    "created": "2013-02-05T15:10:33.234Z",
    "enablews": true,
    "forward": "somewhere@example.com",
    "webhook": "https://example.com/email-callback",
    "owner": "your account._id",
    "encryptedInbox": "inbox-d6da59f7a6e78d9abba34c4"
}

Reserve ownership of a private email address.

No POST body is required.

Returns 200 if successfully reserves the address.

Returns 401 if owned by other user.

Returns 400 if it is already owned by the user.

Release a Private Address

DELETE /api/addresses/:email

Release ownership of a private address.

Returns 200 if successfully releases the address.

Returns 401 if owned by other user.

Returns 400 if it is not owned.

Forward an Email Address

PUT /api/private-address-forwarding/:email

{
    "forward": "newemail@example.com",
    "enablews": true,
    "webhook": "https://example.com/email-callback"
}

For a privately owned address :email, set it to forward to another email.

PUT Body

Field Description
forward email address - SMTP forwarding / standard email forwarding - set to "" or null to disable forwarding
enablews boolean, defaults false - set to true to enable web socket forwarding (see Web Socket API)
webhook url - set to your public webhook endpoint to receive mail via webhook - set to "" or null to disable webhooks

Email Messages API

Permissions and Disposability

By default, all emails sent to Mailsac are accepted and public. They are recycled regularly unless starred.

Buying and reserving an email address means only you can see messages sent to it.

Anyone can request messages on a public (non-owned) inbox. Anyone can also delete messages from public inboxes.

Example Email Message Object

{
    "_id": "wLf7biMiadm6fPXHVE",
    "from": [Recipient],
    "to": [Recipient],
    "subject": "hi",
    "savedBy": "bob",
    "originalInbox": "test@example.com",
    "text": "hey there",
    "inbox": "test@example.com",
    "domain": "example.com",
    "received": "2016-08-16T02:59:13.406Z",
    "body": "<div>hey there</div>",
    "html": "<div>hey there</div>",
    "raw": "",
    "headers": {
        "received": ["", ""],
        "reply-to": "",
    },
    "size": "6821",
    "attachments": ["def20078c72e1e72043e910734e5efbc"]
}
Field Description
_id unique identifier of the email
from array of Recipient objects (see below)
to array of Recipient objects (see below)
subject email subject line
savedBy when starred, this is the Account._id
originalInbox same as inbox unless sent to the encryptedInbox
inbox email address to which this message belongs
domain hostname domain for the inbox
received ISO 8601 date and time string
body cleaned HTML body
text the text representation of the email
html full unsafe HTML body
raw original full email transport text
headers object of parsed smtp headers with all key fields lowercased - may be an array when multiple headers with the same name existed
size content length in bytes of the entire raw email message
attachments null or array of MD5 hashes of attachments

Example Recipient Object

{
    name: "Bill Jones",
    address: "billjones@example.com"
}
Field Description
name friendly email name, optional part of the transport so may be empty string
address email address

List Inbox Email Messages

GET /api/addresses/:email/messages

[{
  "inbox": "test@example.com",
  "to": [{
    "address": "test@example.com",
    "name": ""
  }],
  "_id": "XOYj2t0MMe92286kf2hsOFNuPLxkjt3eQ",
  "from": [{
    "address": "tomriddle@example.com",
    "name": "Tom Riddle"
  }],
  "subject": "Page 2",
  "received": "2014-10-02T09:05:51.484Z",
  "originalInbox": "test@example.com",
  "size": 6210,
  "attachments": ["1e72043e910def20078c72e734e5efbc"]
}, {
  "inbox": "test@example.com",
  "to": [{
    "address": "test@example.com",
    "name": ""
  }],
  "savedBy": "bob",
  "_id": "vUSsCSHLC9vJkYBPruWhyhTZJXOaIIrm-0",
  "from": [{
    "address": "nounverb@example.com",
    "name": "Noun Verb"
  }],
  "subject": "Weeping",
  "received": "2016-10-10T16:58:59.131Z",
  "originalInbox": "test@example.com",
  "size": 115313,
  "attachments": null
}]

This is how to check the mail. Get a list of messages for the :email address.

The objects are abbreviated to provide basic metadata.

List Starred/Saved Messages

GET /api/addresses/starred/messages

Get a list of messages that have been saved and made private for the user.

Get a Single Email Message

GET /api/addresses/:email/messages/:messageId

Get the full detailed information about the message. It includes parsed headers, raw SMTP, HTML and text representations of the message.

Path Params

Field Description
:email email address
:messageId the Mailsac Message._id

Star/Save a Message

PUT /api/addresses/:email/messages/:messageId/star

{
    "savedBy": "bob",
    "inbox": "test@example.com",
    "to": [{
        "address": "test@example.com",
        "name": ""
    }],
    "_id": "C9vJkYBIIrmPruWhyhTZJXOavUSsCSHL",
    "from": [{
        "address": "joe@example.com",
        "name": ""
    }],
    "subject": "Saved",
    "received": "2017-01-10T16:58:59.131Z",
    "originalInbox": "test@example.com",
    "size": 115313,
    "attachments": null
}

Toggle starred status so it will not be automatically removed.

There is no PUT body.

It returns only the message metadata.

Delete a Message

DELETE /api/addresses/:email/messages/:messageId

Permanently removes a message. There is no history or trash bin.

Get Message Headers

GET /api/headers/:email/:messageId

{
    "dkim-signature": "",
    "received": "",
    "x-facebook": "",
    "date": "",
    "to": "",
    "subject": "",
    "x-priority": "",
    "x-mailer": "",
    "return-path": "",
    "from": "",
    "reply-to": "",
    "errors-to": "",
    "x-facebook-notify": "",
    "list-unsubscribe": "",
    "x-facebook-priority": "",
    "x-auto-response-suppress": "",
    "require-recipient-valid-since": "",
    "message-id": "",
    "mime-version": "",
    "content-type": "",
    "received": ["", ""],
    "x-mailsac-whitelist": ""
}

Get the SMTP headers from an email message.

Use the querystring param ?download=1 to trigger file download in browser.

Get Sanitized HTML

GET /api/body/:email/:messageId

Content-Type: text/html

Get safe HTML from an email message. Scripts, images and links are stripped out.

Use the querystring param ?download=1 to trigger file download in browser.

Get Message HTML

GET /api/dirty/:email/:messageId

Content-Type: text/html

Get a message's HTML content.

Attached images are inlined and nothing has been stripped.

Use the querystring param ?download=1 to trigger file download in browser.

Get Message Text

GET /api/text/:email/:messageId

Content-Type: text/plain

Get a message's text content.

Use the querystring param ?download=1 to trigger file download in browser.

Get Raw SMTP

GET /api/raw/:email/:messageId

Content-Type: text/plain

The entire original SMTP message transport message.

Use the querystring param ?download=1 to trigger file download in browser.

Send Email Messages

POST /api/outgoing-messages

{
    "to": "someone@example.com",
    "from": "somebody@mailsac.com",
    "subject": "Hey",
    "text": "Message text body [2561a.jpg]",
    "html": "<div>Message text body <img src=3D\"F3011FGE@hsd1.ca.comcast.net.\"></div>",
    "attachments": [{
        "cid": "F3011FGE@hsd1.ca.comcast.net.",
        "contentDisposition": "inline; filename=2561a.jpg",
        "content": "3asfji32gia...93as==",
        "encoding": "base64",
        "filename": "2561a.jpg",
    }],
    "received": ["by 130.7.72.46 with SMTP id g633m40907;\n Fri, 12 Oct 2016 17:26:53 -0700 (PDT)"],
    "raw": "raw SMTP message",
}

Send transactional text-only email messages.

Outgoing message credits must be purchased first.

One credit will be used per recipient (as opposed to per email).

Either text or html is required to send a message.

When passing a raw SMTP package it should be a full SMTP message. All required fields below must be included in the raw package.

POST Body

Field Description
to required - email addresses, currently capped at 3 - comma separated like a@example.com,b@example.com or as an array of recipient objects
from required - the email address to be sent from - must be a verified domain the account is allowed to send from, formats could be a string email address or an array of recipient objects
subject optional email subject line
text non-HTML body
html HTML body content
attachments Array of attachment objects, see example code for format
received Array of strings (when multiple) or string of previous received header(s)
raw overrides all other fields; a raw SMTP message

User Account API

Get Current User

GET /api/me

When the API key matches / user is authenticated

{
    "_id": "my_username",
    "email": "outside-email@example.com",
    "messageLimit": 1000,
    "sendsRemaining": 362,
    "catchAll": 0,
    "privateAddressCredits": 1,
    "recents": [
        "example@mailsac.com",
        "mailsac@example.com"
    ],
    "noAds": 1
}
Field Description
_id account username
email account email address (optional)
messageLimit maximum allowed message history: starred messages + all messages on private addresses
sendsRemaining number of outbound recipients left to be able to send a message to
catchAll catch-all domain address, unused credits
privateAddressCredits number of private addresses that the account is entitled to but has not yet reserved
recents short list of recently viewed inboxes
noAds indicates whether this is a paid API account when > 0

When API key is invalid / user is not authenticated

null

Get User Stats

GET /api/me/stats

{
    "storedMessages": 40,
    "starredMessages": 14,
    "addresses": [
        "example@mailsac.com",
        "mailsac@example.com"
    ],
    "nonOwnedInboxes": [
        "some-public-addr@mailsac.com"
    ]
}

Get information about non-owned addresses with starred messages and total starred messages, and list of owned addresses.

Field Description
addresses list of owned private addresses
nonOwnedInboxes list of email addresses where user has starred messages but does not own the email address itself
starredMessages total count of saved messages
storedMessages total messages on all private addresses owned by the account

Sign Out

POST /api/auth/logout

Destroy the logged in user's session.

No POST body.

For cookie auth which works on the website only.

Attachments API

List Common Attachments

GET /api/mailstats/common-attachments

Example Request

GET /api/mailstats/common-attachments?startDate=2017-03-25&endDate=2017-03-28T02:53:50.269Z&limit=100&skip=1000
[
    {
        "_id": "d98f50c1cb9598b1d3cdf69779d5a435",
        "n": 3
    },
    {
        "_id": "b556203c4d5f74def67e1b7087548907",
        "n": 3
    },
    {
        "_id": "a58180dd3c36128f48e425f8f15ce204",
        "n": 2
    },
    {
        "_id": "29f28a35b7fe4c870a5db3b0b3fe712c",
        "n": 2
    },
    {
        "_id": "f7f3f975bdfb0044a96c1dc27d18d0fb",
        "n": 2
    }
]

Search for attachments that were received during the requested time period.

Limited to non-private inboxes.

Request

Querystring Param Format Description
startDate date (UTC) Required - Limit results to inboxes that received messages after this date.
endDate date (UTC) Required - Limit results to inboxes that received messages before this date.
limit integer Optional - Limit results to this many, default 20, max 1000.
skip integer Optional - Skip this many, default 0.

Response

Field Description
_id MD5 hash of the attachment file
n count of messages with this attachment

Count Attachments by MD5

GET /api/mailstats/common-attachments/:md5sum/count

{
    "n": 70
}

Count the number of email messages that have attachments with this MD5 sum.

Limited to non-private inboxes.

Get Messages with Attachment

GET /api/mailstats/common-attachments/:md5sum

[
    {
        "inbox": "xh@mailsac.com",
        "_id": "qC4068KcUG0ht6eBfnFcEtXs7",
        "from": [
            {
                "address": "a@b.com",
                "name": "Aaa"
            }
        ],
        "subject": "Stuff",
        "received": "2017-04-23T05:49:29.297Z",
        "originalInbox": "xh@mailsac.com",
        "attachments": [
            "06f33e07967f624c57445666b9efb1a9",
            "666b9ef33066967f24c57445e07fb1a0"
        ]
    },
    {
        "inbox": "joe@example.com",
        "_id": "Ms8PPC9FKPOwi2o8OwMs89CQw",
        "from": [
            {
                "address": "belmo@a.co",
            }
        ],
        "subject": "Chicken sandwich",
        "received": "2017-04-26T05:42:29.444Z",
        "originalInbox": "joe@example.com",
        "attachments": [
            "06f33e07967f624c57445666b9efb1a9"
        ]
    }
]

List the email messages that have attachments with the requested MD5 sum.

Limited to non-private inboxes.

Download an Attachment

GET /api/mailstats/common-attachments/:md5sum/download

Download an attachment with the MD5 sum requested.

Email Stats API

These APIs can be helpful in detecting spam, phishing, or other nefarious SMTP activity.

Mailsac receives email for tens of thousands of domains, acting as a honeypot.

Private addresses data is not returned by the this set of APIs.

List Top Email Addresses

GET /api/mailstats/top-addresses

Example Request

GET /api/mailstats/top-addresses?startDate=2017-04-26T03:14:40.412Z&endDate=2017-04-28T07:14:40.412Z
[
    {
        "_id": "apad@mailsac.com",
        "n": 10
    },
    {
        "_id": "foooo@mailsac.com",
        "n": 7
    },
    {
        "_id": "fcca3a@mailsac.com",
        "n": 6
    },
    {
        "_id": "11111@mailsac.com",
        "n": 4
    }
]

Search for the top non-private addresses that have been receiving mail.

Request

Querystring Param Format Description
startDate date (UTC) Required - Limit results to inboxes that received messages after this date.
endDate date (UTC) Required - Limit results to inboxes that received messages before this date.
limit integer Optional - Limit results to this many, default 20, max 1000.
skip integer Optional - Skip this many, default 0.

Response

Field Description
_id email address
n count of messages in the inbox

Blacklisted Domains and IPs

GET /api/mailstats/blacklist

Get an array of domains and IP addresses that have been blacklisted for violating the terms of service and/or degrading the service experience for other customers.

[
    "example.com",
    "192.168.0.1"
]

Check Blacklist

GET /api/mailstats/blacklist/:domainOrIP

Check if a domain or IP is on the blacklist.

Returns 404 if not blacklisted.

Returns 200 if blacklisted.

Webhooks

Webhook docs coming soon

Web Socket API

You can receive email via web socket, for private email addresses.

To enable web socket forwarding, select "Edit" for the email address you want to forward. Then check the checkbox for web socket forwarding, and save. Web socket forwarding is not enabled by default.

Web Socket Examples

Web Socket Test Page

https://sock.mailsac.com

Receive emails in your web browser.

Experiment with the web socket gateway in realtime.

Web Socket Node.js

Listen for Mailsac emails via websocket in this tiny Node.js example app.

https://github.com/ruffrey/mailsac-node-websocket-example

Web Socket Connection Endpoint

The web socket endpoint is wss://sock.mailsac.com/incoming-messages

Query String Parameters

# Example Web Socket Connection URL
wss://sock.mailsac.com/incoming-messages?_id=myusername;&amp;key=skkie9bksd2ad&amp;addresses=1@mailsac.com,2@mailsac.com

Web Socket Message Format

All web socket messages are JSON. After parsing the JSON, there will be a status field with an HTTP status code (usually 200).

An email coming over the web socket will also have an email property, and its value will be the same as the messages REST API, plus some additional fields:

Example Web Socket Frame

{
    "status": 200,
    "email": {
        "_id": "W0YIhkgWJxcZc1qujq2w6f1YPZwFc",
        "from": [
            {
                "name": "",
                "address": "foo@mailsac.com"
            }
        ],
        "to": [
            {
                "name": "",
                "address": "bar@mailsac.com"
            }
        ],
        "subject": "Hi hello",
        "originalInbox": "bar@mailsac.com",
        "inbox": "bar@mailsac.com",
        "domain": "mailsac.com",
        "received": "2017-05-01T01:39:27.940Z",
        "body": "<div>Yoooo</div>",
        "html": "<div>Yoooo</div>",
        "raw": "DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mailsac.com;\r\n q=dns/txt;
        s=mailsacrelay;\r\n h=from:subject:to:mime-version:content-type:content-transfer-encoding:list-unsubscribe;\r\n b=redacted\r\nReceived: from localhost (127.0.0.1) by fortune with SMTP; Sun Apr 30\r\n 2017 21:40:10 GMT-0400 (EDT)\r\nContent-Type: text/plain\r\nFrom: foo@mailsac.com\r\nTo: bar@mailsac.com\r\nSubject: Hi me\r\nMessage-ID:\r\n \r\nList-Unsubscribe: \r\nContent-Transfer-Encoding: 7bit\r\nDate: Mon, 01 May 2017 01:40:10 +0000\r\nMIME-Version: 1.0\r\n\r\nYoooo",
        "headers": {
            "content-transfer-encoding": "7bit",
            "content-type": "text/plain",
            "date": "Mon, 01 May 2017 01:40:10 +0000",
            "dkim-signature": "&lt;redacted&gt;",
            "from": "foo@mailsac.com",
            "list-unsubscribe": "",
            "message-id": "",
            "mime-version": "1.0",
            "received": "from localhost (127.0.0.1) by fortune with SMTP; Sun Apr 30 2017 21:40:10 GMT-0400 (EDT)",
            "subject": "Hi me",
            "to": "bar@mailsac.com"
        },
        "text": "Yoooo"
    }
}

API Errors

JSON Error Formats

    {
        "error": "error info here",
        "message": "or a message here"
    }

The Mailsac API attempts to send errors in a standardized format using HTTP status codes.

Error Codes

HTTP Status Status Message Meaning
400 Bad Request Fix the validation error and try the request again
401 Unauthorized Your API key is wrong or you are requesting something that belongs to someone else
403 Forbidden No matter how you repeat the request, it will not succeed with those credentials
404 Not Found The requested resource does not exist, or no longer exists, or the URL route is wrong
418 I'm a teapot Short and stout
420 Relax your calm Chill
429 Too Many Requests Please slow down your requests
500 Internal Server Error We had a problem with our server and have been notified via our monitoring - try again later
503 Service Unavailable We're temporarially offline for maintanance - try again later