Migrate from Postmark
Step-by-step guide to switch from Postmark to Postkit
Postmark and Postkit have different API conventions -- most notably JSON field naming and authentication. Postmark uses PascalCase fields and a custom X-Postmark-Server-Token header, while Postkit uses snake_case and standard Authorization: Bearer headers. This guide maps Postmark concepts to Postkit and walks you through the structural changes.
Key differences
| Feature | Postmark | Postkit |
|---|---|---|
| Auth header | X-Postmark-Server-Token: token | Authorization: Bearer pk_live_... |
| JSON style | PascalCase (HtmlBody, TextBody, MessageID) | snake_case (html, text, id) |
| Webhook signing | None (Basic Auth + IP allowlist) | HMAC-SHA256 with whsec_ shared secret |
| Template sending | Separate POST /email/withTemplate endpoint | Unified POST /v1/emails with template_id field |
| Message Streams | Separate transactional/broadcast streams | Unified API with tags for categorization |
Endpoint mapping
| Operation | Postmark | Postkit |
|---|---|---|
| Send email | POST /email | POST /v1/emails |
| Send batch | POST /email/batch (500 max) | POST /v1/emails/batch (100 max) |
| Send with template | POST /email/withTemplate | POST /v1/emails with template_id |
| Create template | POST /templates | POST /v1/templates |
| Domain auth | Sender Signatures / Domains | POST /v1/domains |
| Webhooks | Per Message Stream config | POST /v1/webhooks with event subscription |
| Suppressions | GET /message-streams/{id}/suppressions | GET /v1/suppressions |
Step-by-step migration
Get your Postkit API key
Sign up at app.postkit.eu and create an API key in Settings > API Keys. Production keys start with pk_live_. For testing the migration without sending real emails, create a sandbox key starting with pk_test_.
Update authentication
Replace Postmark's custom X-Postmark-Server-Token header with the standard Authorization: Bearer header.
Before (Postmark):
curl -X POST "https://api.postmarkapp.com/email" \
-H "X-Postmark-Server-Token: your-server-token" \
-H "Content-Type: application/json"After (Postkit):
curl -X POST https://api.postkit.eu/v1/emails \
-H "Authorization: Bearer pk_live_abc123..." \
-H "Content-Type: application/json"Update JSON field names
This is the most impactful change. Postmark uses PascalCase for all JSON fields, while Postkit uses snake_case.
Before (Postmark):
{
"From": "you@yourdomain.com",
"To": "user@example.com",
"Subject": "Hello from Postmark",
"HtmlBody": "<h1>Hello</h1>",
"TextBody": "Hello",
"ReplyTo": "reply@yourdomain.com",
"Tag": "welcome"
}After (Postkit):
{
"from": "you@yourdomain.com",
"to": ["user@example.com"],
"subject": "Hello from Postkit",
"html": "<h1>Hello</h1>",
"text": "Hello",
"reply_to": "reply@yourdomain.com",
"tags": ["welcome"]
}Common field mappings:
| Postmark | Postkit |
|---|---|
HtmlBody | html |
TextBody | text |
Subject | subject |
From | from |
To | to (array) |
ReplyTo | reply_to |
Cc | cc |
Bcc | bcc |
Tag | tags (array) |
MessageID | id |
Note that to in Postkit is always an array of email addresses, and tags is an array (not a single string). Postmark's single To string becomes a one-element array.
Unify template sending
Postmark uses a separate endpoint for template-based emails (POST /email/withTemplate). Postkit uses the standard send endpoint with a template_id field.
Before (Postmark):
// POST /email/withTemplate
{
"TemplateId": 12345,
"TemplateModel": {
"name": "User",
"action_url": "https://example.com/welcome"
},
"From": "you@yourdomain.com",
"To": "user@example.com"
}After (Postkit):
// POST /v1/emails
{
"from": "you@yourdomain.com",
"to": ["user@example.com"],
"template_id": "tmpl_abc123...",
"template_data": {
"name": "User",
"action_url": "https://example.com/welcome"
}
}Add webhook signing
Postmark does not sign webhook payloads -- it relies on Basic Auth and IP allowlisting for security. Postkit uses HMAC-SHA256 signing with a shared secret (prefixed whsec_), following the Standard Webhooks specification.
When you create a webhook in Postkit, you receive a signing_secret. Add signature verification to your webhook handler using the webhook-id, webhook-timestamp, and webhook-signature headers.
See the Webhooks guide for complete verification examples in multiple languages.
Verify your domain
Add your sending domain in Postkit and configure the DNS records (DKIM, SPF, DMARC). Postmark uses "Sender Signatures" and "Domains" -- Postkit unifies domain management under a single /v1/domains endpoint.
See the Domain Setup guide for step-by-step DNS configuration instructions.
Test with sandbox keys
Use a pk_test_ key to verify your integration end-to-end without delivering actual emails. Once everything works as expected, switch to your pk_live_ key for production.
What's next?
- Quickstart -- send your first email with Postkit
- Domain Setup -- configure DNS records for production sending
- Webhooks -- set up webhook endpoints and signature verification