Webhooks
Webhooks let Saturday push real-time event notifications to your server. Instead of polling the API for changes, register a webhook URL and Saturday will POST events to you as they happen.Registering a webhook
Available events
Subscription event payloads
subscription.created fires once per unlock — after the purchase record exists, never before. A resubscribe after cancellation fires it again.
source values: checkout_subscription, checkout_lifetime (no expires_at), existing_subscription_linked (an already-subscribed Saturday account tapped your CTA — they were linked without being charged), email_match (a paying Saturday account was linked to your athlete automatically by email — see Freemium Model → Automatic linking by email), simulated (test env only).
subscription.cancelled means the athlete’s next calculate returns teaser ranges:
Don’t cache tier from webhooks alone —
GET /v1/athletes/{id} returns a computed subscription_status (full | trial | teaser) whenever you need ground truth, e.g. when an athlete returns from checkout.Webhook payload format
Every webhook delivery has this structure:Verifying webhook signatures (HMAC-SHA256)
Every webhook delivery includes a signature in theX-Saturday-Signature header. Always verify this signature to confirm the webhook came from Saturday and wasn’t tampered with.
The signature is computed as HMAC-SHA256(webhook_secret, timestamp + "." + raw_body).
Verification steps
- Extract the timestamp and signature from the header
- Reconstruct the signed payload:
{timestamp}.{raw_body} - Compute HMAC-SHA256 using your webhook secret
- Compare with constant-time equality
Retry behavior
If your endpoint fails (non-2xx response or timeout), Saturday retries with exponential backoff:
After 5 failed retries, the delivery is marked as failed and the event is logged for manual retry.
Auto-disable
If a webhook endpoint fails consistently for 3 consecutive days, Saturday automatically disables it and sends a notification email to the partner contact. Re-enable it from the API after fixing the issue:Best practices
- Return 200 immediately — process events asynchronously. Saturday times out after 30 seconds.
- Handle duplicates — use the
idfield to deduplicate. The same event may be delivered more than once. - Verify signatures — always. Never trust a webhook payload without HMAC verification.
- Use HTTPS — Saturday only delivers to HTTPS endpoints.
- Log everything — store raw payloads for debugging. Include the event
idin your logs.