Every webhook delivery sends a JSON payload to your configured endpoint. This structure is consistent across all event types.
Each delivery is an HTTP POST carrying these headers:
| Header | Description |
|---|
X-Webhook-ID | UUID of the webhook subscription that produced the delivery. |
X-Delivery-ID | UUID of this specific delivery. Matches the id field in the body — use it to deduplicate. |
X-Event-Type | The event name, e.g. trader_whale_trade. |
X-Attempt | Delivery attempt number, starting at 1. |
X-Webhook-Signature | HMAC-SHA256 signature of the body, present only when the webhook has a secret. See Signature Verification. |
Payload Structure
{
"id": "4aa4e020-818d-4a76-af9d-b023dd9674d2",
"event": "trader_whale_trade",
"data": { ... },
"timestamp": 1773025181866,
"webhook_id": "26cc4fb7-c62e-450c-a532-07196afd7b67",
"attempt": 1
}
Fields
A unique identifier (UUID) for this specific webhook delivery. Use this to deduplicate events on your end.
event
The event type that triggered this webhook. Matches one of the event types you subscribed to during setup.
data
The event payload. Its shape depends on the event type. See the individual event documentation for field details.
timestamp
Unix timestamp in milliseconds indicating when the event was emitted.
webhook_id
The UUID of the webhook subscription that produced this delivery. Useful when you have multiple webhooks configured and need to identify the source.
attempt
The delivery attempt number, starting at 1. If your endpoint fails to respond with a 2xx status code, Struct retries the delivery and increments this value.
Retries & failures
A delivery succeeds only on a 2xx response within the timeout. Otherwise it is retried:
| Property | Value |
|---|
| Success criteria | HTTP status 200–299 |
| Request timeout | 30 seconds per attempt |
| Max attempts | 10 |
| Backoff | 1 second between attempts |
| After all attempts fail | The webhook is automatically disabled |
If 10 consecutive attempts fail, the subscription is set to Disabled and stops receiving events until you re-enable it with a PUT /v1/webhooks/{id}. Return 2xx quickly — acknowledge first, then process the event out of band — so slow downstream work never trips the 30-second timeout.
Because a delivery can be retried, the same event may arrive more than once. Deduplicate using the id field (or the X-Delivery-ID header).
Fields within data may be null depending on the event type and the availability of enriched metadata at the time of delivery.