---
name: webhooks
description: tinysend webhooks — subscribe to 36 real-time events across posts, emails, subscribers, contacts, newsletters, and mailboxes, with HMAC-SHA256 signature verification, retries, and delivery history. use when reacting to tinysend events from another system.
license: MIT
compatibility: requires network access to api.tinysend.com (see the platform skill for auth)
---

# webhooks

receive real-time HTTP POST notifications when events happen in tinysend.

## setup

1. create a subscription with a URL and list of events
2. tinysend sends a test event to verify your endpoint
3. save the `secret` from the response — shown only once

```
POST /v1/webhooks
{
  "url": "https://example.com/webhook",
  "events": ["post.sent", "subscriber.created"]
}
```

## events

36 events across 8 entities, all using entity.action naming:

post: post.created, post.updated, post.sent, post.delivered, post.paused, post.resumed, post.cancelled, post.viewed, post.liked
email: email.received, email.sent, email.delivered, email.bounced, email.opened, email.clicked, email.complained, email.replied
subscriber: subscriber.created, subscriber.confirmed, subscriber.unsubscribed, subscriber.deleted
contact: contact.created, contact.updated, contact.deleted
contact group: contact_group.created, contact_group.updated, contact_group.deleted
list: list.created, list.updated, list.deleted
mailbox: mailbox.created, mailbox.updated, mailbox.deleted
calendar: calendar_event.created, calendar_event.updated, calendar_event.deleted

## payload

every delivery uses this envelope:

```json
{
  "id": "01jx...",
  "type": "post.sent",
  "created_at": "2025-06-09T12:00:00Z",
  "data": {
    "post_id": "01jx...",
    "list_id": "01jx...",
    "subject": "Weekly update"
  }
}
```

## signature verification

each delivery includes an HMAC-SHA256 signature in `X-Tinysend-Signature`, computed with your subscription secret.

```javascript
const expected = crypto
  .createHmac('sha256', secret)
  .update(rawBody)
  .digest('hex');
const valid = crypto.timingSafeEqual(
  Buffer.from(signature),
  Buffer.from(expected)
);
```

## headers

- X-Tinysend-Event — event type (e.g. post.sent)
- X-Tinysend-Signature — HMAC-SHA256 hex signature
- X-Tinysend-Delivery-Id — unique delivery ID for idempotency

## delivery

- timeout: 10 seconds
- retries: 3 attempts with backoff
- auto-disable: after 10 consecutive failures
- your endpoint must return 2xx to acknowledge

## managing subscriptions

```
POST   /v1/webhooks                create subscription
GET    /v1/webhooks                list subscriptions
GET    /v1/webhooks/:id            subscription details
PATCH  /v1/webhooks/:id            update URL, events, or status
DELETE /v1/webhooks/:id            delete subscription
POST   /v1/webhooks/:id/test       send test event
GET    /v1/webhooks/:id/deliveries list recent deliveries
```
