Sending mails through Postmark is as simple as sending HTTP Post request to the service. A line of code speaks more than a thousand words – the example below sends a message straight through curl. Execute it in your terminal to the see results (Mac and Linux).
$: curl -X POST "http://api.postmarkapp.com/email" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "X-Postmark-Server-Token: ed742D75-5a45-49b6-a0a1-5b9ec3dc9e5d" \
-v \
-d "{From: 'sender@example.com', To: 'receiver@example.com', Subject: 'Postmark test', HtmlBody: '<html><body><strong>Hello</strong> dear Postmark user.</body></html>'}"
Note that you can also use SSL encryption by issuing requests to https://api.postmarkapp.com/email.
In order to authenticate yourself to the service, you need to send the correct HTTP header with the API key of your server:
X-Postmark-Server-Token: your-api-key-here
The header name and value are case insensitive. Should you execute the request with wrong or missing headers, you will receive HTTP Response 401 (Unauthorized).
Often when implementing your client library or when integrating an existing library into your application you would want to send “test” emails that don’t actually get delivered to the recipient. You just need to know if your data is valid. You can do that by passing the “POSTMARK_API_TEST” value as your server API token.
Currently Postmark supports JSON message format. The mail message format is
{
"From" : "sender@example.com",
"To" : "receiver@example.com",
"Cc" : "copied@example.com",
"Bcc": "blank-copied@example.com",
"Subject" : "Test",
"Tag" : "Invitation",
"HtmlBody" : "<b>Hello</b>",
"TextBody" : "Hello",
"ReplyTo" : "reply@example.com",
"Headers" : [{ "Name" : "CUSTOM-HEADER", "Value" : "value" }]
}
You should pass the json encoded message in the body of the request. Both from and to accept name, in the format of John Doe <email@example.com>. You can provide HtmlBody for html formatted messages, TextBody for plain text, or both for multipart. Multipart sends html with a text version for clients that don’t support html. Passing headers is optional.
From: "John Smith <sender@example.com>".Attachments are specified in the Attachments array property. An attachment is an object that has to provide the file name (via the Name property), the content type (ContentType property) and the actual binary data (Content property) that has to be sent with the message.
The name is the actual file name that will be displayed to the message recipient. Note that the file extension is important. To eliminate the possibility of spreading viruses or spyware we allow only a number of file types. That is, instead of using a list of forbidden files and risking an unanticipated file type spreading infections, we have taken the opposite approach — we whitelist document file types that we are certain are safe. Here is the list of allowed files:
Contact us if you feel we need to whitelist a file that your application needs.
The content type is the MIME content type that email clients use to interpret various attachments such as: text/plain, text/html, image/jpeg, etc. Your code can either detect it by the file extension, use a third party library to infer it, ask the user to provide it or just default to application/octet-stream.
The binary data has to be transmitted as a base64-encoded string. Most programming languages and libraries have this built in e.g. Java, .NET, PHP, Ruby
Here is a sample request containing attachments:
{
"From" : "sender@example.com",
"To" : "receiver@example.com",
"Subject" : "Test",
"HtmlBody" : "<b>Hello</b>",
"TextBody" : "Hello",
"Headers" : [{ "Name" : "CUSTOM-HEADER", "Value" : "value" }],
"Attachments": [
{
"Name": "readme.txt",
"Content": "dGVzdCBjb250ZW50",
"ContentType": "text/plain"
},
{
"Name": "report.pdf",
"Content": "dGVzdCBjb250ZW50",
"ContentType": "application/octet-stream"
}
]
}
Limitations:
If all goes well, you will get back a JSON message looking a lot like:
{
"ErrorCode" : 0,
"Message" : "OK",
"MessageID" : "b7bc2f4a-e38e-4336-af7d-e6c392c2f817",
"SubmittedAt" : "2010-11-26T12:01:05.1794748-05:00",
"To" : "receiver@example.com"
}
Note the MessageID property. You can log it in your system and use it to associate the message you just sent to a possible bounce that you obtained from a bounce web hook or the bounce API.
While Postmark is focused on transactional email, we understand that developers with higher volumes or processing time constraints need to send their messages in batches. To facilitate this we provide a batching endpoint that permits you to send up to 500 well-formed Postmark messages in a single API call.
The format of the batched message is a JSON array containing multiple message requests like the following example.
$: curl -X POST "http://api.postmarkapp.com/email/batch" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "X-Postmark-Server-Token: ed742D75-5a45-49b6-a0a1-5b9ec3dc9e5d" \
-v \
-d "[{From: 'sender@example.com', To: 'receiver1@example.com', Subject: 'Postmark test #1', HtmlBody: '<html><body><strong>Hello</strong> dear Postmark user.</body></html>'},{From: 'sender@example.com', To: 'receiver2@example.com', Subject: 'Postmark test #2', HtmlBody: '<html><body><strong>Hello</strong> dear Postmark user.</body></html>'}]"
Note that you can also use SSL encryption by issuing requests to https://api.postmarkapp.com/email/batch.
Similarly, you will receive a matching JSON array containing each response for the messages you sent in your batched call:
[
{
"ErrorCode" : 0,
"Message" : "OK",
"MessageID" : "b7bc2f4a-e38e-4336-af7d-e6c392c2f817",
"SubmittedAt" : "2010-11-26T12:01:05.1794748-05:00",
"To" : "receiver1@example.com"
},
{
"ErrorCode" : 0,
"Message" : "OK",
"MessageID" : "e2ecbbfc-fe12-463d-b933-9fe22915106d",
"SubmittedAt" : "2010-11-26T12:01:05.1794748-05:00",
"To" : "receiver2@example.com"
}
]
{ErrorCode: 405, Message: "details"} with an error code and an error message containing details on what went wrong.Whenever the Postmark server detects an input error it will return an HTTP 422 status code along with a JSON object containing error details: {ErrorCode: 405, Message: "details"}. The ErrorCode field can be used to programmatically detect the type of error. Here are the supported error codes: