Skip to main content

Webhooks

Webhooks push real-time event notifications to your server when things happen in Brother POS — a sale completes, a product is updated, inventory changes, etc. This is more efficient than polling the API repeatedly.


How Webhooks Work

  1. You create a webhook subscription via the API, specifying a URL and which events to listen for.
  2. When a subscribed event occurs, Brother POS sends an HTTP POST to your URL with the event data.
  3. Your server processes the event and returns a 2xx status code.

Creating a Subscription

Your API key needs the webhooks:manage scope.

curl -X POST \
-H "X-API-Key: bpos_abc..." \
-H "Content-Type: application/json" \
-d '{
"webhook_subscription": {
"url": "https://your-server.com/webhooks/brotherpos",
"events": ["sale.completed", "product.updated"]
}
}' \
https://yourstore.brotherpos.ca/api/v1/webhook_subscriptions
HTTPS required

Webhook URLs must use HTTPS. HTTP URLs will be rejected. URLs pointing to private/internal IP addresses are also blocked.


Available Events

EventFires When
sale.completedA sale is completed (payment received)
sale.voidedA completed sale is voided
product.createdA new product is added
product.updatedA product's details change (price, name, stock, etc.)
product.deletedA product is deleted
customer.createdA new customer is added
customer.updatedA customer's details change
inventory.adjustedA stock adjustment is made (receive, count, spoilage, etc.)

Webhook Payload

{
"id": "a1b2c3d4-e5f6-...",
"event": "sale.completed",
"resource_type": "Sale",
"resource_id": 12345,
"created_at": "2026-03-22T14:30:00Z",
"data": {
"id": 12345,
"receipt_number": "R-001234",
"status": "completed",
"total": 47.50,
"line_items": [ ... ],
"customer": { ... }
}
}

For *.deleted events, data contains only { "id": 12345 } since the resource no longer exists.


Verifying Signatures

Every webhook delivery includes an HMAC-SHA256 signature in the X-BrotherPOS-Signature header. Use this to verify the webhook came from Brother POS.

X-BrotherPOS-Signature: sha256=a1b2c3d4e5f6...
X-BrotherPOS-Event: sale.completed
X-BrotherPOS-Delivery: a1b2c3d4-e5f6-...

Verification Example (Node.js)

const crypto = require('crypto');

function verifyWebhook(body, signature, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}

Verification Example (Python)

import hmac, hashlib

def verify_webhook(body: bytes, signature: str, secret: str) -> bool:
expected = 'sha256=' + hmac.new(
secret.encode(), body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)

The signing secret is generated when you create the subscription. It's included in the creation response but cannot be retrieved afterward.


Retry Policy

If your server doesn't respond with a 2xx status within 10 seconds, the delivery is marked as failed.

  • Failed deliveries are retried with exponential backoff (approximately 30s, 2m, 15m, 1h, 4h).
  • After 5 consecutive failures, the subscription is automatically disabled.
  • You can re-enable a disabled subscription from the Admin Panel under Developer API > Webhooks.

Managing Subscriptions

List Subscriptions

curl -H "X-API-Key: bpos_abc..." \
https://yourstore.brotherpos.ca/api/v1/webhook_subscriptions

Update a Subscription

curl -X PATCH \
-H "X-API-Key: bpos_abc..." \
-H "Content-Type: application/json" \
-d '{"webhook_subscription": {"events": ["sale.completed"]}}' \
https://yourstore.brotherpos.ca/api/v1/webhook_subscriptions/1

Delete a Subscription

curl -X DELETE \
-H "X-API-Key: bpos_abc..." \
https://yourstore.brotherpos.ca/api/v1/webhook_subscriptions/1

Send a Test Ping

curl -X POST \
-H "X-API-Key: bpos_abc..." \
https://yourstore.brotherpos.ca/api/v1/webhook_subscriptions/1/test

Monitoring in the Admin Panel

Go to Developer API > Webhooks to see all webhook subscriptions, their status, failure counts, and recent delivery logs. If a subscription was auto-disabled, click Reset Failures & Re-enable to resume deliveries.


What's Next?