Authentication
Create a key in Settings → API keys. Send it with every request:
Authorization: Bearer pm_live_xxxxxxxxxxxxxxxxxxxx
Base URL: https://postaramail.com/api/v1. Requests and responses are JSON. Keep keys on your server; never put them in website code that visitors can see.
Limits and errors
Each key can make 120 requests per minute. Errors return an HTTP status and a JSON body:
{ "error": { "code": "consent_required", "message": "Set \"consent\": true to confirm…" } }
| Status | Meaning |
|---|---|
| 401 | Missing, invalid or revoked key |
| 403 | Plan doesn't include the API, or subscriber limit reached |
| 404 | Not found |
| 409 | Conflict, e.g. the contact unsubscribed |
| 422 | Invalid input |
| 429 | Too many requests |
Account
GET /me
Your workspace, plan, subscriber count and emails sent this month.
curl https://postaramail.com/api/v1/me \
-H "Authorization: Bearer $POSTARAMAIL_KEY"
Contacts
POST /contacts
Add a subscriber. consent must be true: it confirms the person agreed to receive your emails. New contacts start any automation set to "start for new contacts" (send "start_automations": false to skip). People who unsubscribed, bounced or complained are never re-subscribed (409). If the email already exists and is subscribed, you get 200 with "created": false.
curl -X POST https://postaramail.com/api/v1/contacts \
-H "Authorization: Bearer $POSTARAMAIL_KEY" \
-H "Content-Type: application/json" \
-d '{"email":"sam@example.com","first_name":"Sam","consent":true}'
{ "data": { "id": 42, "email": "sam@example.com", "first_name": "Sam", "last_name": null,
"status": "subscribed", "source": "api", "created_at": "…", "updated_at": "…" }, "created": true }
GET /contacts
List contacts, newest first. Query: limit (1–100, default 25), page, status (subscribed, unsubscribed, bounced, complained), email.
GET /contacts/:id
One contact.
PATCH /contacts/:id
Update first_name and last_name, or set "status": "unsubscribed". Re-subscribing isn't possible through the API.
DELETE /contacts/:id
Delete a contact permanently.
Automations
GET /automations
Your automations with their status, number of steps and contacts in progress.
POST /automations/:id/enroll
Add an existing subscribed contact to an active automation. Send contact_id or email. Contacts already in the automation are not added twice.
curl -X POST https://postaramail.com/api/v1/automations/3/enroll \
-H "Authorization: Bearer $POSTARAMAIL_KEY" \
-H "Content-Type: application/json" \
-d '{"email":"sam@example.com"}'
Emails and campaigns
GET /emails
Your saved emails (id, name, subject, whether it's a designed template).
GET /campaigns and GET /campaigns/:id
Campaign status and results: recipients, sent, failed, skipped, opened and clicked.
Campaigns are sent from the PostaraMail app, where you review each email before it goes out. The API doesn't send campaigns.
Example: website signup form
Post the form to your own server, then call the API from there:
// Node.js (server side)
await fetch('https://postaramail.com/api/v1/contacts', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.POSTARAMAIL_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ email, first_name: firstName, consent: true })
});
Only send consent: true when the person ticked a box or otherwise clearly agreed to receive your emails.