Articles on: Webhook API

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

Authorization

string

Required

Bearer YOUR_PUBLIC_API_KEY

Content-Type

string

Required

application/json


Body

Name

Type

Required

Description

topic

string

Required

A topic from Webhook Events

callbackUrl

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

id

string

Subscription id

topic

string

The subscribed topic or wildcard

callbackUrl

string

Where deliveries are sent

previousSecretValidUntil

string

End of the rotation grace period, null if never rotated

signingSecret

string

64 hex characters. Returned once — store it now


Errors

Status

Cause

400 Bad Request

Unknown topic, non-HTTPS URL, or a URL pointing at an internal host

409 Conflict

This shop already has a subscription with the same topic and callbackUrl

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

id

string

Required

Subscription id


Body

Name

Type

Required

Description

callbackUrl

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

400 Bad Request

Malformed id, or a callbackUrl that fails validation

404 Not Found

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

id

string

Required

Subscription id


Body

Name

Type

Required

Description

graceHours

integer

Optional

How long the previous secret stays valid, 024. Defaults to 24. Send 0 to revoke it immediately


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

signingSecret

string

The new secret. Returned once — store it now

previousSecretValidUntil

string

When the old secret stops being accepted, 24 hours out


Errors

Status

Cause

400 Bad Request

Malformed id

404 Not Found

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

400 Bad Request

Malformed id

404 Not Found

No such subscription on your shop

Rate limits

Limits are per shop, measured over a rolling 60-second window.

Endpoint

Limit

GET/POST/PUT/DELETE on /webhooks/subscriptions

30 requests per minute

POST /webhooks/subscriptions/{id}/rotate-secret

5 requests per minute

GET /webhooks/deliveries

60 requests per minute

POST /webhooks/deliveries/{id}/replay

10 requests per minute


Exceeding a limit returns 429 Too Many Requests. Back off and retry.

Updated on: 27/08/2026

Was this article helpful?

Share your feedback

Cancel

Thank you!