Command Palette

Search for a command to run...

API Reference

Webhooks

Receive real-time notifications about email events. Configure endpoints to receive webhooks for delivery, opens, clicks, bounces, and more.

Available Events

EventDescription
email.sentEmail was sent to the recipient
email.deliveredEmail was delivered to inbox
email.openedRecipient opened the email
email.clickedRecipient clicked a link
email.bouncedEmail bounced (hard or soft)
email.complainedRecipient marked as spam
email.failedEmail failed to send
POST/v1/webhooks

Create a Webhook

Request Body

ParameterTypeRequiredDescription
urlstringRequiredHTTPS endpoint URL
eventsstring[]RequiredEvents to subscribe to (min: 1)
cURL
curl -X POST https://www.unosend.co/api/v1/webhooks \
  -H "Authorization: Bearer un_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://yourdomain.com/webhooks/unosend",
    "events": ["email.delivered", "email.opened", "email.clicked", "email.bounced"]
  }'

Response

201 Created
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "url": "https://yourdomain.com/webhooks/unosend",
  "events": ["email.delivered", "email.opened", "email.clicked", "email.bounced"],
  "secret": "whsec_xxxxxxxxxxxxxxxxxxxx",
  "enabled": true,
  "created_at": "2024-01-15T10:30:00.000Z"
}

Important: The signing secret is only returned once during creation. Store it securely to verify webhook signatures.

GET/v1/webhooks

List Webhooks

cURL
curl https://www.unosend.co/api/v1/webhooks \
  -H "Authorization: Bearer un_your_api_key"

Response

200 OK
{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "url": "https://yourdomain.com/webhooks/unosend",
      "events": ["email.delivered", "email.opened", "email.clicked", "email.bounced"],
      "enabled": true,
      "created_at": "2024-01-15T10:30:00.000Z"
    }
  ]
}

Webhook Payload

Webhooks are sent as HTTP POST requests with a JSON payload:

Webhook Payload
{
  "id": "evt_xxxxxxxxxxxxxxxx",
  "type": "email.delivered",
  "created_at": "2024-01-15T10:30:00.000Z",
  "data": {
    "email_id": "550e8400-e29b-41d4-a716-446655440000",
    "from": "hello@yourdomain.com",
    "to": "user@example.com",
    "subject": "Welcome to Unosend",
    "timestamp": "2024-01-15T10:30:00.000Z"
  }
}

Verify Webhook Signature

Verify the webhook signature to ensure it came from Unosend. The signature is in the X-Unosend-Signature header.

Node.js
import crypto from 'crypto';

function verifyWebhook(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

// In your webhook handler
app.post('/webhooks/unosend', (req, res) => {
  const signature = req.headers['x-unosend-signature'];
  const isValid = verifyWebhook(
    JSON.stringify(req.body),
    signature,
    process.env.WEBHOOK_SECRET
  );
  
  if (!isValid) {
    return res.status(401).send('Invalid signature');
  }
  
  // Process the webhook
  const { type, data } = req.body;
  console.log('Received:', type, data);
  
  res.status(200).send('OK');
});
DELETE/v1/webhooks/:id

Delete Webhook

cURL
curl -X DELETE https://www.unosend.co/api/v1/webhooks/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer un_your_api_key"