Postmark
Python client for the Postmark transactional email API. No official Python SDK exists — postmarker is the primary community library (listed by Postmark on their developer docs). Maintained by Dmitry Dygalo. v1.0 released but project marked inactive on Snyk (no new PyPI releases in 12+ months as of mid-2025). Django email backend included.
Common errors
-
AttributeError: module 'postmarker' has no attribute 'PostmarkClient'
cause The `PostmarkClient` class is located within the `postmarker.core` submodule, not directly under the top-level `postmarker` package.fixUse `from postmarker.core import PostmarkClient` to correctly import the client class. -
ImproperlyConfigured: You should specify TOKEN to use Postmark email backend
cause When using `postmarker.django.EmailBackend`, the `TOKEN` key is missing from the `POSTMARK` dictionary in your Django project's `settings.py`.fixAdd the `POSTMARK` setting with your server API token to your `settings.py` file: `POSTMARK = {'TOKEN': 'YOUR_POSTMARK_SERVER_TOKEN'}`. -
PostmarkerException: Sender Signature not defined for From address.
cause The 'From' email address specified in your email message has not been added and verified as a Sender Signature or a verified domain in your Postmark account.fixLog into your Postmark account, navigate to 'Sender Signatures', and add and verify the email address you intend to use in the 'From' field. -
PostmarkerException: Connection Timed Out
cause This error typically occurs when your application cannot establish a connection to Postmark's SMTP servers, often due to outbound traffic on port 25 being blocked by your ISP or hosting provider.fixSwitch your SMTP port to 2525 or 587 in your application's configuration, as Postmark supports these alternative ports to bypass common blocks on port 25. -
PostmarkerException: Authentication Failed
cause The Postmark API token provided in your `PostmarkClient` initialization or Django settings is incorrect, contains typos, or is an Account API Token instead of a Server API Token.fixVerify that you are using the correct Server API Token for the specific Postmark server and ensure there are no leading or trailing spaces or other typos.
Warnings
- gotcha postmarker is a community library, not an official Postmark SDK. Postmark has no official Python SDK. postmarker is the recommended community option per Postmark's developer docs, but it is not maintained by Postmark.
- gotcha postmarker v1.0 has no releases to PyPI in 12+ months as of mid-2025. The project may be effectively abandoned. Python 3.11+ compatibility has not been verified in recent releases.
- gotcha Field names in postmarker follow Postmark's PascalCase API convention, not Python snake_case. Code passing lowercase fields (from_email, html_body) is silently ignored or raises AttributeError.
- gotcha PostmarkClient constructor kwarg is server_token=, not token=. An earlier version used token= — code from older tutorials passes token= and raises TypeError.
- gotcha Use 'POSTMARK_API_TEST' as the server_token to send emails to Postmark's blackhole test environment (test@blackhole.postmarkapp.com). These emails are never delivered. Switch to a real server token for production.
Install
-
pip install postmarker -
pip install django-anymail[postmark]
Imports
- PostmarkClient
from postmarker.core import PostmarkClient postmark = PostmarkClient(token='SERVER_TOKEN')
from postmarker.core import PostmarkClient postmark = PostmarkClient(server_token='SERVER_TOKEN')
- Django backend
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
# settings.py EMAIL_BACKEND = 'postmarker.django.EmailBackend' POSTMARK = { 'TOKEN': 'SERVER_TOKEN', 'TEST_MODE': False, 'VERBOSITY': 0, }
Quickstart
import os
from postmarker.core import PostmarkClient
postmark = PostmarkClient(server_token=os.environ['POSTMARK_SERVER_TOKEN'])
# Send single email
response = postmark.emails.send(
From='sender@example.com',
To='recipient@example.com',
Subject='Hello from Postmark',
HtmlBody='<strong>Hello!</strong>'
)
print(response['MessageID'])
# Send batch
postmark.emails.send_batch(
{
'From': 'sender@example.com',
'To': 'recipient1@example.com',
'Subject': 'Batch 1',
'TextBody': 'Hello 1'
},
{
'From': 'sender@example.com',
'To': 'recipient2@example.com',
'Subject': 'Batch 2',
'TextBody': 'Hello 2'
}
)
# Test token for sandbox
# postmark = PostmarkClient(server_token='POSTMARK_API_TEST')