Webhooks

Receive real-time notifications when orders, tasks, and listings change, instead of polling.

Setting Up a Webhook

Register an HTTPS endpoint from your dashboard’s developer settings, or via the API:

Register a webhook
curl -X POST https://api.baalvion.com/v1/webhooks \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://yourapp.example.com/webhooks/baalvion",
    "events": ["order.status_changed", "task.approval_requested"]
  }'

Events

EventDescription
order.createdA new order was created.
order.status_changedAn order’s status changed.
task.approval_requestedA task requires trade agent approval.
task.completedA task was marked complete.
listing.availability_lowA listing’s available quantity dropped below a threshold.

Payload Example

order.status_changed
{
  "event": "order.status_changed",
  "createdAt": "2026-02-01T12:15:00Z",
  "data": {
    "orderId": "ord_51c9a2",
    "previousStatus": "pending",
    "status": "fulfilling"
  }
}

Verifying Signatures

Every webhook request includes a Baalvion-Signature header — an HMAC-SHA256 signature of the raw request body, signed with your webhook’s signing secret. Verify it before trusting the payload:

verify.js
const crypto = require('crypto');

function isValidSignature(rawBody, signature, secret) {
  const expected = crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}
Always verify before processing
An unverified webhook payload could be spoofed by anyone who discovers your endpoint URL. Reject any request whose signature doesn’t match before acting on it.

Retries

If your endpoint doesn’t respond with a 2xx status, delivery is retried with exponential backoff for up to 24 hours. Respond quickly (acknowledge, then process asynchronously) to avoid unnecessary retries.