Webhooks Quickstart
Subscribe to an event, receive a signed payload, verify it, respond 200 — end to end in five minutes.
MemberPass delivers webhook POSTs to any publicly reachable HTTPS URL you register. This page walks the happy path from zero.
Register a target
Either through Settings → Webhooks in the dashboard, or via the REST API:
curl -X POST https://api.memberpass.net/v1/webhook-endpoints \
-H "Authorization: Bearer $MP_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"name": "My target",
"url": "https://hooks.example.com/memberpass",
"events": ["subscription.created", "payment.succeeded"]
}'The response includes a one-time secret field. Store it — you'll need it to verify signatures and you cannot retrieve it again.
Receive the POST
Every delivery lands on your URL as a JSON POST:
POST /memberpass HTTP/1.1
MP-Event-Id: 01HXDELIVERY000000000TST
MP-Event-Name: subscription.created
MP-Signature: t=1762041600,v1=4a2b...
Content-Type: application/json
{"id":"evt_01HX...","type":"subscription.created",...}Verify the signature
Every payload is signed with HMAC-SHA256 over <timestamp>.<raw_body>. The signature verification page has 3-language snippets. TL;DR in Node:
import crypto from "node:crypto";
function verify(header: string, body: string, secret: string): boolean {
const [tPart, v1Part] = header.split(",");
const t = tPart.split("=")[1];
const v1 = v1Part.split("=")[1];
const expected = crypto
.createHmac("sha256", secret)
.update(`${t}.${body}`)
.digest("hex");
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
}Reject the request if the signature doesn't match.
Respond 200 quickly
Return 200 OK within 10 seconds. Anything else counts as a failure and triggers a retry. If your work takes longer, enqueue a background job and respond immediately.
De-dupe on event_id
The MP-Event-Id header (and the id in the payload) is unique per event. Store it and short-circuit if you've seen it before — retries can cause the same event to arrive more than once.
What next
How is this guide?