Webhooks API Reference
The webhook receiver accepts inbound webhooks from external providers (Stripe, GitHub, Shopify, Slack, etc.) and converts them into OneHazel events that can trigger workflows.
Endpoint
POST /functions/v1/webhook-receiver/:connectionIdAuthentication: None required. Providers call this URL directly. Signature verification is used instead.
How it works
- You configure an external provider to send webhooks to your OneHazel webhook URL
- The provider sends a POST request with the event payload
- OneHazel verifies the signature (if a signing secret is configured)
- The payload is stored as a OneHazel event of type
provider.webhook.<eventType> - The event can trigger workflows
Setting up webhooks
1. Register the webhook
Register your webhook in the OneHazel dashboard under your connection settings. This creates a provider_webhooks record with:
- The connection ID
- The provider name (e.g.
stripe,github) - An optional signing secret for signature verification
- Which events to listen for
2. Configure the provider
Set the webhook URL in your external provider's settings:
https://api.onehazel.com/webhook-receiver/<connectionId>Replace <connectionId> with your connection ID.
3. Set the signing secret
For secure webhook delivery, configure the same signing secret in both the external provider and your OneHazel webhook registration.
Signature verification
When a signing secret is configured, OneHazel verifies the webhook signature using provider-specific methods:
Stripe
Reads the stripe-signature header, extracts the timestamp (t) and signature (v1), and verifies using HMAC-SHA256 of {timestamp}.{body}.
GitHub
Reads the x-hub-signature-256 header and verifies using HMAC-SHA256 of the raw request body. Expected format: sha256=<hex>.
Shopify
Reads the x-shopify-hmac-sha256 header and verifies using HMAC-SHA256 of the raw request body, base64-encoded.
Slack
Reads the x-slack-signature and x-slack-request-timestamp headers. Verifies using HMAC-SHA256 of v0:{timestamp}:{body}. Expected format: v0=<hex>.
Generic providers
For other providers, OneHazel checks common signature headers (x-signature, x-webhook-signature, x-signature-256, webhook-signature, x-hook-signature) and tries both hex and base64 HMAC-SHA256 verification.
Event type extraction
OneHazel extracts the event type from the webhook payload based on the provider:
| Provider | Event type source |
|---|---|
| Stripe | body.type (e.g. payment_intent.succeeded) |
| GitHub | x-github-event header (e.g. push, pull_request) |
| Shopify | x-shopify-topic header (e.g. orders/create) |
| Slack | body.event.type or body.type |
| Other | body.event or body.type or {provider}.webhook |
OneHazel event format
Verified webhooks are stored as events with the type provider.webhook.<extractedEventType>:
{
"id": "evt_a1b2c3d4e5f67890",
"operator_id": "op_xyz",
"type": "provider.webhook.payment_intent.succeeded",
"data": {
"connectionId": "conn_abc123",
"provider": "stripe",
"originalEventType": "payment_intent.succeeded",
"payload": { ... },
"registrationId": "reg_456"
},
"created_at": "2026-04-06T12:00:00.000Z"
}Unregistered webhooks
If a webhook arrives for a connection without an active webhook registration, it is still accepted but logged as webhook.received.unregistered. The response includes a warning:
{
"received": true,
"eventId": "evt_a1b2c3d4e5f67890",
"warning": "No active webhook registration"
}Response
Success
{
"received": true,
"eventId": "evt_a1b2c3d4e5f67890"
}HTTP status: 200
Signature failure
{
"error": "Webhook signature verification failed"
}HTTP status: 401
Workflow triggers
Webhook events can trigger workflows. For example:
provider.webhook.payment_intent.succeeded— trigger a workflow that updates the player's balanceprovider.webhook.push— trigger a deployment pipelineprovider.webhook.orders/create— trigger order fulfilment
Configure these triggers in the workflow builder by selecting the event type pattern.
Error codes
| HTTP Status | Error Code | Description |
|---|---|---|
400 | — | Missing connectionId in URL path |
401 | — | Webhook signature verification failed |
405 | — | Method not allowed (only POST accepted) |
500 | — | Internal server error |