Skip to main content
The webhook object tells the platform how to process incoming HTTP requests from your provider. This is the core of event-driven integration. Your webhook URL: https://{saas-api-url}/miniapps/{ns}/webhooks This URL is auto-generated and available as {{webhookUrl}} in registration requests.
Not tenant webhooks — These are inbound provider webhooks (e.g. Salla → Karzoun). For outbound workspace events to your own server, see Tenant webhooks.

Event Extraction

Tells the platform where to find the event name in the incoming webhook request. Simple extraction (single field):
Examples:
  • Salla sends { "event": "order.created", "data": {...} }source: 'body', path: '$.event'
  • A service sends the event name in a header → source: 'header', path: 'X-Event-Type'
Composite extraction (multi-field): Some providers split event identification across multiple fields. Use compositeStrategy to combine them:
Another example — Slack uses body fields:

Transaction Deduplication

Prevents the same webhook from being processed twice (e.g., during retries).
The platform checks Redis for the transaction ID. If it’s already been processed, the webhook is silently acknowledged without re-processing. Common patterns:
  • '$.data.id' — Salla order/cart ID
  • '$.delivery' — GitHub delivery header
  • '$.event_id' — Generic event ID field

Verification (HMAC Signatures)

Verify that incoming webhooks genuinely come from your provider using HMAC signature verification.
Verification types: Optional encoding on HMAC types: 'hex' (default) or 'base64' (WooCommerce X-WC-Webhook-Signature). How the secret is resolved (secretKey): The secretKey field is a key name, not the secret value itself. The platform resolves the actual secret using a two-source lookup:
  1. Per-tenant credentials — Checks installedMiniApps.credentials[secretKey] first. Use this when the provider issues a unique secret per connected store/tenant (e.g., registering a webhook returns a per-store signing key).
  2. Global app config — Falls back to miniApp.auth.config[secretKey] if not found in tenant credentials. Use this when the provider uses a single global secret shared across all tenants (e.g., Salla, where the webhook secret is set once in the partner dashboard).
For global secrets, set the value in auth.config of your MiniApp definition. For per-tenant secrets, store them in credentials during registration requests or the OAuth flow.
How HMAC verification works:
  1. Platform reads the signature from headerName
  2. Strips sha256= or sha1= prefix if present
  3. Resolves the secret via the two-source lookup described above
  4. Computes HMAC of the raw request body using the resolved secret
  5. Compares using timing-safe comparison to prevent timing attacks
  6. Rejects with 401 if they don’t match

Challenge/Handshake Response

Some providers (like Slack) require a challenge-response handshake when registering webhooks.
How it works:
  1. Provider sends a POST with { "type": "url_verification", "challenge": "abc123" }
  2. Platform checks: body.type === 'url_verification' → yes, this is a challenge
  3. Platform extracts challenge token from $.challenge"abc123"
  4. Platform responds with { "challenge": "abc123" }
  5. Provider considers the webhook URL verified
If responseField is omitted, the challenge token is returned as the raw response body.

Customer Extraction

For MiniApps that receive customer data in webhooks (e-commerce platforms, CRMs), configure automatic customer creation/matching.
Available customer fields: How it works: When a webhook arrives, the platform:
  1. Extracts customer data from basePath (or override path for the specific event)
  2. Maps provider field names to internal field names
  3. Calls getOrCreateCustomer() which finds or creates the customer record
  4. Links the customer to the incoming event for automation context

Response Configuration

Define what the platform sends back to your provider after receiving a webhook.
The platform sends the response immediately upon receiving the webhook, before async processing begins. This prevents provider timeouts. Use 202 if your provider expects acknowledgment-style responses.
Last modified on August 8, 2026