Receive webhooks
Receive webhooks
Goal: get CRM events (record created / updated / deleted) pushed to your endpoint instead of polling. Time: ~10 min.
You need
- A public HTTPS endpoint that answers with a
2xxstatus within 5 seconds. - An API key (
crtk_live_…) or OAuth token (crtk_oauth_…) with theread.<object_slug>scope for the object you want to watch.
1. Register an endpoint
Create a subscription with your credential. Pick the object and the events you care about:
A dedicated workspace uses its own subdomain instead of app. The response
carries data.signing_secret. It is returned only once, so store it now.
2. Verify the signature
Every delivery carries an X-Corteksa-Signature header of the form
t=<unix seconds>,v1=<hex>. v1 is the lowercase hex HMAC-SHA256 of the string
<t>.<raw body>: the timestamp, a ., then the exact request body bytes. The
key is your whole signing secret, including its whsec_ prefix.
Recompute it over the raw body, before any JSON parsing, and compare in
constant time. Reject a t more than 5 minutes from your clock to stop replays.
Each retry is signed again with a new t, so this window does not reject
retries.
3. Respond fast, work async
Return 200 immediately and process in the background. A delivery is tried up
to 3 times: a timeout (5 seconds), a connection failure, a 5xx, a 408 or a
429 is retried with backoff, and any other 4xx stops the retries.
Make your handler idempotent. There is no event id that stays the same
across retries: X-Corteksa-Delivery, t and the body's timestamp all change
on every attempt. Treat each delivery as a signal and fetch the record by
record_slug (GET /api/v1/object/data/:objectSlug/:dataSlug) before you act,
so running the same delivery twice does no harm.
Notes
- This is Corteksa → your app. Provider → Corteksa webhooks (WhatsApp and Facebook replies) are handled by Corteksa itself and need nothing from you.
- Every event, header and body field, with a signature test vector → Webhook events.
- Listing and deleting subscriptions → Webhooks.