Webhooks
Overview
Webhooks provide a way for the API Gateway to notify your application when specific events occur. Instead of polling the API for changes, your application receives HTTP POST requests with event data in real-time.
Key Concepts
| Concept | Description |
|---|---|
| Webhook | A configuration that specifies which events to receive and where to send them |
| Event Type | The category of event (e.g., SALE.CREATE, TRANSACTION.UPDATE) |
| Endpoint URL | Your HTTPS URL that receives webhook notifications |
| Secret | A shared key used to sign and verify webhook requests |
| Max Concurrency | Maximum simultaneous webhook deliveries to your endpoint |
Managing Webhooks
Before creating a webhook, you can retrieve the list of available event types you can subscribe to using the /v1/webhooks/events endpoint. Then create a new webhook configuration to start receiving notifications. One webhook configuration can receive notifications for multiple event types, if notifications should be sent to different urls then multiple webhook configurations need to be created.
Creating a webhook configuration
Endpoint: POST /v1/webhooks
Request Body
{
"url": "https://api.example.com/webhooks/notifications",
"storeId": "s_1234abcd",
"eventTypes": ["SALE.CREATE", "SALE.UPDATE", "TRANSACTION.CREATE"],
"maxConcurrency": 10,
"secret": "your-secret"
}Request Fields
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | The HTTPS endpoint URL where webhooks will be delivered. Must be publicly accessible. |
storeId | string | No | Optional store filter. If set, only events for this specific store are delivered. If null, events for all stores are delivered. |
eventTypes | string[] | Yes | List of event type codes to subscribe to. Use codes from the /v1/webhooks/events endpoint. |
maxConcurrency | integer | Yes | Maximum number of concurrent webhook deliveries (1-100). Higher values allow faster delivery during high-volume periods but increase load on your endpoint. |
secret | string | Yes | The secret key used to sign webhook requests. Minimum 8 characters, maximum 32 characters. Store this securely—you'll need it to verify signatures. |
Response
HTTP Status: 201 Created
{
"id": "es_1234abcd5678efgh",
"url": "https://api.example.com/webhooks/notifications",
"storeId": "s_1234abcd",
"eventTypes": ["SALE.CREATE", "SALE.UPDATE", "TRANSACTION.CREATE"],
"maxConcurrency": 10,
"secret": "your-secure-webhook-secret-min-8-chars",
"status": "Active",
"createdAt": "2026-02-23T10:30:00Z",
"_links": {
"self": {
"href": "/v1/webhooks/es_1234abcd5678efgh",
"method": "GET"
},
"update": {
"href": "/v1/webhooks/es_1234abcd5678efgh",
"method": "POST"
}
}
}Receiving Webhooks
When an event occurs for which there is an active webhook configuration, an HTTP POST request will be sent to your configured endpoint.
Webhook Payload Format
Request Headers:
Content-Type: application/json
Content-Digest: sha-256=:BASE64_HASH:
Signature-Input: sig=("host" "content-digest" "@request-target");alg="hmac-sha256";created=TIMESTAMP;nonce="NONCE"
Signature: sig=:BASE64_SIGNATURE:
Idempotency-Key: 7110eda4d09e062aa5e4a390b0a572ac0d2c0220
Buck-Event-Type: SALE.CREATE
Request Body:
The body contains application-specific JSON data for the event. The exact format depends on the event type. For example, for the SALE.CREATE event the content is identical to the GET /v1/sales/{id} response.
Signature Verification
For the notification signature we’ll be using the HTTP Message Signing standard. See https://datatracker.ietf.org/doc/html/rfc9421 & https://httpsig.org/.
Understanding the Signature Headers
| Header | Description |
|---|---|
Content-Digest | SHA-256 hash of the request body, formatted as sha-256=:BASE64_HASH: |
Signature-Input | Describes how the signature was constructed, including algorithm, timestamp, and nonce |
Signature | The actual HMAC-SHA256 signature, formatted as sig=:BASE64_SIGNATURE: |
Example Headers:
Content-Digest: sha-256=:X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=:
Signature-Input: sig=("host" "content-digest" "@request-target");alg="hmac-sha256";created=1708689045;nonce="550e8400-e29b-41d4-a716-446655440000"
Signature: sig=:JsxlPZ9DJPdJZTBOz8qVOgP3VtFwSIRYVjNqLB3xVxE=:
Verification Steps
Step 1: Verify the content digest
Compute the SHA-256 hash of the request body and compare it to the Content-Digest header.
Step 2: Parse the Signature-Input header
Extract these components:
- Signed components:
"host","content-digest","@request-target" - Algorithm:
hmac-sha256 - Created timestamp: Unix timestamp when the signature was created
- Nonce: Unique identifier for replay protection
Step 3: Build the signature base string
The signature base is a newline-separated string with this exact format:
"host": api.example.com
"content-digest": sha-256=:X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=:
"@request-target": /webhooks/notifications
"@signature-params": ("host" "content-digest" "@request-target");alg="hmac-sha256";created=1708689045;nonce="550e8400-e29b-41d4-a716-446655440000"
Step 4: Compute the HMAC-SHA256
Using your webhook's secret as the key:
- Create HMAC-SHA256 with the secret
- Update with the signature base string (UTF-8 encoded)
- Compute the digest and base64-encode it
Step 5: Compare signatures
Extract the signature from the Signature header (between : delimiters) and compare with your computed value using a timing-safe comparison.
Step 6: Validate timestamp (recommended)
Check that the created timestamp is recent (within 5 minutes) to prevent replay attacks.
Delivery & Retry Behavior
Successful Delivery
A webhook is considered successfully delivered when your endpoint returns an HTTP status code in the 2xx range (200-299).
Retry Logic
If delivery fails (non-2xx response, timeout, or network error), the notification is retried:
- Maximum retries: 10 attempts
- Timeout: 20 seconds per request
- Final status: After 10 failed attempts, the notification is marked as
Failed
Response Requirements
Your webhook endpoint should:
- Return a
2xxstatus code on success (200, 201, 202, etc.) - Respond within 20 seconds
- Be idempotent—you may receive the same webhook multiple times even if a success response was returned, since it could get lost on the return trip
Security Considerations
Secret Management
- Use a strong secret (minimum 8 characters, max 32 characters)
- Store the secret securely (e.g., environment variables, secret manager)
Endpoint Security
- Always use HTTPS for your webhook endpoint
- Verify signatures on every request before processing
- Validate timestamps to prevent replay attacks (accept signatures no older than 5 minutes)
Idempotency
Design your webhook handler to be idempotent. Due to retries and at-least-once delivery semantics, you may receive the same notification multiple times. Every notification will have an Idempotency-Key to allow for easy deduplication.
Troubleshooting
Common Issues
| Issue | Possible Cause | Solution |
|---|---|---|
| Signature verification fails | Wrong secret, modified payload, or header parsing | Double-check secret value and signature base format |
| Webhooks not received | Subscription inactive or wrong event types | Verify subscription status and event type configuration |
| Duplicate notifications | Retries due to timeout/error | Implement idempotent handling |
Updated 10 days ago