Webhooks
Receive signed HTTP callbacks for email lifecycle events.
Base URL: https://api.supersendtx.com
Manage endpoints in the dashboard (Webhooks) or via the API / SDK / CLI below.
Authentication
Authorization: Bearer stx_…Dashboard session cookies also work for browser requests to /api/webhooks.
Supported events
| Event | When fired |
|---|---|
email.received |
An inbound email arrived on a receive-enabled domain; retrieve full content from /received-emails/{id} |
email.sent |
SuperSend TX accepted the message for delivery |
email.delivered |
The message was delivered to the recipient mailbox provider |
email.delivery_delayed |
Delivery was delayed or temporarily held |
email.bounced |
Hard/soft bounce; recipient is auto-suppressed |
email.complained |
Recipient marked the message as spam/complaint |
email.opened |
Open pixel loaded when open tracking is on |
email.clicked |
Tracked link clicked when click tracking is on |
email.failed |
Delivery failed |
email.suppressed |
Send blocked because a recipient is on the suppression list |
email.scheduled |
Email accepted with scheduled_at |
automation.started |
An active automation matched an incoming event and a run was created |
automation.step_completed |
One automation step completed successfully |
automation.completed |
A run finished all steps (or ended early on a false condition) |
automation.failed |
A run failed (send failure, timeout, validation, etc.) |
Open/click tracking are domain settings (open_tracking / click_tracking) configured per domain.
Create endpoint
POST /webhooks
{
"url": "https://yourapp.com/webhooks/supersendtx",
"events": ["email.delivered", "email.bounced"]
}events is optional — defaults to all supported events.
200 — Created
{
"webhook": {
"id": "clx…",
"url": "https://yourapp.com/webhooks/supersendtx",
"events": ["email.delivered", "email.bounced"],
"enabled": true,
"created_at": "2026-07-25T12:00:00.000Z",
"updated_at": "2026-07-25T12:00:00.000Z"
},
"secret": "whsec_…"
}Copy secret immediately — it is only returned once. Use it to verify incoming webhook signatures.
List endpoints
GET /webhooks
Cursor pagination: limit, cursor → { webhooks, has_more, next_cursor }.
Retrieve endpoint
GET /webhooks/{id}
{
"webhook": {
"id": "clx…",
"url": "https://yourapp.com/webhooks/supersendtx",
"events": ["email.delivered", "email.bounced"],
"enabled": true,
"created_at": "2026-07-25T12:00:00.000Z",
"updated_at": "2026-07-25T12:00:00.000Z"
}
}Update endpoint
PATCH /webhooks/{id}
{
"url": "https://yourapp.com/new-path",
"events": ["email.bounced"],
"enabled": false
}All fields are optional.
Delete endpoint
DELETE /webhooks/{id}
{ "ok": true }Test sink
POST /emails/test (full-scope API key)
{ "event": "email.bounced", "email_id": "msg_…", "deliver": true }Builds a webhook payload (optionally for an existing email) and, when deliver is not false, enqueues delivery to your subscribed endpoints. Useful in CI.
Incoming webhook payload
SuperSend TX POSTs JSON to your endpoint URL when a subscribed event occurs.
Email event example
{
"type": "email.received",
"created_at": "2026-07-25T12:05:00.000Z",
"data": {
"email_id": "inb_abc123…",
"to": ["sales@inbound.example.com"],
"from": "Sender <sender@example.com>",
"subject": "Hello",
"status": "received",
"rcpt_to": "sales@inbound.example.com",
"cc": [],
"message_id": "<abc@example.com>",
"in_reply_to": null,
"references": [],
"spam_status": "NotSpam",
"attachment_count": 1,
"attachments": [
{
"filename": "invoice.pdf",
"content_type": "application/pdf",
"size": 48291
}
],
"received_at": "2026-07-25T12:04:59.000Z"
}
}For inbound events, attachment metadata is included but attachment bytes are not — fetch /received-emails/{id} for full bodies and base64 attachment data.
For bounces, type is email.bounced, status is bounced, and bounce_reason may contain a provider reason string.
Automation event example
{
"type": "automation.step_completed",
"created_at": "2026-07-26T12:05:00.000Z",
"data": {
"automation_id": "a1b2c3",
"automation_name": "Welcome flow",
"run_id": "r1s2t3",
"status": "running",
"event_name": "user.created",
"step_index": 0,
"step_type": "send_email",
"error": null
}
}Signature verification
Each delivery includes:
SuperSendTX-Signature: t=1721908800,v1=abc123…SDK helper (preferred)
import { SuperSendTX, verifyWebhookSignature } from 'supersendtx'
const ok = verifyWebhookSignature(secret, rawBody, request.headers.get('supersendtx-signature'))
// or:
const client = new SuperSendTX(process.env.SUPERSENDTX_API_KEY!)
client.webhooks.verify(secret, rawBody, header)Verify by:
- Read the raw request body as a string (before JSON parsing).
- Parse
t(Unix timestamp) andv1(hex HMAC) from the header. - Reject if
tis more than 5 minutes from your server clock. - Compute
HMAC-SHA256(secret, "${t}.${rawBody}")and compare tov1(constant-time).
Return 2xx quickly from your handler. Failed deliveries are retried by Bull at 0s, 5s, 30s, 2m, 2m (persisted in Redis via the supersendtx:webhook-delivery queue). Run the worker:webhooks process alongside the app.
SDK
import { SuperSendTX } from 'supersendtx'
const client = new SuperSendTX(process.env.SUPERSENDTX_API_KEY!)
const { webhook, secret } = await client.webhooks.create({
url: 'https://yourapp.com/webhooks/supersendtx',
})
const { webhooks } = await client.webhooks.list()
const one = await client.webhooks.get(webhooks[0].id)
await client.webhooks.update(one.webhook.id, { enabled: false })
await client.webhooks.delete(webhooks[0].id)CLI
supersendtx webhooks list
supersendtx webhooks create --url https://yourapp.com/hooks
supersendtx webhooks delete --id clx…Requires SUPERSENDTX_API_KEY or --api-key.
OpenAPI
Machine-readable spec: openapi/supersendtx.yaml