Skip to content

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/:connectionId

Authentication: None required. Providers call this URL directly. Signature verification is used instead.

How it works

  1. You configure an external provider to send webhooks to your OneHazel webhook URL
  2. The provider sends a POST request with the event payload
  3. OneHazel verifies the signature (if a signing secret is configured)
  4. The payload is stored as a OneHazel event of type provider.webhook.<eventType>
  5. 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:

ProviderEvent type source
Stripebody.type (e.g. payment_intent.succeeded)
GitHubx-github-event header (e.g. push, pull_request)
Shopifyx-shopify-topic header (e.g. orders/create)
Slackbody.event.type or body.type
Otherbody.event or body.type or {provider}.webhook

OneHazel event format

Verified webhooks are stored as events with the type provider.webhook.<extractedEventType>:

json
{
  "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:

json
{
  "received": true,
  "eventId": "evt_a1b2c3d4e5f67890",
  "warning": "No active webhook registration"
}

Response

Success

json
{
  "received": true,
  "eventId": "evt_a1b2c3d4e5f67890"
}

HTTP status: 200

Signature failure

json
{
  "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 balance
  • provider.webhook.push — trigger a deployment pipeline
  • provider.webhook.orders/create — trigger order fulfilment

Configure these triggers in the workflow builder by selecting the event type pattern.

Error codes

HTTP StatusError CodeDescription
400Missing connectionId in URL path
401Webhook signature verification failed
405Method not allowed (only POST accepted)
500Internal server error