Webhooks
Integrations — Webhooks
Instead of polling, subscribe an HTTPS endpoint and Corteksa will push a
signed HTTP POST to it when a record in an object is created, updated or
deleted. An app registers its own subscriptions with its API key
(crtk_live_…) or OAuth token (crtk_oauth_…), the same credential it uses
to read and write records. One credential can hold many subscriptions.
Events today:
record.created,record.updatedandrecord.deleted. CallGET /api/v1/webhooks/eventsfor the current list.
1. Subscribe
name is optional. Without it, the subscription is named after the object and
the target host.
201 response — the signing secret is shown exactly once. Store it now.
target_urlmust be HTTPS. Otherwise422.eventsmust be names from the catalog (GET /api/v1/webhooks/events). An unknown name returns400.- The credential must have read access to the object (scope
read.<object_slug>), because a webhook only ever carries data the credential could already read. Otherwise403. - An
object_slugthat matches no object returns404. - Subscriptions are addressed by
slug, never a numeric id.
Manage
| Method & path | Does |
|---|---|
GET /api/v1/webhooks/events | List subscribable event names |
GET /api/v1/webhooks/subscriptions | List your subscriptions, newest first |
GET /api/v1/webhooks/subscriptions/:slug | Get one |
DELETE /api/v1/webhooks/subscriptions/:slug | Delete one |
A subscription belongs to the credential that created it: the API key, or the
OAuth app for an OAuth token. Only that credential can list, read or delete it.
The signing secret is never returned again after the create call. A user
session (JWT) is rejected with 403, because these endpoints are for apps.
2. Receive a delivery
Corteksa sends a POST with a JSON body and these headers:
| Header | Example | Meaning |
|---|---|---|
Content-Type | application/json | The body is JSON |
X-Corteksa-Event | record.updated | The event that fired |
X-Corteksa-Delivery | 4021 | A number, new for every delivery attempt. A retry of the same event carries a different value, so it is not an idempotency key |
X-Corteksa-Signature | t=1752400000,v1=9f86d0… | Timestamp and HMAC signature — see §3 |
Body:
changed_fields and full_record are keyed by field slug. What they hold
depends on the event: on record.updated, full_record holds only the fields
the write sent, not the whole record. Use record_slug, not record_id, to
fetch the record. Every event, its body and the values it can carry are listed
in Webhook events.
Answer with any 2xx within 5 seconds. See §4 for what is retried.
3. Verify the signature
The X-Corteksa-Signature header is t=<unix-seconds>,v1=<hex>, where v1 is
the lowercase hex HMAC-SHA256(signing_secret, "<t>.<raw-request-body>"). Use
the whole signing secret as the key, including its whsec_ prefix. Recompute it
over the raw body (do not re-serialize) and compare in constant time. Reject
a t more than a few minutes from your clock to stop replays. Each retry is
signed again with a new t, so this does not reject retries.
4. Delivery, retries, and loops
- Retries: a delivery is tried up to 3 times. A timeout (5 seconds), a
connection failure, a
5xx, a408or a429is retried with exponential backoff. Any other4xxstops the retries. - Idempotency: nothing in the request stays the same across attempts —
X-Corteksa-Delivery,tandtimestampall change. Make your handler safe to run twice, for example by treating a delivery as a signal and fetching the record byrecord_slugbefore you act. Deliveries can also arrive out of order. - No echo of your own writes: a change made by a request with your API key or OAuth token is not delivered to that credential's own subscriptions, so writing back in response to a delivery does not loop. Changes by other keys, apps and users still notify you, and so can work that runs later in the background, such as an automation your change triggers. See Webhook events for the exact rules.
- Disconnecting: delete the subscription with
DELETE /api/v1/webhooks/subscriptions/:slug, using the credential that created it.
5. Security checklist
- Treat
signing_secretlike a password; store it server-side. - Always verify
X-Corteksa-Signaturebefore trusting a payload. - Enforce the timestamp replay window.
- Only accept HTTPS callbacks.