Emails API
Emails API
Send transactional emails and retrieve sending history.
Send Email
POST /v1/send
Send a transactional email to one or more recipients.
Usage is counted per accepted recipient. Recipients in to, cc, and bcc
each consume one unit of the shared monthly send + receive email quota.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
from | string | Yes | Sender email address (must be from a verified domain) |
to | array | Yes | Recipient email addresses |
cc | array | No | CC recipients |
bcc | array | No | BCC recipients |
subject | string | Conditional | Email subject (required unless using a template) |
html_body | string | Conditional | HTML body content (required if no text_body and no template) |
text_body | string | Conditional | Plain text body content (required if no html_body and no template) |
template | string | No | Template slug to use (mutually exclusive with inline subject/body) |
template_id | string | No | Template UUID to use (mutually exclusive with inline subject/body) |
variables | object | No | Variables to render into the template |
headers | object | No | Custom email headers |
tags | array | No | Tags for categorization |
metadata | object | No | Custom metadata |
You can either provide inline subject/html_body/text_body, or specify a template (slug) or template_id (UUID) with variables. You cannot combine both — the API will return a 400 error if both are set.
Example Request
curl -X POST https://api.postscale.io/v1/send \
-H "Authorization: Bearer ps_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"from": "orders@yourapp.com",
"to": ["customer@example.com"],
"subject": "Order Confirmation #12345",
"html_body": "<h1>Thank you for your order!</h1><p>Order #12345 has been confirmed.</p>",
"text_body": "Thank you for your order! Order #12345 has been confirmed.",
"tags": ["order", "confirmation"],
"metadata": {
"order_id": "12345",
"customer_id": "cust_abc"
}
}'
Example: Send with Template
curl -X POST https://api.postscale.io/v1/send \
-H "Authorization: Bearer ps_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"from": "orders@yourapp.com",
"to": ["customer@example.com"],
"template": "order-confirmation",
"variables": {
"first_name": "Jane",
"order_id": "12345",
"total": "$79.98"
}
}'
The template's subject, HTML body, and text body are rendered with the provided variables before sending. See Templates for details on template syntax.
Response
{
"message_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890@yourapp.com",
"status": "queued",
"warming_phase": "phase_1",
"remaining_today": 1500,
"remaining_this_hour": 100
}
List Emails
GET /v1/emails
Retrieve a list of sent emails with optional filtering.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
limit | integer | Number of results (default: 50, max: 100) |
offset | integer | Number of results to skip |
status | string | Filter by status: queued, processing, sent, delivered, bounced, deferred, or failed |
to | string | Filter by recipient address substring |
from | string | Filter by sender address substring |
subject | string | Filter by subject substring |
tag | string | Filter by exact tag |
isp | string | Filter by detected recipient ISP |
bounce_type | string | Filter by hard or soft bounce |
from_date | string | Created-at lower bound, as RFC 3339 or YYYY-MM-DD |
to_date | string | Created-at upper bound, as RFC 3339 or YYYY-MM-DD |
sort | string | Sort by created_at, updated_at, sent_at, delivered_at, status, subject, to, recipient_isp, or isp |
direction | string | asc or desc |
Example Request
curl -X GET "https://api.postscale.io/v1/emails?limit=50&status=bounced&sort=sent_at&direction=desc" \
-H "Authorization: Bearer ps_live_your_api_key"
Response
{
"emails": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"message_id": "abc123@yourapp.com",
"from": "orders@yourapp.com",
"to": "customer@example.com",
"recipients": ["customer@example.com"],
"subject": "Order Confirmation #12345",
"status": "delivered",
"isp": "gmail",
"sent_at": "2026-01-18T10:30:01Z",
"delivered_at": "2026-01-18T10:30:02Z",
"tags": ["orders"],
"metadata": { "order_id": "12345" }
}
],
"total": 1
}
Get Email
GET /v1/emails/:id
Retrieve details for a specific email.
Example Request
curl -X GET https://api.postscale.io/v1/emails/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
-H "Authorization: Bearer ps_live_your_api_key"
List Email Events
GET /v1/emails/:id/events
Retrieve the delivery lifecycle timeline for a specific email. Events include queue ID, recipient, relay host, delay, DSN code, bounce classification, and diagnostic text when available.
curl -X GET https://api.postscale.io/v1/emails/a1b2c3d4-e5f6-7890-abcd-ef1234567890/events \
-H "Authorization: Bearer ps_live_your_api_key"
{
"events": [
{
"event_type": "bounced",
"recipient": "customer@example.com",
"bounce_type": "hard",
"bounce_code": "550",
"dsn_code": "5.1.1",
"diag_message": "user unknown",
"relay_host": "mx.example.com",
"delay_seconds": 1.42,
"event_at": "2026-01-18T10:30:04Z"
}
]
}
Email Status Values
| Status | Description |
|---|---|
queued | Email accepted and queued for sending |
processing | Email is currently being prepared or handed to the MTA |
sent | Email handed to the local outbound MTA |
delivered | Recipient mail server accepted the message; inbox placement is not guaranteed |
failed | Email sending failed |
bounced | Email bounced (hard or soft bounce) |
deferred | Recipient mail server temporarily deferred the message |
Batch Sending
POST /v1/send/batch
Send up to 100 emails in a single request.
Request
{
"emails": [
{
"from": "newsletter@yourapp.com",
"to": ["user1@example.com"],
"subject": "Newsletter",
"html_body": "<p>Hello User 1</p>"
},
{
"from": "newsletter@yourapp.com",
"to": ["user2@example.com"],
"subject": "Newsletter",
"html_body": "<p>Hello User 2</p>"
}
]
}
Response
{
"queued": 2,
"failed": 0,
"results": [
{
"index": 0,
"message_id": "a1b2c3d4@yourapp.com",
"status": "queued"
},
{
"index": 1,
"message_id": "e5f67890@yourapp.com",
"status": "queued"
}
],
"warming_phase": "phase_1",
"remaining_today": 1498,
"remaining_this_hour": 98
}
Batch Sending with Templates
Each email in a batch can use a template instead of inline content. Templates are resolved once per unique slug/ID for efficiency:
{
"emails": [
{
"from": "orders@yourapp.com",
"to": ["user1@example.com"],
"template": "order-confirmation",
"variables": { "first_name": "Alice", "order_id": "001" }
},
{
"from": "orders@yourapp.com",
"to": ["user2@example.com"],
"template": "order-confirmation",
"variables": { "first_name": "Bob", "order_id": "002" }
}
]
}
For very high volumes (100K+/day), contact us about dedicated infrastructure and optimized sending.