Webhooks
Get notified in real time when something happens to your email.
Webhooks send an HTTP POST to your application when an event happens: an email is delivered, bounces, is opened, an email is received, a contact unsubscribes. Use them to update your database, alert your team or trigger follow-ups, without polling the API.
Create a webhook
Add a webhook in the dashboard under Webhooks, or with the API. Choose the endpoint URL and the events to subscribe to:
curl -X POST https://api.usend.et/webhooks \
-H "Authorization: Bearer us_123456789" \
-H "Content-Type: application/json" \
-d '{
"endpoint": "https://acme.com/webhooks/usend",
"events": ["email.delivered", "email.bounced", "email.complained"]
}'{
"object": "webhook",
"id": "4dd369bc-aa82-4ff3-97de-514ae3000ee0",
"endpoint": "https://acme.com/webhooks/usend",
"events": ["email.delivered", "email.bounced", "email.complained"],
"enabled": true,
"signing_secret": "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw",
"created_at": "2026-10-11T08:00:00.000Z"
}Store signing_secret securely: you need it to verify signatures.
The endpoint must be a public http:// or https:// URL. Use HTTPS in production. Endpoints that resolve to private or loopback addresses are refused at delivery time.
Events
| Event | When |
|---|---|
email.queued | An email was accepted and queued. |
email.scheduled | An email was accepted with a future scheduled_at. |
email.sent | An email was handed to the sending infrastructure. |
email.delivered | The recipient's server accepted the email. |
email.delivery_delayed | Delivery failed temporarily and is being retried. |
email.bounced | The recipient's server rejected the email. |
email.complained | The recipient marked the email as spam. |
email.opened | The recipient opened the email (open tracking). |
email.clicked | The recipient clicked a link (click tracking). |
email.failed | usend could not send the email. |
email.canceled | A scheduled email was canceled. |
email.received | An email arrived on one of your receiving domains. |
contact.unsubscribed | A contact unsubscribed from a broadcast. |
See Event types for each payload.
The request
usend sends a POST with a JSON body:
{
"type": "email.delivered",
"created_at": "2026-10-11T09:12:47.118Z",
"data": {
"email_id": "4ef9a417-02e9-4d39-ad75-9611e0fcc33c",
"from": "Acme <[email protected]>",
"to": ["[email protected]"],
"subject": "Your receipt",
"created_at": "2026-10-11T09:12:43Z",
"tags": [{ "name": "category", "value": "receipt" }],
"recipient": "[email protected]"
}
}And these headers:
| Header | Description |
|---|---|
webhook-id | A unique ID for this event delivery (msg_...). It stays the same across retries. |
webhook-timestamp | Unix timestamp (seconds) of this attempt. |
webhook-signature | The signature: v1,<base64>. |
User-Agent | usend-Webhooks/1.0 |
Respond quickly
Return any 2xx status within 20 seconds to acknowledge the event. Anything else, including redirects and timeouts, counts as a failure and is retried. Do slow work in a background job after responding.
Events can arrive more than once and out of order. Use webhook-id to skip duplicates, and created_at to order events.
Manage webhooks
- Edit the endpoint or events with
PATCH /webhooks/{id}. - Pause a webhook with
PATCH /webhooks/{id}and{ "enabled": false }. Events are not delivered while it is disabled. - Delete it with
DELETE /webhooks/{id}. - Inspect deliveries in the dashboard or with
GET /webhooks/{id}/deliveries.
See the Webhooks API reference.