Apiera webhooks deliver real-time HTTP notifications when events occur in your organization. Instead of polling for changes, your application receives a POST request for each event, enabling responsive integrations that react to changes as they happen.
Apiera uses a granular, signal-based webhook architecture. Every operation across the API surface fires a corresponding event. Not just top-level resource changes, but sub-resource operations too (e.g. product.attribute.linked, product.input_value.updated).
Granular events let integrators know what kind of change occurred, not just that something changed. A coarse product.updated event forces consumers to either fetch-and-diff or maintain complex routing logic. Granular events allow selective subscriptions and clear intent.
Thin payloads contain only navigational properties: the UUIDs needed to construct the exact REST API call to fetch current state. Delta payloads (before/after values) are deliberately avoided. While the infrastructure can provide near-ordered delivery in many cases, delta payloads require guaranteed ordering to be safe. Out-of-order delivery of before/after values can corrupt consumer state. Consumers always fetch current state from the API, which is architecturally sound regardless of delivery order.
- Subscribe - Create a webhook subscription with a target URL and select which event types to receive.
- Receive - When an event occurs, Apiera sends an HTTP POST to your endpoint with a signed JSON payload.
- Verify - Validate the HMAC-SHA256 signature to confirm the request is authentic.
- Fetch - Use the UUIDs in the payload to call the corresponding REST endpoint for current state.
curl -X POST https://api.apiera.io/v1/webhook-subscriptions \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"displayName": "My Integration",
"targetUrl": "https://example.com/webhooks"
}'The response includes a secret field (format: whsec_<base64>). Store this secret securely. It is only returned on creation and when explicitly rotated. You need it to verify incoming webhook signatures.
{
"uuid": "a1b2c3d4-...",
"status": "active",
"displayName": "My Integration",
"targetUrl": "https://example.com/webhooks",
"requestTimeoutMs": 10000,
"secret": "whsec_dGhpcyBpcyBhIHNlY3JldA==",
"createdAt": "2026-03-10T12:00:00Z",
"updatedAt": "2026-03-10T12:00:00Z"
}List available event types, then subscribe to the ones you need:
# List all available event types
curl https://api.apiera.io/v1/webhook-event-types \
-H "Authorization: Bearer {token}"
# Subscribe to an event type
curl -X POST https://api.apiera.io/v1/webhook-subscriptions/{subscriptionUuid}/event-types \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"webhookEventTypeUuid": "event-type-uuid-here"
}'You only receive events for event types you have explicitly subscribed to.
| Action | Method | Endpoint |
|---|---|---|
| List subscriptions | GET | /v1/webhook-subscriptions |
| Get subscription | GET | /v1/webhook-subscriptions/{uuid} |
| Update subscription | PATCH | /v1/webhook-subscriptions/{uuid} |
| Delete subscription | DELETE | /v1/webhook-subscriptions/{uuid} |
| Activate / Deactivate | PATCH | /v1/webhook-subscriptions/{uuid}/actions/lifecycle |
| Rotate secret | PATCH | /v1/webhook-subscriptions/{uuid}/actions/rotate-secret |
| List subscribed event types | GET | /v1/webhook-subscriptions/{uuid}/event-types |
| Subscribe to event type | POST | /v1/webhook-subscriptions/{uuid}/event-types |
| Unsubscribe from event type | DELETE | /v1/webhook-subscriptions/{uuid}/event-types/{eventTypeUuid} |
Subscriptions have three states:
| Status | Description |
|---|---|
| active | Receives and delivers events normally. |
| inactive | Paused. No events are created or delivered. |
| suspended | Temporarily disabled by the system (e.g. persistent delivery failures). |
Transition between states using the lifecycle endpoint:
curl -X PATCH https://api.apiera.io/v1/webhook-subscriptions/{uuid}/actions/lifecycle \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{ "transition": "deactivate" }'Every webhook delivery is signed with your subscription's HMAC secret. Always verify the signature before processing the payload.
Each request includes three headers:
| Header | Description |
|---|---|
webhook-id | Unique delivery identifier (UUID). |
webhook-timestamp | Unix timestamp (seconds) when the webhook was sent. |
webhook-signature | HMAC-SHA256 signature in the format v1,<base64>. |
The signature is computed over the string:
{webhook-id}.{webhook-timestamp}.{payload}Where {payload} is the raw JSON request body.
Verification steps:
- Extract the
webhook-id,webhook-timestamp, andwebhook-signatureheaders. - Construct the signed content:
{webhook-id}.{webhook-timestamp}.{payload}. - Compute HMAC-SHA256 using your secret (Base64-decode the secret after removing the
whsec_prefix). - Compare the computed signature with the
webhook-signatureheader value. - Optionally, reject requests where the timestamp is older than 5 minutes to prevent replay attacks.
See Examples for complete verification code in multiple languages.
If your secret is compromised, rotate it immediately:
curl -X PATCH https://api.apiera.io/v1/webhook-subscriptions/{uuid}/actions/rotate-secret \
-H "Authorization: Bearer {token}"The response contains the new secret. Update your verification code before the next delivery.
Every webhook POST request includes these headers:
| Header | Description |
|---|---|
Content-Type | Always application/json; charset=utf-8. |
webhook-id | Unique delivery UUID. |
webhook-timestamp | Unix timestamp (seconds). |
webhook-signature | HMAC-SHA256 signature (v1,<base64>). |
X-Webhook-Event-Type | The event type string (e.g. product.created). |
Deprecation | (Optional) RFC 7234 date if the event type is deprecated. |
Sunset | (Optional) RFC 7234 date when the event type will be removed. |
All payloads are thin. They contain only the UUIDs needed to fetch current state via the REST API.
{
"productUuid": "550e8400-e29b-41d4-a716-446655440000"
}The payload structure varies by event type but always maps directly to REST API path parameters. See Events for details on event types and their payloads.
Track delivery status and debug failures using the delivery endpoints:
# List deliveries for a subscription
curl https://api.apiera.io/v1/webhook-subscriptions/{uuid}/deliveries \
-H "Authorization: Bearer {token}"
# Get a specific delivery
curl https://api.apiera.io/v1/webhook-subscriptions/{uuid}/deliveries/{deliveryUuid} \
-H "Authorization: Bearer {token}"
# List delivery attempts
curl https://api.apiera.io/v1/webhook-subscriptions/{uuid}/deliveries/{deliveryUuid}/attempts \
-H "Authorization: Bearer {token}"Each delivery tracks:
| Field | Description |
|---|---|
status | pending, delivered, or failed. |
attempts | Number of delivery attempts made. |
lastStatusCode | HTTP status code from the most recent attempt. |
scheduledAt | When the next retry is scheduled (if pending). |
Each attempt records the HTTP status code, response body (truncated to 2048 characters), and response time in milliseconds.