Skip to main content
Quickstarts

Quickstart: subscribe to webhook events

Create a webhook subscription, capture the signing secret, verify a delivery, and clean up. Runs end-to-end against live endpoints.

What this quickstart does

By the end of this quickstart you will have:

  1. Created a webhook subscription against POST /public/v1/orgs/:o/entities/:e/webhooks
  2. Captured the one-time signing_secret (returned only on creation)
  3. Listed your active subscriptions
  4. 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 like work_order.released, work_order.completed, lot.created, eco.released, and jobwork_challan.overdue are 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 | jq

Response (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.

Frequently asked questions

Can I update the topics on an existing subscription?

Not today. Delete and create — subscriptions are immutable for the topics array. The signing_secret will rotate on re-create, so update both sides at once.

What happens after too many failed deliveries?

ConsecutiveFailures increments on each non-2xx delivery. The exact threshold for auto-disable is governed server-side; treat ConsecutiveFailures > 0 as a signal to investigate your endpoint.

    Quickstart: HelloBooks Webhook Subscriptions