Get events with webhooks
Have Eden post sales, signups, bookings, scheduled posts, and more to your own app or automation tool the moment they happen.
Go to Settings → API, click Add endpoint under Webhooks, paste an https address, and pick your events. Eden posts each event there as it happens, signed with the webhook's secret.
Add a webhook
- 01
Open Settings → API
Webhooks belong to the workspace you have open, and get that workspace's store and post events. Have more than one workspace? Open the right one first.
- 02
Click Add endpoint
Paste the address that should get events. It must start with
https://and be on the public internet. - 03
Pick events
Keep All events, including new ones, or untick it and pick only the ones you need.
- 04
Copy the signing secret
Eden shows it once. You only need it if your own code checks signatures.
Click a webhook to Send test event, Roll secret, Turn off, or Delete it. Recent deliveries shows the last 30 days, with Resend on each one.
Webhooks need Starter or above, and up to 20 fit in each workspace. You don't need a store: post events work in any workspace, and store events start once you set up a store.
Events
| Group | Events |
|---|---|
| Sales | purchase.created, purchase.refunded, purchase.membership_ended, membership.renewed, membership.cancelled |
| Customers | customer.created, affiliate_sale.created |
lead.created, contact.tagged, form.completed | |
| Calls | booking.created, booking.cancelled, booking.rescheduled, coaching_application.created |
| Courses and reviews | lesson.completed, lesson_question.created, cohort_signup.created, review.created, testimonial.created |
| Ask me | paid_question.created |
| Posts | post.published, post.failed |
purchase.created covers Eden checkout, free claims, and sales your own checkout reports to Eden.
Post events
post.published fires when a scheduled post goes out on at least one platform. post.failed fires when it fails on every platform. Eden sends either one once every platform is done, so a post that waits on Substack sends when Substack finishes.
data has post_id, status (posted, partial, or failed), text, scheduled_for, posted_at, url (the first live link), links, error, and platforms: one entry per platform with its status, url, and error. They go to the webhooks of the post's workspace.
What Eden sends
A JSON POST like this:
{
"id": "evt_3f2a9c0d8b7e4a51a2c3d4e5f6a7b8c9",
"type": "booking.created",
"created_at": "2026-10-04T17:00:00.000Z",
"store": { "handle": "yourname" },
"data": { "id": "booking:abc", "email": "[email protected]" }
}
data has the same fields as the matching list in the API reference. The five sale, signup, and form events keep the fields the store webhook always sent.
Each event comes once per webhook. If one could arrive twice (a resend, a retry after your app timed out), use id to skip the repeat.
Check the signature
Every post has these headers:
X-Eden-Signature:sha256=and an HMAC-SHA256 of<timestamp>.<body>made with your secret.X-Eden-Timestamp: when Eden signed it, in milliseconds.X-Eden-EventandX-Eden-Event-Id: the type and theid.
import { createHmac, timingSafeEqual } from "node:crypto";
function fromEden(rawBody, headers, secret) {
const expected = createHmac("sha256", secret)
.update(`${headers["x-eden-timestamp"]}.${rawBody}`)
.digest("hex");
const given = String(headers["x-eden-signature"]).replace("sha256=", "");
return (
given.length === expected.length && timingSafeEqual(Buffer.from(given), Buffer.from(expected))
);
}
The same check in Python:
import hashlib, hmac
def from_eden(raw_body: bytes, headers, secret: str) -> bool:
signed = headers["X-Eden-Timestamp"].encode() + b"." + raw_body
expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
given = headers.get("X-Eden-Signature", "").removeprefix("sha256=")
return hmac.compare_digest(given, expected)
Check the raw body, before your framework parses it.
Retries
- Answer with any
2xxwithin 10 seconds and the event is done. - Anything else, Eden tries again after 1 minute, 5 minutes, 30 minutes, 2 hours, 6 hours, 12 hours, and 24 hours.
- Eden doesn't follow redirects. Use the final address.
- After 3 days with nothing but failures, Eden turns the webhook off and emails you. Fix it, then click Turn on.
Missed some while your app was down? GET /store-app/v1/events lists every event from the last 30 days.
Your store webhook from before
The webhook on your store's Integrations page now shows here too, marked Your store webhook. It keeps its address, secret, five events, and body, so your Zaps keep working. It now gets retries and a delivery log, and sales from your own checkout reach it too.
If something's not working
| What you see | What to do |
|---|---|
| "That address points at a private network" | Use a public https:// address. Eden can't post to local or internal addresses. |
| Gave up on a delivery | Your app didn't answer 2xx after every retry. Fix it, then click Resend. |
| Signatures never match | Check the raw body, not parsed JSON, and make sure you copied the newest secret. |
Use the Eden API
Make an API key and connect your own code, a checkout, or an automation tool to your Eden store and workspace.
Eden (Creator Platform) API reference
Every store API endpoint, with sign-in by API key or OAuth, for developers and Zapier's review team.
Add buyers to your email list with Zapier
Catch Eden's purchase webhook in a Zap and add each buyer to Mailchimp, MailerLite, ActiveCampaign, or any list Zapier supports.
Email us. A real person reads every message.
Tell us what you tried and where you got stuck. We answer within one business day.
[email protected]