Send — Transactional Email
Send transactional emails through waypoints' own Postal SMTP infrastructure. Supports custom sending domains, HTML and plain-text bodies, file attachments, delivery tracking, and full log access via API.
/api/v1/send/emailSend a single transactional email. The from address must use a verified sending domain. See the Custom Domains section below to set one up.
| Parameter | Type | Required | Description |
|---|---|---|---|
| from | string | yes | Sender address — must use a verified domain, e.g. hello@yourapp.com |
| to | string | yes | Recipient email address |
| subject | string | yes | Email subject line |
| html | string | one of | HTML body of the email |
| text | string | one of | Plain-text body of the email (recommended as fallback) |
| replyTo | string | no | Reply-to address if different from from |
| attachments | object[] | no | Array of { filename: string, content: string (base64) } |
| tags | string[] | no | Array of tag strings for log filtering, e.g. ["transactional", "welcome"] |
cURL
curl -X POST https://api.waypoints.tech/v1/send/email \
-H "x-api-key: wp_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"from": "hello@yourapp.com",
"to": "user@example.com",
"subject": "Welcome to yourapp!",
"html": "<h1>Welcome!</h1><p>Thanks for signing up.</p>",
"text": "Welcome! Thanks for signing up.",
"tags": ["transactional", "welcome"]
}'SDK (@waypoints/sdk)
import waypoints from "@waypoints/sdk";
const wp = new waypoints({ apiKey: process.env.WAYPOINTS_API_KEY });
const result = await wp.send.email({
from: "hello@yourapp.com",
to: "user@example.com",
subject: "Welcome to yourapp!",
html: "<h1>Welcome!</h1><p>Thanks for signing up.</p>",
text: "Welcome! Thanks for signing up.",
tags: ["transactional", "welcome"],
});
console.log(result.id); // "msg_01jx..."
console.log(result.status); // "queued"SDK — with attachment
import { readFileSync } from "fs";
const pdfBuffer = readFileSync("./invoice.pdf");
const base64 = pdfBuffer.toString("base64");
const result = await wp.send.email({
from: "billing@yourapp.com",
to: "client@example.com",
subject: "Your invoice #1042",
html: "<p>Please find your invoice attached.</p>",
attachments: [
{ filename: "invoice-1042.pdf", content: base64 },
],
});Response
{
"id": "msg_01jx9k2m3n4p5q6r7s8t9u0v",
"status": "queued",
"credits_used": 1,
"request_id": "req_01jx9k2m3n4p5q6r7s8t9u0v"
}| Status | Meaning |
|---|---|
| queued | Email accepted by Postal and queued for delivery |
| delivered | Email confirmed delivered to recipient mail server |
| bounced | Delivery failed — recipient address does not exist or rejected |
| complained | Recipient marked the email as spam |
/api/v1/send/logsRetrieve paginated email delivery logs for your account. Filter by status, date range, and recipient to monitor delivery health.
| Query param | Type | Description |
|---|---|---|
| status | string | Filter by delivery status: queued, delivered, bounced, complained |
| from | string | ISO date string — only return logs on or after this date |
| to | string | ISO date string — only return logs on or before this date |
| limit | number | Number of results per page (default: 50, max: 200) |
| cursor | string | Pagination cursor from previous response |
cURL
curl "https://api.waypoints.tech/v1/send/logs?status=bounced&limit=20" \
-H "x-api-key: wp_live_your_key_here"Response
{
"logs": [
{
"id": "msg_01jx...",
"from": "hello@yourapp.com",
"to": "user@example.com",
"subject": "Welcome to yourapp!",
"status": "delivered",
"delivered_at": "2026-03-21T14:32:00Z",
"opened_at": "2026-03-21T14:35:22Z",
"created_at": "2026-03-21T14:31:58Z"
}
],
"next_cursor": "cursor_01jx...",
"has_more": true
}Custom Domain Setup
To send emails from your own domain (e.g. hello@yourapp.com), you must verify the domain by adding DNS records. This protects deliverability and prevents spoofing.
1Register your domain
curl -X POST https://api.waypoints.tech/v1/send/domains \
-H "x-api-key: wp_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{ "domain": "yourapp.com" }'waypoints returns the required DNS records (SPF, DKIM, DMARC) for you to add at your DNS provider.
2Add DNS records
| Type | Name | Value | Purpose |
|---|---|---|---|
| TXT | @ | v=spf1 include:postal.waypoints.tech ~all | SPF — authorises waypoints to send on your behalf |
| TXT | postal._domainkey | v=DKIM1; k=rsa; p=<provided> | DKIM — cryptographic signature |
| TXT | _dmarc | v=DMARC1; p=quarantine; rua=... | DMARC — policy for unauthenticated mail |
DNS propagation typically takes 5–30 minutes, but can take up to 48 hours in some regions.
3Verify in the dashboard
Open the waypoints dashboard → Sending Domains → click Verify. Once SPF, DKIM, and DMARC all show green, you can send from that domain immediately.
Notes
Postal webhook
Delivery status updates (delivered, bounced, complained) are pushed to waypoints via a Postal webhook and stored in your email logs in Convex in real time. No polling required.
Attachment limits
Maximum total attachment size is 10 MB per email. Attachments are base64-encoded in the request body. For larger files, upload to storage first and link to the download URL in the email body.
Sandbox keys
Emails sent using wp_test_ keys are accepted and logged but NOT actually delivered. Use sandbox keys during development to avoid sending real emails and wasting credits.
Unsubscribe compliance
waypoints is a transactional email service. Marketing emails (newsletters, promotions) sent through waypoints violate the terms of service. Use a dedicated marketing platform for bulk campaigns.