This add-on is operated by Wildbit Llc

Email delivery for web apps


Last Updated: 10 June 2015

Table of Contents

Postmark add-on removes the headaches of delivering and parsing transactional email for your web app, with minimal setup time and zero maintenance. We have years of experience getting email to the inbox, so you can focus on what you do best.

Use our Send API or our simple SMTP interface to start sending in minutes. Our Inbound API parses incoming email and forwards it to you via a web hook, making it easy to handle incoming email in your application.

Provisioning the add-on

Postmark can be attached to a Heroku application via the CLI:

A list of all plans available can be found on the Postmark add-on page.

$ heroku addons:create postmark:10k
-----> Adding postmark to sharp-mountain-4005... done, v18 (free)

Once Postmark has been added a POSTMARK_API_TOKEN setting will be available in the app configuration and will contain the api token to access Postmark API or SMTP interface. This can be confirmed using the heroku config:get command.

$ heroku config:get POSTMARK_API_TOKEN

After installing the Postmark add-on you also need to create at least one sender signature and configure your application to fully integrate with the add-on.

Creating sender signatures

Sender signatures are required in order to verify that, well, you really own the mailbox, and that you are not a spammer (yes, we hate spam too). You must have a sender signature for each from address used in your application.

To create a sender signature, open the Postmark Dashboard from the terminal:

$ heroku addons:open postmark
Opening postmark for sharp-mountain-4005…

You can also proceed to the Postmark Dashboard from your application page on the Heroku web site.

Setting up a local development environment

Postmark automatically sets environment variables on your Heroku servers, but sometimes you may need to recreate the environment locally. Foreman aims to solve this for you. You can save the environment variables in your .env file and let Foreman do the rest.

  $ bash -c 'echo "POSTMARK_API_TOKEN=`heroku config:get POSTMARK_API_TOKEN`" >> .env'
  $ bash -c 'echo "POSTMARK_SMTP_SERVER=`heroku config:get POSTMARK_SMTP_SERVER`" >> .env'
  $ bash -c 'echo "POSTMARK_INBOUND_ADDRESS=`heroku config:get POSTMARK_INBOUND_ADDRESS`" >> .env'

Sending emails via the Postmark SMTP interface

You want to try Postmark, but your application uses SMTP to send email? You can instantly switch your current email delivery without having to modify the application. This feature lets you use plain SMTP to send your messages and, to use it, you need to only change your configuration to point to the Postmark SMTP server.

The SMTP listener endpoint is available at on port 25 and 2525 (to get around firewall issues). We support both plain text authentication and CRAM-MD5. We recommend the latter as it is a lot more secure. CRAM-MD5 encrypts just the authentication process, but the message content is still sent as plain text. You can encrypt the entire connection using TLS via the standard STARTTLS SMTP extension. STARTTLS is supported by the vast majority of mailers and some of them, like Ruby’s ActionMailer automatically switch to encrypted communication when they detect that the server supports it.

Here is a sample configuration for Ruby Mail library:

Mail.defaults do
  delivery_method :smtp, {
    :address => ENV['POSTMARK_SMTP_SERVER'],
    :port => '25', # or 2525
    :domain => '',
    :user_name => ENV['POSTMARK_API_TOKEN'],
    :password => ENV['POSTMARK_API_TOKEN'],
    :authentication => :cram_md5, # or :plain for plain-text authentication
    :enable_starttls_auto => true, # or false for unencrypted connection

And Rails/ActionMailer:

ActionMailer::Base.smtp_settings = {
  :port           => '25', # or 2525
  :address        => ENV['POSTMARK_SMTP_SERVER'],
  :user_name      => ENV['POSTMARK_API_TOKEN'],
  :password       => ENV['POSTMARK_API_TOKEN'],
  :domain         => '',
  :authentication => :cram_md5, # or :plain for plain-text authentication
  :enable_starttls_auto => true, # or false for unencrypted connection
ActionMailer::Base.delivery_method = :smtp

Sending emails in Ruby

We support the official Ruby gem called postmark. It’s integrated with the Ruby Mail library and requires it to be installed. You can install both manually using the following command:

$ gem install mail postmark

If your application is using Bundler, add the following entries to your Gemfile and update application dependencies with bundle install:

gem 'mail'
gem 'postmark'

The following example will use the gem to send a text email with attachments:

message = do
  from            ''
  to              'Dr. Sheldon Cooper <>'
  subject         'Have you seen these pictures of yours?'
  body            'You look like a geek!'
  add_file        '1.jpeg'

  delivery_method Mail::Postmark, :api_token => ENV['POSTMARK_API_TOKEN']

message.attachments['sheldon.jpeg'] ='2.jpeg')

# => #<Mail::Message:70185826686240, Multipart: true, Headers: <From:>, <To:>, <Message-ID: ba644cc1-b5b1-4bcb-aaf8-2f290b5aad80>, <Subject: Have you seen these pictures of yours?>, <Content-Type: multipart/mixed; boundary=--==_mimepart_5121f9f1ec653_12c53fd569035ad817726>>

Sending emails in Ruby on Rails 3.x

Our postmark-rails Ruby gem was designed to make switching to the Postmark API as easy as possible. Ruby on Rails applications will need to add the following entry into their Gemfile specifying the Postmark client library.

gem 'postmark-rails', '>= 0.10.0'

Update application dependencies with bundler.

$ bundle install

Add this to your config/application.rb:

config.action_mailer.delivery_method   = :postmark
config.action_mailer.postmark_settings = { :api_token => ENV['POSTMARK_API_TOKEN'] }

That’s it. Now send emails as usual.

class TestMailer < ActionMailer::Base

  def tagged_message
      :subject => 'Did you know Postmark has a Heroku add-on?',
      :to      => '',
      :from    => '',
      :tag     => 'my-tag'


Sending emails in Ruby on Rails 2.x

Rails 2.x applications will need to add the following to config/environment.rb: do |config|

  # ...

  config.gem 'postmark-rails'
  require    'postmark-rails'

  config.action_mailer.delivery_method  = :postmark

  # ...


Usage example:

class SuperMailer < ActionMailer::Base

  def email
    from       ""
    subject    "Hello from Postmark"
    recipients ""
    tag        "big-bang"


See the postmark-rails gem documentation for more examples.

Sending emails in Python

Python users will need to install the python-postmark library. It’s possible to install the library via pip. Just add python-postmark>=0.4.3 to your requirements.txt file.

The following example will use the python-postmark library to send a tagged email.

import os
from postmark import PMMail

message = PMMail(api_key = os.environ.get('POSTMARK_API_TOKEN'),
                 subject = "Hello from Postmark",
                 sender = "",
                 to = "",
                 text_body = "Hello",
                 tag = "hello")


Check out the PMMail class’ documentation for more information on usage.

Sending emails in NodeJS

NodeJS users can use the postmark package available to install using NPM:

$ npm install postmark

The following example will use the postmark package for NodeJS to send a tagged text email:

var postmark = require("postmark")(process.env.POSTMARK_API_TOKEN)

    "From": "",
    "To": "",
    "Subject": "Hello from Postmark",
    "TextBody": "Hello!",
    "Tag": "big-bang"
}, function(error, success) {
    if(error) {
        console.error("Unable to send via postmark: " + error.message);
    }"Sent to postmark for delivery")

