What this quickstart does
By the end of this quickstart you will have:
- Created a webhook subscription against
POST /public/v1/orgs/:o/entities/:e/webhooks - Captured the one-time
signing_secret(returned only on creation) - Listed your active subscriptions
- Deleted the subscription when no longer needed
Prerequisites: a working access token from the marketplace app setup quickstart and an HTTPS endpoint you control to receive webhook deliveries.
1. Pick a topic
Each subscription targets one or more event topics. Topics are namespaced <domain>.<resource>.<verb> — e.g. invoice.paid, bill.created. The list of currently published topics is governed server-side; consult your HelloBooks partner manager for the latest catalog.
Manufacturing topics are not yet emitted. Topics likework_order.released,work_order.completed,lot.created,eco.released, andjobwork_challan.overdueare on the roadmap (see Manufacturing API roadmap). Subscribing to them today will create the subscription row, but you will not receive any deliveries until the publisher ships.
2. Create the subscription
Set environment variables, then POST. Note the target_url MUST be HTTPS:
export HB_TOKEN="<access_token>"
export HB_ORG="<org_ref_id from /me>"
export HB_ENT="<entity_ref_id from /me>"
curl -s -X POST \
-H "Authorization: Bearer $HB_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"topics": ["invoice.paid", "bill.created"],
"target_url": "https://your-app.example.com/hellobooks/webhook"
}' \
https://api.hellobooks.com/public/v1/orgs/$HB_ORG/entities/$HB_ENT/webhooks | jqResponse (HTTP 201):
{
"id": "65f1aa...",
"topics": ["invoice.paid", "bill.created"],
"target_url": "https://your-app.example.com/hellobooks/webhook",
"signing_secret": "shhh-this-is-shown-once-base64",
"created_at": "2026-05-04T10:14:32.123Z"
}⚠️ **Store signing_secret immediately.** It's returned only on creation and is hashed server-side after that. If you lose it, delete the subscription and create a new one to receive a fresh secret.
3. Verify delivery signatures
Every webhook delivery to your target_url arrives with an X-HelloBooks-Signature header. Compute HMAC-SHA256 of the raw request body using your stored signing_secret and compare:
import crypto from "node:crypto";
function verify(req, secret) {
const sig = req.headers["x-hellobooks-signature"];
const expected = crypto
.createHmac("sha256", secret)
.update(req.rawBody) // raw bytes — do NOT JSON.stringify
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(sig, "hex"),
Buffer.from(expected, "hex"),
);
}Reject anything that fails verification with HTTP 401. Acknowledge successful processing with HTTP 2xx — non-2xx responses count as a failed delivery and increment ConsecutiveFailures on the subscription row.
4. List your subscriptions
curl -s -H "Authorization: Bearer $HB_TOKEN" \
https://api.hellobooks.com/public/v1/orgs/$HB_ORG/entities/$HB_ENT/webhooks | jq{
"subscriptions": [
{
"_id": "65f1aa...",
"Topics": ["invoice.paid", "bill.created"],
"TargetUrl": "https://your-app.example.com/hellobooks/webhook",
"IsActive": true,
"LastDeliveryAt": "2026-05-04T10:18:11.420Z",
"LastDeliveryStatus": 200,
"ConsecutiveFailures": 0,
"createdAt": "2026-05-04T10:14:32.123Z"
}
]
}Use ConsecutiveFailures and LastDeliveryStatus to monitor delivery health.
5. Delete when done
export HB_SUB="65f1aa..."
curl -s -X DELETE -H "Authorization: Bearer $HB_TOKEN" \
https://api.hellobooks.com/public/v1/orgs/$HB_ORG/entities/$HB_ENT/webhooks/$HB_SUB | jq{ "ok": true, "modified": 1 }Deletion is a soft-delete (IsActive: false) — re-listing will not include the deleted subscription, but the row is preserved for auditing.