Event Delivery
Request format
BLOY sends a POST request with a JSON body and these headers:
Header | Description |
|---|---|
| The event topic, for example |
| Unique event id, for example |
| The |
| Webhook API version, currently |
| HMAC-SHA256 of the raw body, hex encoded, signed with the current secret |
| Only present during a secret rotation grace period |
| Delivery attempt number, starting at |
|
|
Routing metadata lives in headers, not in the body — the body is not padded with values you already have in the headers.
Body structure
Every payload has the same four top-level fields, whatever the topic:
{
"id": "9f2c7a1b4e8d3c6f0a5b2e91",
"occurredAt": "2026-08-25T08:14:22.913Z",
"customer": {
"id": "66f2a1c9e4b0d8a12f3c9a71",
"shopifyCustomerId": "7284619203841",
"email": "mai.nguyen@example.com",
"pointBalance": 1500,
"currentTier": { "id": "66d1b4e7c2a9f80315de7742", "name": "Gold" },
"referralCode": "MAI-4F2A",
"birthday": "1994-03-18T00:00:00.000Z",
"createdAt": "2025-11-02T09:41:07.220Z"
},
"data": {}
}
Field | Type | Description |
|---|---|---|
| string | Unique event id, identical to |
| string | ISO 8601 timestamp of when the event happened |
| object | The customer the event is about. Same shape for every topic |
| object | Topic-specific fields — see Event payloads |
The customer object:
Field | Type | Description | |
|---|---|---|---|
| string | BLOY customer id | |
| string | null | Shopify customer id |
| string | null | Customer email |
| number | Point balance after the event | |
| object | null |
|
| string | null | The customer's referral code |
| string | null | ISO 8601 date |
| string | null | ISO 8601 date the customer joined the programme |
Responding
Return any 2xx status code to acknowledge the delivery. Any other status, a connection error, or no answer at all counts as a failure and starts the retry sequence. Redirects are followed automatically, and the status at the end of the redirect chain is what decides success.
BLOY waits 5 seconds for a response. Return quickly and defer the real work; a slow handler will time out and be retried even though it succeeded.
Automatic retries
A failed delivery is retried up to 6 attempts in total over roughly 31 minutes:
Attempt | Sent |
|---|---|
1 | Immediately |
2 | 1 minute after attempt 1 fails |
3 | 2 minutes after attempt 2 fails |
4 | 4 minutes after attempt 3 fails |
5 | 8 minutes after attempt 4 fails |
6 | 16 minutes after attempt 5 fails |
Retries target only the endpoint that failed. If you have several subscriptions matching one event and just one endpoint is down, the healthy endpoints are not re-sent to. | |
After attempt 6 the delivery is marked |
Handle duplicate events
BLOY will not re-send an event to an endpoint that has already acknowledged it, but you should still make your handler idempotent. Network partitions and infrastructure failures can, in rare cases, produce a repeat delivery.
Record the id of every event you process and ignore ids you have seen before. The id is stable across all attempts and replays of the same event.
Updated on: 26/08/2026
Thank you!