Sending emails in Clojure

Clojure users can use clojure-postmark to interact with the API. To get started add the following entry to your project dependencies (we assume you’re using Leiningen):

[postmark "1.1.0"]

The following example will use the clojure-postmark library to send a tagged text email:

(use '[postmark.core :only (postmark)])

(def api-token (get (System/getenv) "POSTMARK_API_TOKEN"))

(def send-message (postmark api-token ""))

(send-message {:to ""
               :subject "Hello from Postmark"
               :text "Hello!"
               :tag "big-bang"})

Using Postmark Inbound

Postmark makes email parsing easy, too. We provide you with a unique inbound email address, which can be used for receiving emails. Postmark then parses the incoming emails and sends you the data in a nicely formatted JSON document via web hook. To see it, run:

$ heroku config:get POSTMARK_INBOUND_ADDRESS

Depending on your use, you may not want your users to see the email. There are two options: MX Record Forwarding (beta) and custom forwarding with Gmail/Google Apps.

Our MX Record Support is in beta until we’ve released a web-based configuration UI. It’s currently API-only, and you can read the documentation on configuring MX Records.

If you’d like to wait until the feature is included in Postmark’s UI, or if you do not have access to edit your DNS records, you can read our help article to learn how to configure a custom forwarding email address from your Gmail/Google Apps account.

In order for your application receive the emails that we parse, you will need to tell Postmark where to send the JSON data for each inbound email it processes, which is done via an HTTP POST to a URL of your choice. You can set this URL in the Settings page for your Postmark server on the Postmark Dashboard.

To test your inbound server, we recommend using RequestBin first.

Here is a simple Ruby/Sinatra application that does basic inbound processing:

require 'sinatra'
require 'json'
require 'logger'

logger =

class Comment
  attr_accessor :attributes

  def self.create_from_inbound_hook(message) => message["TextBody"],
             :user_email => message["From"],
             :discussion_id => message["MailboxHash"])

  def initialize(attributes={})
    @attributes = attributes

post '/inbound' do
  comment = Comment.create_from_inbound_hook(JSON.parse( comment.inspect

Let’s assume the inbound hook is set to Then, if a user sends an email to (the part after plus sign is called “mailbox hash” and can be used to transfer additional information), it will be processed by Postmark and forwarded to the app’s inbound hook as a JSON object. The example app creates a new instance of Comment object using JSON object provided by Postmark.

I, [2013-02-28T05:18:56.407910 #2]  INFO -- : #<Comment:0x00000002979260 @attributes={:text=>"That's what you said about the Green Lantern movie. You were 114 minutes of wrong. ", :user_email=>"", :discussion_id=>"discussion7864"}>

Migrating between plans

Application owners should carefully manage the migration timing to ensure proper application function during the migration process.

Use the heroku addons:upgrade command to migrate to a new plan.

$ heroku addons:upgrade postmark:gold
-----> Upgrading postmark:newplan to sharp-mountain-4005... done, v18 ($49/mo)
       Your plan has been updated to: postmark:gold

Removing the add-on

Postmark can be removed via the CLI.

This will destroy all associated data and cannot be undone!

$ heroku addons:destroy postmark
-----> Removing postmark from sharp-mountain-4005... done, v20 (free)

Differences from Postmark

Postmark is primarily a standalone web service that provides a superset of features offered by the add-on. Besides a different billing model, when using the add-on you have no access to following Postmark functionality:

  1. Creating multiple Postmark servers. In Postmark you create a server for each app connected to your Postmark account. The add-on is limited to a single server connected to your Heroku app.
  2. Inviting moderators to your Postmark account. Postmark has functionality allowing you to invite users who can review delivered and received messages without having access to your API tokens or account settings. When using the add-on, you can only invite collaborators to your Heroku account, who have the same permission level as you within the Postmark dashboard.
  3. Account API tokens and all related API endpoints. You will not be able to manage your Postmark infrastructure (create servers and signatures) via the API.
  4. Automatic balance renewal. If you ever run out of credits, you will need to manually upgrade to a higher plan.


If you need help or have questions, you can contact Postmark at any time at or @postmarkapp on Twitter. For system status, visit