API Reference
API reference
Base URL: https://api.bloy.io/rest-api/v1/webhooks/subscription
Create Subscription
POST https://api.bloy.io/rest-api/v1/webhooks/subscription
Register an endpoint for a topic. Returns the signing secret — the only time it is ever exposed.
Headers
Name | Type | Required | Example |
|---|---|---|---|
| string | Required |
|
| string | Required |
|
Body
Name | Type | Required | Description |
|---|---|---|---|
| string | Required | A topic from Webhook Events |
| string | Required | HTTPS URL |
Request
curl -X POST https://api.bloy.io/rest-api/v1/webhooks/subscriptions \
-H "Authorization: Bearer YOUR_PUBLIC_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"topic": "points/earned",
"callbackUrl": "https://example.com/webhooks/bloy"
}'
Response 201 Created
{
"success": true,
"message": "OK",
"subscription": {
"id": "66f3d8b1c7a4e90218ba5c33",
"topic": "points/earned",
"callbackUrl": "https://example.com/hooks/bloy",
"previousSecretValidUntil": null,
"createdAt": "2026-08-25T08:02:11.004Z",
"updatedAt": "2026-08-25T08:02:11.004Z",
"signingSecret": "3f9a1c8e...64_hex_characters...b02d7e14"
}
}
Field | Type | Description |
|---|---|---|
| string | Subscription id |
| string | The subscribed topic or wildcard |
| string | Where deliveries are sent |
| string | End of the rotation grace period, |
| string | 64 hex characters. Returned once — store it now |
Errors
Status | Cause |
|---|---|
| Unknown topic, non-HTTPS URL, or a URL pointing at an internal host |
| This shop already has a subscription with the same |
List Subscriptions
GET https://api.bloy.io/rest-api/v1/webhooks/subscriptions
Get every subscription registered for your shop, newest first. Signing secrets are never included.
Request
curl https://<your-bloy-api-host>/rest-api/v1/webhooks/subscriptions \
-H "Authorization: Bearer YOUR_PUBLIC_API_KEY"
Response 200 OK
{
"success": true,
"message": "OK",
"subscriptions": [
{
"id": "66f3d8b1c7a4e90218ba5c33",
"topic": "points/earned",
"callbackUrl": "https://example.com/hooks/bloy",
"previousSecretValidUntil": null,
"createdAt": "2026-08-25T08:02:11.004Z",
"updatedAt": "2026-08-25T08:02:11.004Z"
},
{
"id": "66f3d7a0c7a4e90218ba5c2f",
"topic": "tier/*",
"callbackUrl": "https://example.com/hooks/bloy-vip",
"previousSecretValidUntil": "2026-08-26T04:30:00.000Z",
"createdAt": "2026-08-24T11:20:45.881Z",
"updatedAt": "2026-08-25T04:30:00.000Z"
}
]
}
Update Subscription
PUT https://api.bloy.io/rest-api/v1/webhooks/subscriptions/{id}
Change where a subscription delivers. The topic and the signing secret are unchanged — to change the topic, delete the subscription and create a new one.
Path parameters
Name | Type | Required | Description |
|---|---|---|---|
| string | Required | Subscription id |
Body
Name | Type | Required | Description |
|---|---|---|---|
| string | Required | New HTTPS URL |
Request
curl -X PUT https://<your-bloy-api-host>/rest-api/v1/webhooks/subscriptions/66f3d8b1c7a4e90218ba5c33 \
-H "Authorization: Bearer YOUR_PUBLIC_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "callbackUrl": "https://example.com/hooks/bloy-v2" }'
Response 200 OK
{
"success": true,
"message": "OK",
"subscription": {
"id": "66f3d8b1c7a4e90218ba5c33",
"topic": "points/earned",
"callbackUrl": "https://example.com/hooks/bloy-v2",
"previousSecretValidUntil": null,
"createdAt": "2026-08-25T08:02:11.004Z",
"updatedAt": "2026-08-25T09:15:38.442Z"
}
}
Errors
Status | Cause |
|---|---|
| Malformed id, or a |
| No such subscription on your shop |
Rotate Signing Secret
POST https://api.bloy.io/rest-api/v1/webhooks/subscriptions/{id}/rotate-secret
Issue a new signing secret while keeping the previous one valid for 24 hours.
Path parameters
Name | Type | Required | Description |
|---|---|---|---|
| string | Required | Subscription id |
Body
Name | Type | Required | Description |
|---|---|---|---|
| integer | Optional | How long the previous secret stays valid, |
Request
curl -X POST \
https://<your-bloy-api-host>/rest-api/v1/webhooks/subscriptions/66f3d8b1c7a4e90218ba5c33/rotate-secret \
-H "Authorization: Bearer YOUR_PUBLIC_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "graceHours": 2 }'
Response 201 Created
{
"success": true,
"message": "OK",
"subscription": {
"id": "66f3d8b1c7a4e90218ba5c33",
"topic": "points/earned",
"callbackUrl": "https://example.com/hooks/bloy",
"previousSecretValidUntil": "2026-08-26T09:41:02.771Z",
"createdAt": "2026-08-25T08:02:11.004Z",
"updatedAt": "2026-08-25T09:41:02.771Z",
"signingSecret": "c71b4e02...64_hex_characters...9ad35f68"
}
}
Field | Type | Description |
|---|---|---|
| string | The new secret. Returned once — store it now |
| string | When the old secret stops being accepted, 24 hours out |
Errors
Status | Cause |
|---|---|
| Malformed id |
| No such subscription on your shop |
Delete Subscription
DELETE https://api.bloy.io/rest-api/v1/webhooks/subscriptions/{id}
Stop delivering to an endpoint. Existing delivery records are kept and remain queryable.
Request
curl -X DELETE \
https://<your-bloy-api-host>/rest-api/v1/webhooks/subscriptions/66f3d8b1c7a4e90218ba5c33 \
-H "Authorization: Bearer YOUR_PUBLIC_API_KEY"
Response 200 OK
{
"success": true,
"message": "OK"
}
Errors
Status | Cause |
|---|---|
| Malformed id |
| No such subscription on your shop |
Rate limits
Limits are per shop, measured over a rolling 60-second window.
Endpoint | Limit |
|---|---|
| 30 requests per minute |
| 5 requests per minute |
| 60 requests per minute |
| 10 requests per minute |
Exceeding a limit returns 429 Too Many Requests. Back off and retry.
Updated on: 27/08/2026
Thank you!
