A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.
The Postmark API is how an app or AI agent works with a Postmark account: sending a transactional or bulk email, sending through a saved template, reading why a message bounced, or searching delivered messages and their opens and clicks. Access is granted through one of two tokens, a server token that reaches one server's mail and stats, and an account token that manages servers, domains, and senders, so the token type sets what a call can touch. Postmark can also push an event when a message is delivered, bounces, or is opened.
How an app or AI agent connects to Postmark determines what it can reach. There is a route for sending and inspecting mail on one server, a route for managing the account's servers, domains, and senders, and an experimental hosted server that exposes Postmark tools to agents, and each is governed by the token behind it.
The REST API takes JSON request bodies, returns JSON, and pages lists with count and offset, at https://api.postmarkapp.com. A call authenticates with a token in a header, either X-Postmark-Server-Token for one server's sending and messages or X-Postmark-Account-Token for account-level resources. The Accept and Content-Type headers are application/json.
An open-source Model Context Protocol server published by Postmark (ActiveCampaign) at github.com/ActiveCampaign/postmark-mcp exposes Postmark tools to AI agents and MCP clients like Claude Desktop and Cursor. It is run locally over stdio via npx, configured with a POSTMARK_SERVER_TOKEN, a default sender, and a default message stream. Its tools cover sending mail, templates, message search, bounces, suppressions, delivery stats, server info, and webhooks. It is an experimental Postmark Labs project, not a hosted endpoint, and is MIT licensed.
Postmark POSTs a JSON payload to a registered HTTPS endpoint when an event happens, like a delivery, bounce, open, click, spam complaint, or inbound message. The payload carries a RecordType naming the event. The receiver is secured with HTTP Basic auth credentials in the URL or with custom headers, and Postmark retries until it gets a 200, stopping on a 403.
Postmark also accepts outbound mail over SMTP at smtp.postmarkapp.com, authenticated with a server token as both the username and password, or with a stream-specific SMTP token to target a message stream. SMTP covers sending only; bounces, messages, stats, and account management are reached through the REST API.
A server token authorises sending and reading mail on a single server: sending email, templates, bounces, message search, opens, clicks, suppressions, and outbound stats. It is sent in the X-Postmark-Server-Token header and cannot reach account-level resources. Each server has its own token, so the token both identifies the server and bounds what a call can touch.
An account token authorises account-level work: creating and managing servers, domains, and sender signatures, and pushing templates between servers. It is sent in the X-Postmark-Account-Token header and is available to Account Owners and Admins. It is not used for sending mail, and it reaches every server in the account.
A stream-specific SMTP token sends mail over SMTP into a chosen message stream, used as the SMTP username and password. A server token can also be used directly over SMTP. SMTP tokens cover sending only.
The Postmark API is split into areas an agent can act on, like sending email, managing templates, reading bounces, searching delivered messages, and managing servers and domains. Each area is reached with one of two token types, and a write in some areas sends real mail or changes how an account sends.
Methods for sending transactional and bulk email, with or without a template.
Methods for managing the templates an account sends from.
Methods for reading bounces and reactivating bounced addresses.
Methods for searching delivered and received mail and its opens and clicks.
Methods for the do-not-send list on a message stream.
Read-only counts of sends, bounces, opens, clicks, and spam complaints.
Account-level methods for the servers that hold sending setups.
Account-level methods for sending domains and their DKIM and Return-Path setup.
Account-level methods for the verified from-addresses an account sends as.
Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.
| Method | Endpoint | What it does | Access | Permission | Version | |
|---|---|---|---|---|---|---|
Email (send)Methods for sending transactional and bulk email, with or without a template.4 | ||||||
| POST | /email | Send a single email message through a server. | write | Server token | Current | |
Needs the server token. Sends real mail; up to 10 MB including attachments. Acts onemail Permission (capability) Server tokenVersionAvailable since the API’s base version Webhook event deliveryRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /email/batch | Send up to 500 messages in one call. Returns 200 even when individual messages fail validation. | write | Server token | Current | |
Needs the server token. Each array entry carries its own ErrorCode; check per message. Up to 500 messages, 50 MB. Acts onemail Permission (capability) Server tokenVersionAvailable since the API’s base version Webhook event deliveryRate limitUp to 500 messages per call SourceOfficial documentation ↗ | ||||||
| POST | /email/withTemplate | Send a single email rendered from a saved template, with supplied model data. | write | Server token | Current | |
Needs the server token. References a template by id or alias. Acts onemail Permission (capability) Server tokenVersionAvailable since the API’s base version Webhook event deliveryRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /email/batchWithTemplates | Send up to 500 template-rendered messages in one call. | write | Server token | Current | |
Needs the server token. Same batch limits as /email/batch. Acts onemail Permission (capability) Server tokenVersionAvailable since the API’s base version Webhook event deliveryRate limitUp to 500 messages per call SourceOfficial documentation ↗ | ||||||
TemplatesMethods for managing the templates an account sends from.6 | ||||||
| GET | /templates | List the templates on a server. | read | Server token | Current | |
Read-only. Needs the server token. Acts ontemplate Permission (capability) Server tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /templates/{templateIdOrAlias} | Get a single template by id or alias. | read | Server token | Current | |
Read-only. Needs the server token. Acts ontemplate Permission (capability) Server tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /templates | Create a template on a server. | write | Server token | Current | |
Needs the server token. A server may hold up to 100 templates. Acts ontemplate Permission (capability) Server tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /templates/{templateIdOrAlias} | Edit an existing template. | write | Server token | Current | |
Needs the server token. Changes the template future sends will render. Acts ontemplate Permission (capability) Server tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /templates/{templateIdOrAlias} | Delete a template from a server. | write | Server token | Current | |
Needs the server token. Sends referencing it by alias then fail. Acts ontemplate Permission (capability) Server tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /templates/validate | Validate template content and preview the rendered result against supplied model data. | read | Server token | Current | |
Does not save anything; validates and previews only. Needs the server token. Acts ontemplate Permission (capability) Server tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
BouncesMethods for reading bounces and reactivating bounced addresses.5 | ||||||
| GET | /deliverystats | Get delivery statistics and a summary of bounce counts by type for a server. | read | Server token | Current | |
Read-only. Needs the server token. Acts onbounce Permission (capability) Server tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /bounces | Search bounces on a server, filtering by type, status, tag, and date. | read | Server token | Current | |
Read-only. Returns up to 10,000 results through paging. Needs the server token. Acts onbounce Permission (capability) Server tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /bounces/{bounceid} | Get the details of a single bounce. | read | Server token | Current | |
Read-only. Needs the server token. Acts onbounce Permission (capability) Server tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /bounces/{bounceid}/dump | Get the raw SMTP dump for a bounce. | read | Server token | Current | |
Read-only. Needs the server token. Acts onbounce Permission (capability) Server tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /bounces/{bounceid}/activate | Reactivate a bounced address so Postmark will send to it again. | write | Server token | Current | |
Needs the server token. Re-enables sending to an address Postmark had deactivated. Acts onbounce Permission (capability) Server tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
MessagesMethods for searching delivered and received mail and its opens and clicks.7 | ||||||
| GET | /messages/outbound | Search outbound messages on a server, filtering by recipient, tag, status, and date. | read | Server token | Current | |
Read-only. Returns up to 10,000 results through paging. Needs the server token. Acts onmessage Permission (capability) Server tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /messages/outbound/{messageid}/details | Get the full details of an outbound message, including body, recipients, and events. | read | Server token | Current | |
Read-only. Needs the server token. Acts onmessage Permission (capability) Server tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /messages/outbound/opens | Search message opens, with client, OS, and geographic detail. | read | Server token | Current | |
Read-only. Requires open tracking on the messages. Needs the server token. Acts onopen Permission (capability) Server tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /messages/outbound/clicks | Search link clicks, with client and location detail. | read | Server token | Current | |
Read-only. Requires link tracking on the messages. Needs the server token. Acts onclick Permission (capability) Server tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /messages/inbound | Search inbound messages received on a server. | read | Server token | Current | |
Read-only. Returns up to 10,000 results through paging. Needs the server token. Acts onmessage Permission (capability) Server tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /messages/inbound/{messageid}/retry | Reprocess a failed inbound message, re-POSTing it to the inbound webhook. | write | Server token | Current | |
Needs the server token. Triggers another inbound webhook delivery. Acts onmessage Permission (capability) Server tokenVersionAvailable since the API’s base version Webhook event inboundRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /messages/inbound/{messageid}/bypass | Bypass inbound blocking rules for a message that was held back. | write | Server token | Current | |
Needs the server token. Lets a blocked inbound message through to processing. Acts onmessage Permission (capability) Server tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
SuppressionsMethods for the do-not-send list on a message stream.3 | ||||||
| GET | /message-streams/{stream_id}/suppressions/dump | List the suppressed addresses on a message stream, with the reason each is inactive. | read | Server token | Current | |
Read-only. Needs the server token. Acts onsuppression Permission (capability) Server tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /message-streams/{stream_id}/suppressions | Add up to 50 addresses to a stream's do-not-send list. | write | Server token | Current | |
Needs the server token. Stops future sends to those addresses on the stream. Acts onsuppression Permission (capability) Server tokenVersionAvailable since the API’s base version Webhook event subscription-changeRate limitUp to 50 addresses per call SourceOfficial documentation ↗ | ||||||
| POST | /message-streams/{stream_id}/suppressions/delete | Remove up to 50 addresses from a stream's do-not-send list, reactivating them. | write | Server token | Current | |
Needs the server token. SpamComplaint suppressions cannot be removed. Acts onsuppression Permission (capability) Server tokenVersionAvailable since the API’s base version Webhook event subscription-changeRate limitUp to 50 addresses per call SourceOfficial documentation ↗ | ||||||
StatsRead-only counts of sends, bounces, opens, clicks, and spam complaints.3 | ||||||
| GET | /stats/outbound | Get an overview of outbound stats: sends, bounces, opens, clicks, and spam complaints. | read | Server token | Current | |
Read-only. Needs the server token. Acts onstat Permission (capability) Server tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /stats/outbound/bounces | Get total counts of sent emails that bounced. | read | Server token | Current | |
Read-only. Needs the server token. Acts onstat Permission (capability) Server tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /stats/outbound/opens | Get total counts of recipients who opened emails. | read | Server token | Current | |
Read-only. Needs the server token. Acts onstat Permission (capability) Server tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
ServersAccount-level methods for the servers that hold sending setups.5 | ||||||
| GET | /servers | List the servers on the account. | read | Account token | Current | |
Read-only. Needs the account token, not a server token. Acts onserver Permission (capability) Account tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /servers/{serverid} | Get the details of a single server. | read | Account token | Current | |
Read-only. Needs the account token. Acts onserver Permission (capability) Account tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /servers | Create a server, which provisions a new sending setup and its server token. | write | Account token | Current | |
Needs the account token. Mints a new server token an integration could then send with. Acts onserver Permission (capability) Account tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /servers/{serverid} | Edit a server's settings, like its name, tracking, and webhook URLs. | write | Account token | Current | |
Needs the account token. Can change where events are POSTed. Acts onserver Permission (capability) Account tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /servers/{serverid} | Delete a server from the account. | write | Account token | Current | |
Needs the account token. Removes the server and invalidates its token. Acts onserver Permission (capability) Account tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
DomainsAccount-level methods for sending domains and their DKIM and Return-Path setup.4 | ||||||
| GET | /domains | List the sending domains on the account with their authentication status. | read | Account token | Current | |
Read-only. Needs the account token. Acts ondomain Permission (capability) Account tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /domains | Add a sending domain to the account. | write | Account token | Current | |
Needs the account token. The domain must then pass DKIM and Return-Path checks. Acts ondomain Permission (capability) Account tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /domains/{domainid}/verifyDkim | Verify the DKIM DNS records for a domain. | write | Account token | Current | |
Needs the account token. Changes how the domain authenticates its mail. Acts ondomain Permission (capability) Account tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /domains/{domainid}/rotatedkim | Create a new DKIM key to replace the current one for a domain. | write | Account token | Current | |
Needs the account token. Requires updating DNS before the new key is active. Acts ondomain Permission (capability) Account tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Sender signaturesAccount-level methods for the verified from-addresses an account sends as.3 | ||||||
| GET | /senders | List the sender signatures, the verified from-addresses on the account. | read | Account token | Current | |
Read-only. Needs the account token. Acts onsignature Permission (capability) Account tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /senders | Create a sender signature for a from-address, which sends a confirmation email. | write | Account token | Current | |
Needs the account token. The address must confirm before it can send. Acts onsignature Permission (capability) Account tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /senders/{signatureid} | Delete a sender signature from the account. | write | Account token | Current | |
Needs the account token. Removes a verified sending identity. Acts onsignature Permission (capability) Account tokenVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Postmark can notify an app when something happens to a message, like a delivery confirming, an address bouncing, a recipient opening an email or clicking a link, or a spam complaint arriving. It POSTs a JSON payload with a RecordType naming the event, so an integration learns about activity without polling.
| Event | What it signals | Triggered by |
|---|---|---|
Delivery | A message was accepted by the recipient's mail server. Postmark POSTs a payload with RecordType Delivery. | /email/email/batch/email/withTemplate |
Bounce | A message could not be delivered and bounced, for example a hard bounce or a spam block. The payload carries the bounce Type and the affected address. | /email/email/batch/email/withTemplate |
SpamComplaint | A recipient marked a delivered message as spam, which deactivates the address for future sends. | /email/email/batch/email/withTemplate |
Open | A recipient opened a message that had open tracking enabled. The payload includes client, OS, and geographic detail. | /email/email/withTemplate |
Click | A recipient clicked a tracked link in a message that had link tracking enabled. | /email/email/withTemplate |
SubscriptionChange | A recipient's suppression status changed, for example an unsubscribe or a reactivation, on a broadcast stream. | /message-streams/{stream_id}/suppressions/message-streams/{stream_id}/suppressions/delete |
Inbound | An email arrived at an inbound address. Postmark parses it and POSTs the parsed message, including headers and attachments, to the inbound webhook URL. | /messages/inbound/{messageid}/retry |
Postmark does not publish a fixed request rate, but it returns a 429 response when calls arrive faster than acceptable use allows, and it caps batch sends, search results, and payload size.
Postmark does not publish a fixed request rate. It returns HTTP 429 (Rate Limit Exceeded) when requests arrive faster than acceptable use allows, with guidance to slow the query rate. The clearer ceilings are on volume per call: a batch send takes at most 500 messages, and a message search returns at most 10,000 results.
List and search endpoints use offset pagination through count and offset query parameters, where count sets the page size and offset skips ahead. A search returns a TotalCount alongside the page, and the documented maximum reachable through a single search is 10,000 messages.
A single email may carry up to 10 MB including attachments, while a batch request may carry up to 50 MB. A batch is capped at 500 messages, and a server may hold up to 100 templates.
The status codes an agent should handle, and what to do about each.
| Status | Code | Meaning | What to do |
|---|---|---|---|
| 401 | Unauthorized | The API token in the header is missing or incorrect, or the wrong token type was used for the endpoint, like a server token on an account-level call. | Send the correct token for the area: a server token for sending and messages, an account token for servers, domains, and senders. |
| 422 | Unprocessable Entity (ErrorCode) | The request was understood but rejected, like malformed JSON, an invalid field, an inactive recipient, or a missing sender signature. The body is { ErrorCode, Message } where ErrorCode is a Postmark-specific number. | Branch on ErrorCode, fix the named field or sender, and resend. The request is not retryable as-is. |
| 429 | Rate Limit Exceeded | Requests arrived faster than acceptable use of the API allows. | Slow the request rate and retry with backoff. |
| 500 | Internal Server Error | A Postmark-side error occurred while processing the request. In most cases the message is lost during processing. | Retry with backoff, and contact Postmark support if it persists. |
| 503 | Service Unavailable | Postmark API services are returning this during a planned outage, with an associated JSON body. | Wait and retry; check the Postmark status page for the maintenance window. |
Postmark does not use dated API versions. There is a single, continuously updated API, and notable changes ship through dated release notes rather than a version string a request can pin.
Postmark serves a single, continuously updated API with no dated or numbered version a request can pin. Notable additions and validation changes ship through dated release notes, so an integration follows those notes rather than upgrading a version.
An account-level API to erase recipient data for GDPR and CCPA compliance, automating data removal requests.
Validation of request headers and JSON body structure was tightened, so previously tolerated malformed requests now return a 422.
The API is no longer accessed through static IP allowlisting, changing how locked-down networks reach Postmark.
The Suppressions API gained the ability to reactivate addresses suppressed by an unsubscribe, alongside searching inactive addresses and their reason.
A dedicated /webhooks endpoint was introduced to create and manage event subscriptions, replacing per-event server settings.
There is nothing to pin; an integration tracks the dated release notes for changes.
Postmark API updates ↗Bollard AI sits between a team's AI agents and Postmark. Grant each agent exactly the access it needs, read or write, area by area, and every call is checked and logged.