Using Webhooks
Webhooks let DataRecs push events to your systems in real time. The model has two parts:
- Endpoints — an HTTPS URL where deliveries are sent. Each endpoint has its own signing secret for payload verification.
- Subscriptions — bind one or more event types to an endpoint. You can have multiple subscriptions per endpoint, each filtering for different events.
This separation means you can point several subscriptions (e.g. reconciliation failures, connection tests, API key changes) at the same endpoint URL, or spread them across dedicated endpoints.
How deliveries work
Section titled “How deliveries work”- Every delivery is a CloudEvent JSON document matching the schema used on our internal event bus (see the event catalog).
- Headers include:
Content-Type: application/jsonX-Datarecs-Signature: HMAC-SHA256 signature of the body using the endpoint’s signing secret.
- The webhook service respects the per-endpoint rate limit (requests per second) and retries failed deliveries with exponential backoff.
Step 1 — Create an endpoint
Section titled “Step 1 — Create an endpoint”An endpoint is the HTTPS URL that will receive deliveries.
- Go to Automation → Webhooks and click New Endpoint.
- Enter the URL (must start with
https://). - Add an optional Description (e.g. “Slack #data-alerts”).
- Set the Rate Limit (default 50 req/s).
- Click Create Endpoint.
- A signing secret is generated and copied to your clipboard. Store it securely — you will not see it again.
curl -X POST https://api.datarecs.com/v1/webhook-endpoints \ -H "Authorization: Bearer $DATARECS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://hooks.example.com/datarecs", "description": "Slack failure alerts", "rate_limit_rps": 10 }'The response includes the endpoint object and a one-time signing_secret.
datarecs webhook-endpoint create \ --url https://hooks.example.com/datarecs \ --description "Slack failure alerts" \ --rate-limit-rps 10resource "datarecs_webhook_endpoint" "slack" { url = "https://hooks.example.com/datarecs" description = "Slack failure alerts" rate_limit_rps = 10}Step 2 — Add subscriptions
Section titled “Step 2 — Add subscriptions”A subscription tells DataRecs which event types to deliver to an endpoint.
- Open the endpoint you just created (click its row in the Webhooks list).
- In the Subscriptions section, click Add Subscription.
- Select one or more Event Types from the catalog (or choose
*for all events). - Optionally add Filters as a JSON object (e.g.
{"workspace_id": "ws-aurora"}). - Click Create Subscription.
curl -X POST https://api.datarecs.com/v1/webhook-subscriptions \ -H "Authorization: Bearer $DATARECS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "endpoint_id": "ep_abc123", "event_types": [ "io.datarecs.reconciliation.run.failed", "io.datarecs.reconciliation.run.cancelled" ], "filters": { "workspace_id": "ws-aurora" } }'datarecs webhook-subscription create \ --endpoint-id ep_abc123 \ --event-types "io.datarecs.reconciliation.run.failed,io.datarecs.reconciliation.run.cancelled" \ --filter workspace_id=ws-auroraresource "datarecs_webhook_subscription" "run_failures" { endpoint_id = datarecs_webhook_endpoint.slack.id event_types = [ "io.datarecs.reconciliation.run.failed", "io.datarecs.reconciliation.run.cancelled" ] filters = { workspace_id = datarecs_workspace.ops.id }}Available event types
Section titled “Available event types”Use GET /webhook-event-types (or the Console’s event type picker) to see the full catalog grouped by domain. Common examples:
- Reconciliation:
io.datarecs.reconciliation.run.started,.completed,.failed,.cancelled,.stage_completed - Connections:
io.datarecs.connection.connection.created,.tested,.deleted - Platform:
io.datarecs.platform.api_key.created,.updated,.deleted - Webhooks:
io.datarecs.webhook.endpoint.created,.delivery.failed
Use ["*"] as the event types array to subscribe to all events.
Validating deliveries
Section titled “Validating deliveries”Every delivery is signed with the endpoint’s signing secret.
- Read the raw request body (no whitespace changes).
- Compute
HMAC_SHA256(body, signing_secret). - Compare the hex digest to the
X-Datarecs-Signatureheader using a constant-time compare. - Reject the request if the signature doesn’t match.
Many frameworks have helpers (e.g. crypto.createHmac('sha256', secret) in Node, hmac.new in Python).
Rotating the signing secret
Section titled “Rotating the signing secret”You can rotate an endpoint’s signing secret at any time. The old secret is invalidated immediately.
Open the endpoint detail page and click Rotate Secret. The new secret is copied to your clipboard.
curl -X POST https://api.datarecs.com/v1/webhook-endpoints/ep_abc123/rotate-secret \ -H "Authorization: Bearer $DATARECS_API_KEY"datarecs webhook-endpoint rotate-secret --endpoint-id ep_abc123After rotating, update your receiver to use the new secret before the next delivery arrives.
Managing endpoints and subscriptions
Section titled “Managing endpoints and subscriptions”Disable without deleting
Section titled “Disable without deleting”Both endpoints and subscriptions have an enabled flag. Disabling an endpoint pauses all deliveries to that URL. Disabling a subscription stops deliveries for those specific event types while keeping other subscriptions on the same endpoint active.
Editing
Section titled “Editing”- Endpoints: you can update the URL, description, and rate limit.
- Subscriptions: you can change the event types, filters, and enabled state.
Deleting
Section titled “Deleting”Deleting an endpoint removes the endpoint and all of its subscriptions. Deleting a subscription only removes that subscription — the endpoint and other subscriptions remain.
Event schemas & examples
Section titled “Event schemas & examples”Sample payload: reconciliation run failed
Section titled “Sample payload: reconciliation run failed”{ "specversion": "1.0", "id": "evt_6b39dd9a", "type": "io.datarecs.reconciliation.run.failed", "source": "/workspaces/workspace_123/jobs/job_456", "subject": "runs/run_789", "time": "2026-03-05T12:04:13.102Z", "datacontenttype": "application/json", "data": { "run_id": "run_789", "job_id": "job_456", "workspace_id": "workspace_123", "status": "FAILED", "rows_processed": 10428, "rows_unmatched": 12, "error": { "code": "DIFF_THRESHOLD_EXCEEDED", "message": "12 rows outside tolerance", "details": { "stage": "Stage 2", "tolerance": "0.5%" } } }}Sample payload: stage completed
Section titled “Sample payload: stage completed”{ "specversion": "1.0", "id": "evt_ba1ff274", "type": "io.datarecs.reconciliation.run.stage_completed", "source": "/workspaces/workspace_123/jobs/job_456", "subject": "runs/run_789/stages/Stage 1", "time": "2026-03-05T11:59:42.011Z", "data": { "run_id": "run_789", "job_id": "job_456", "stage_name": "Stage 1", "status": "COMPLETED", "rows_processed": 10428, "mismatches": 0 }}Security considerations
Section titled “Security considerations”Note: Webhooks are only as secure as the endpoint receiving them. Treat the signing secret as a credential.
- Serve your endpoint behind HTTPS and validate TLS.
- Use the signing secret to reject spoofed requests.
- Rotate the signing secret periodically via Console, CLI, or API.
- Store secrets in your own secret manager; never log them.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Resolution |
|---|---|
| Repeated delivery failures | Check your endpoint logs. Ensure it returns 2xx within the timeout window. |
| Signature mismatch | Confirm you’re using the current signing secret and computing HMAC over the exact raw body. Beware JSON reformatting before hashing. |
| Endpoint disabled unexpectedly | Admins can disable via Console/CLI. Check audit logs. |
| Not receiving expected events | Verify the subscription’s event types and filters. A filter like workspace_id narrows which events match. |
| Deleted endpoint still receiving events | Delivery may have been enqueued before deletion. New events will not be delivered. |