Events are Buttondown's way of telling you that something interesting has happened to your newsletter, and webhooks let you react to those events by sending HTTP requests to a URL of your choice. For technical details on event payloads and HMAC signing, see the API reference.
Creating webhooks
Step 1: Navigate to integrations
- Log into your Buttondown account
- Go to Settings
- Click the Create webhook button:
Step 2: Configure webhook settings
You'll need to provide the following information:
Webhook URL
Enter the URL where Buttondown should send event data. This URL is typically provided by:
- Third-party services (Discord, Slack, etc.)
- Automation platforms (Zapier, Make, n8n)
- Your own application endpoint
The URL must be publicly reachable from the internet — Buttondown cannot deliver to localhost, private IP ranges, or endpoints behind a VPN. For local development, use a tunneling service like ngrok or Cloudflare Tunnel.
Events to trigger
Select which events should trigger your webhook. Common event types include:
| Event Type | Description |
|---|---|
| subscriber.created | When someone subscribes to your newsletter |
| subscriber.confirmed | When a subscriber confirms their email |
| subscriber.unsubscribed | When someone unsubscribes |
| email.sent | When you send a newsletter |
| email.delivered | When an email is successfully delivered |
| comment.created | When someone comments on your newsletter |
You can select multiple events for a single webhook.
Signing key (optional but recommended)
If you set a signing key, Buttondown will include an X-Buttondown-Signature: sha256=<hmac> header on every request, computed as HMAC-SHA256 of the raw request body using your key. Verify it on your side before trusting the payload. See the API reference for ready-to-paste verification snippets in Python, Node.js, and Ruby.
Step 3: Test your webhook
Once you've configured your webhook, it's recommended to test it:
- Click the Test webhook button
- Buttondown will send a test payload to your URL
- Verify that your receiving service gets the test data
What to expect on the wire
When designing your endpoint, plan for the following behavior:
- Method and content type. Every webhook is a
POSTwithContent-Type: application/json. The body is a single JSON object containingevent_typeanddata. - Success criteria. Buttondown only treats a delivery as successful if your endpoint returns a
2xxstatus code (200–299). Any3xx,4xx, or5xxresponse — as well as connection errors and timeouts — is treated as a failure and queued for retry. - Retries. Failed deliveries are retried up to 5 times before being abandoned. Retries are spaced out (roughly 5 minutes apart) and run independently per event, so a brief outage on your side won't drop everything in flight.
- Auto-disable. If the same webhook fails on 5 consecutive events, Buttondown disables it and sends an email so you can investigate. You'll need to re-enable it from the webhook settings page once you've fixed the underlying issue.
- Ordering. Events are not guaranteed to arrive in the order they happened. If ordering matters to you, treat the event payload as a notification and re-fetch the canonical resource via the API.
- At-least-once delivery. Retries mean the same event may be delivered more than once. Use the event's
idfield to dedupe on your end. - Payload size. Webhook payloads are capped at 10 MB. In practice events are well under a kilobyte, but if you build a webhook that fans out into a much larger payload (e.g. via an automation action), keep this in mind.
- No fixed source IP. Buttondown does not deliver from a stable set of IPs, so don't rely on IP allowlisting for authentication. Use the signing key instead.
Best practices for webhook handlers
- Respond fast — do work later. Acknowledge with a
2xximmediately and do any heavy processing on a background queue. Slow endpoints get retried as failures and can trigger auto-disable. - Be idempotent. Track which event
ids you've already processed (e.g. in a small table or cache) and short-circuit duplicates. - Verify the signature on the raw body. Don't re-serialize the JSON before computing the HMAC — bytes-in, bytes-out, or the signatures won't match.
- Log failures with the response body. When a delivery fails, Buttondown stores the response status and the first portion of the response body in the deliveries panel — make sure your error responses are descriptive enough to debug from.
Inspecting deliveries
Every webhook page includes a deliveries panel showing each recent attempt, the response status, and a snippet of the response body. This is the fastest way to diagnose why a webhook isn't behaving the way you expect — start here before reaching out to support.