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

FieldTypeRequiredDescription
fromstringYesSender email address (must be from a verified domain)
toarrayYesRecipient email addresses
ccarrayNoCC recipients
bccarrayNoBCC recipients
subjectstringConditionalEmail subject (required unless using a template)
html_bodystringConditionalHTML body content (required if no text_body and no template)
text_bodystringConditionalPlain text body content (required if no html_body and no template)
templatestringNoTemplate slug to use (mutually exclusive with inline subject/body)
template_idstringNoTemplate UUID to use (mutually exclusive with inline subject/body)
variablesobjectNoVariables to render into the template
headersobjectNoCustom email headers
tagsarrayNoTags for categorization
metadataobjectNoCustom metadata
Template vs inline content

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

ParameterTypeDescription
limitintegerNumber of results (default: 50, max: 100)
offsetintegerNumber of results to skip
statusstringFilter by status: queued, processing, sent, delivered, bounced, deferred, or failed
tostringFilter by recipient address substring
fromstringFilter by sender address substring
subjectstringFilter by subject substring
tagstringFilter by exact tag
ispstringFilter by detected recipient ISP
bounce_typestringFilter by hard or soft bounce
from_datestringCreated-at lower bound, as RFC 3339 or YYYY-MM-DD
to_datestringCreated-at upper bound, as RFC 3339 or YYYY-MM-DD
sortstringSort by created_at, updated_at, sent_at, delivered_at, status, subject, to, recipient_isp, or isp
directionstringasc 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

StatusDescription
queuedEmail accepted and queued for sending
processingEmail is currently being prepared or handed to the MTA
sentEmail handed to the local outbound MTA
deliveredRecipient mail server accepted the message; inbox placement is not guaranteed
failedEmail sending failed
bouncedEmail bounced (hard or soft bounce)
deferredRecipient 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" }
    }
  ]
}
High-volume sending

For very high volumes (100K+/day), contact us about dedicated infrastructure and optimized sending.