Integration guide
Receive real-time changes for the enterprises and establishments you watch.
Full flow
- Create a webhook with your HTTPS URL and the entities to watch.
- Carefully store the HMAC secret — it is returned exactly once.
- On the next BCE sync, each change triggers a signed POST.
- Verify the signature on the receiver side before processing the payload.
Create a webhook
bash
curl -X POST https://companybelgium.be/api/v2/webhook \
-H "X-API-Key: $API_KEY" \
-H "X-API-Secret: $API_SECRET" \
-H "Content-Type: application/json" \
-d '{
"name": "Production listener",
"url": "https://hooks.example.com/companybelgium",
"entityNumbers": ["1033022383", "0202239951"]
}'⚠️ The `hmacSecret` field is returned exactly once on creation. Store it now — you will not be able to retrieve it again (only rotate it via PATCH /hmac-secret).
Payload format
http
POST https://hooks.example.com/companybelgium HTTP/1.1
Content-Type: application/json
X-CompanyBelgium-Signature: sha256=8e6c…
X-CompanyBelgium-Timestamp: 1747843200000
X-CompanyBelgium-Event: update
X-CompanyBelgium-Delivery: 9c1b…
{
"event": "update",
"entityNumber": "1033022383",
"entityType": "enterprise",
"data": {},
"timestamp": "2026-04-15T10:00:00.000Z"
}Signature verification
Reconstruct the HMAC on the receiver side with your secret + the timestamp and compare in constant time.
javascript
import crypto from "node:crypto"
function verify(req, secret) {
const signature = req.headers["x-companybelgium-signature"]
const timestamp = req.headers["x-companybelgium-timestamp"]
const body = req.rawBody // Express: use express.raw() or capture before json()
const expected = "sha256=" + crypto
.createHmac("sha256", secret)
.update(`${timestamp}.${body}`)
.digest("hex")
if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
throw new Error("Invalid signature")
}
// Reject signatures older than 5 minutes (replay protection)
if (Math.abs(Date.now() - Number(timestamp)) > 5 * 60_000) {
throw new Error("Timestamp too old")
}
}Retry policy
The dispatcher retries up to 3 times on network errors or 5xx, with exponential backoff (0.5s → 2s → 8s). 4xx are not retried. All attempts show up in GET /webhook/{id}/events.
Trigger a test
To verify your integration without waiting for a real BCE change, use the `trigger` endpoint.
bash
curl -X POST https://companybelgium.be/api/v2/webhook/$WEBHOOK_ID/trigger \
-H "X-API-Key: $API_KEY" \
-H "X-API-Secret: $API_SECRET" \
-H "Content-Type: application/json" \
-d '{"entityNumber":"1033022383","data":{"note":"manual test"}}'