Public Endpoints
These routes are public-facing and usually accessed from email links or embedded forms.
These routes are public-facing and usually accessed from email links or embedded forms.
Health check
GET /api/v1/health
Tracking
GET /t/o/:emailSendId(open pixel)GET /t/c/:emailSendId/:encodedUrl(click redirect + tracking)
Unsubscribe
POST /unsub/:token(RFC 8058 one-click unsubscribe)GET /unsub/verify/:token(validate token and fetch page context)
Preference center
GET /prefs/verify/:tokenPOST /prefs/update/:token
Contact double opt-in
GET /confirm/doi/verify?token=...POST /confirm/doi?token=...
Form submission
POST /forms/:formId
Campaign archive
GET /archive/:token— returns the archived HTML snapshot of a sent campaign
Public-facing endpoint for "View in Browser" links. Returns the campaign content as it appeared at send time.
200 OK — success bodies use the action-mode envelope { "ok": true, "data": { ... } }:
{
"ok": true,
"data": {
"html": "<html>...</html>",
"subject": "Our biggest sale of the year",
"sentAt": 1741616400000,
"organizationName": "Acme Inc."
}
}
sentAt is a Unix-millisecond timestamp (a number), not an ISO string.
404 Not Found — the token does not match any archived campaign. Failures use the locked error envelope:
{
"error": {
"category": "not_found",
"message": "Archive not found",
"data": { "reason": "archive_not_found" }
}
}
The archive token is unique per campaign and included in the email's "View in Browser" link. Archive endpoints are rate limited and CORS enabled. Successful responses set Cache-Control: public, max-age=3600.
Share link preview
GET /share/:token— returns the HTML snapshot of a shared email template preview
Public-facing endpoint for expiring share links created from the email editor. Returns the email content as it appeared when the link was created. Links expire after 48 hours.
Responses:
200 OK— valid share link. Success bodies use the action-mode envelope{ "ok": true, "data": { ... } }:
{
"ok": true,
"data": {
"html": "<html>...</html>",
"subject": "Welcome to our product",
"previewText": "Here's what you need to know",
"organizationName": "Acme Inc.",
"expiresAt": 1742486400000
}
}
expiresAt is a Unix-millisecond timestamp (a number).
404 Not Found— token is invalid or the link has been revoked. The locked error envelope carriescategory: "not_found"anddata.reason: "share_link_not_found":
{
"error": {
"category": "not_found",
"message": "Share link not found",
"data": { "reason": "share_link_not_found" }
}
}
- Expired link (48-hour window passed) —
data.reasonisexpired:
{
"error": {
"category": "not_found",
"message": "This share link has expired",
"data": { "reason": "expired" }
}
}
The expired case maps to HTTP 404 (not_found), not 410 Gone — the shell derives the status from the error category and has no 410 mapping. Discriminate on data.reason: "expired" rather than on the status code.
The share token is a 24-character random string. Share link endpoints set Cache-Control: no-store (unlike archive, which is cacheable for an hour) since the content expires.
Inbound MTA callbacks
These routes live on the same HTTP router but are server-to-server callbacks from the bundled MTA and IMAP services, not browser- or email-link flows. They are authenticated at the transport layer (shared secret / HMAC), so general clients should not call them.
POST /webhooks/mta-mailbox— Postbox (personal-mail) inbound delivery from the MTA. See Postbox Architecture.POST /webhooks/mta-verify-credential— app-password verification for MTA SMTP submission and IMAP/SMTP client auth (HMAC-signed). See Postbox Architecture.
The bounce/complaint/IP delivery-event callback POST /webhooks/mta is documented on the Webhooks page.
Notes
- CORS is enabled where required for browser-based flows
- Public endpoints are rate-limited by IP (per-recipient token endpoints such as archive/share/unsubscribe are keyed on IP+token)
- Tokenized endpoints return structured JSON for invalid/expired tokens