Webhooks
Quick answer
Webhooks let ScrambleSync push events to your server in real time so you don't need to poll the API. Create an endpoint in Settings → API access (or via POST /api/v1/webhooks), choose which event types to subscribe to, and verify each delivery using the HMAC-SHA256 signature in the X-ScrambleSync-Signature header.
On this page
Events you can subscribe to
| Event type | When it fires |
|---|---|
| contact.created | A new contact is added to your organization. |
| registration.created | A golfer registers for one of your tournaments. |
| registration.paid | A registration payment is confirmed by Stripe. |
| invitation.delivered | An outbound invitation email is delivered to the recipient. |
Creating a webhook endpoint
Open Settings → API access
Go to Settings → API access in your dashboard and click the Webhooks tab.
Click Add endpoint
Enter your HTTPS endpoint URL and an optional description.
Choose event types
Select the event types you want to receive. Leave all unchecked (or pass an empty array via API) to receive all supported event types.
Save and copy the signing secret
The signing secret (whsec_…) is shown once on creation and once per rotation. Copy it immediately — it cannot be retrieved again. You need it to verify signatures.
Payload envelope
Every delivery is an HTTP POST with Content-Type: application/json. The body has this shape: { "id": "<event_id>", "type": "registration.created", "created_at": "2026-06-08T15:30:00.000Z", "data": { … } } The data object contains the resource that triggered the event (for example, a registration object for registration.created).
Verifying the signature
Each delivery includes an X-ScrambleSync-Signature header of the form t=<unix_timestamp>,v1=<hex_hmac>. To verify:
- Parse t (Unix timestamp in seconds) and v1 (hex HMAC) from the header.
- Check that t is within 5 minutes of your current time to guard against replay attacks.
- Compute HMAC-SHA256 over the string t.<raw_body> using your signing secret as the key.
- Compare your computed hex digest to v1 using a constant-time comparison. Reject if they don't match.
Retries and failure handling
ScrambleSync retries failed deliveries with exponential backoff: after 1 minute, 5 minutes, 30 minutes, 2 hours, 6 hours, and 24 hours — up to 8 total attempts. If all 8 fail, the endpoint is automatically disabled with a disabled_reason of consecutive_failures. Re-enable it from Settings → API access once your endpoint is fixed, then replay missed deliveries.
Replaying deliveries
From Settings → API access, open a webhook endpoint and find a failed delivery in the delivery log. Click Replay to resend it. You can also replay via the API: POST /api/v1/webhooks/{id}/deliveries/{did}/replay (scope webhooks:write).
Rotating the signing secret
To rotate the signing secret for an endpoint, use the API: POST /api/v1/webhooks/{id}/rotate-secret (scope webhooks:write). The new secret is returned once. Update your application before the old secret stops working.
Frequently asked questions
How do I handle a webhook that arrives more than once?
Use the event id field as an idempotency key. If you see the same id twice, it is a retry and you have already processed it — acknowledge it with 2xx but skip the business logic.
What should my endpoint return?
Return any 2xx HTTP status as quickly as possible (200 or 204 works). If processing takes time, queue the payload internally and return 2xx immediately — do not hold the connection open.
Can I test webhooks locally?
Yes. Use a tunneling tool (such as ngrok or Cloudflare Tunnel) to expose a local port, then register that URL as your endpoint. You can also replay historical deliveries from Settings → API access once your endpoint is registered.
My endpoint was auto-disabled. How do I re-enable it?
Fix your endpoint so it returns 2xx, then go to Settings → API access, find the endpoint, and enable it. You can then replay any missed deliveries from the delivery log.