Anymail integrates with the Postmark transactional email service, using their HTTP email API.



To use Anymail’s Postmark backend, set:

EMAIL_BACKEND = "anymail.backends.postmark.EmailBackend"

in your


Required. A Postmark server token.

    "POSTMARK_SERVER_TOKEN": "<your server token>",

Anymail will also look for POSTMARK_SERVER_TOKEN at the root of the settings file if neither ANYMAIL["POSTMARK_SERVER_TOKEN"] nor ANYMAIL_POSTMARK_SERVER_TOKEN is set.

You can override the server token for an individual message in its esp_extra.


The base url for calling the Postmark API.

The default is POSTMARK_API_URL = "" (It’s unlikely you would need to change this.)

esp_extra support

To use Postmark features not directly supported by Anymail, you can set a message’s esp_extra to a dict that will be merged into the json sent to Postmark’s email API.


message.esp_extra = {
    'HypotheticalFuturePostmarkParam': '2022',  # merged into send params
    'server_token': '<API server token for just this message>',

(You can also set "esp_extra" in Anymail’s global send defaults to apply it to all messages.)

Limitations and quirks

Postmark does not support a few tracking and reporting additions offered by other ESPs.

Anymail normally raises an AnymailUnsupportedFeature error when you try to send a message using features that Postmark doesn’t support You can tell Anymail to suppress these errors and send the messages anyway – see Unsupported features.

Single tag
Postmark allows a maximum of one tag per message. If your message has two or more tags, you’ll get an AnymailUnsupportedFeature error—or if you’ve enabled ANYMAIL_IGNORE_UNSUPPORTED_FEATURES, Anymail will use only the first tag.
No delayed sending
Postmark does not support send_at.

Postmark supports several link-tracking options. Anymail treats track_clicks as Postmark’s “HtmlAndText” option when True.

If you would prefer Postmark’s “HtmlOnly” or “TextOnly” link-tracking, you could either set that as a Postmark server-level default (and use message.track_clicks = False to disable tracking for specific messages), or use something like message.esp_extra = {'TrackLinks': "HtmlOnly"} to specify a particular option.

No envelope sender overrides
Postmark does not support overriding envelope_sender on individual messages. (You can configure custom return paths for each sending domain in the Postmark control panel.)

Batch sending/merge and ESP templates

Postmark supports ESP stored templates populated with global merge data for all recipients, but does not offer batch sending with per-recipient merge data. Anymail’s merge_data message attribute is not supported with the Postmark backend.

To use a Postmark template, set the message’s template_id to the numeric Postmark “TemplateID” and supply the “TemplateModel” using the merge_global_data message attribute:

message = EmailMessage(
    subject=None,  # use template subject
    to=["[email protected]"]  # single recipient...
    # ...multiple to emails would all get the same message
    # (and would all see each other's emails in the "to" header)
message.template_id = 80801  # use this Postmark template
message.merge_global_data = {
    'name': "Alice",
    'order_no': "12345",
    'ship_date': "May 15",
    'items': [
        {'product': "Widget", 'price': "9.99"},
        {'product': "Gadget", 'price': "17.99"},

Set the EmailMessage’s subject to None to use the subject from your Postmark template, or supply a subject with the message to override the template value.

See this Postmark blog post on templates for more information.

Status tracking webhooks

If you are using Anymail’s normalized status tracking, set up a webhook in your Postmark account settings, under Servers > your server name > Settings > Webhooks. The webhook URL is:

Choose all the event types you want to receive. Anymail doesn’t care about the “include messsage content” and “post only on first open” options; whether to use them is your choice.

If you use multiple Postmark servers, you’ll need to repeat entering the webhook settings for each of them.

Postmark will report these Anymail event_types: rejected, failed, bounced, deferred, delivered, autoresponded, opened, clicked, complained, unsubscribed, subscribed. (Postmark does not support sent–what it calls “processed”–events through webhooks.)

The event’s esp_event field will be a dict of Postmark delivery, bounce, spam-complaint, open-tracking, or click data.

Inbound webhook

If you want to receive email from Postmark through Anymail’s normalized inbound handling, follow Postmark’s Inbound Processing guide to configure an inbound server pointing to Anymail’s inbound webhook.

The InboundHookUrl setting will be:

Anymail handles the “parse an email” part of Postmark’s instructions for you, but you’ll likely want to work through the other sections to set up a custom inbound domain, and perhaps configure inbound spam blocking.