Skip to Content

Webhooks

Webhooks deliver real-time notifications to your server whenever something changes — a job or step (Scheduler) or money movement (Payments). Instead of polling the API, you register an endpoint URL and BayWise pushes events to it. Pick the events you care about across both products when you register.

Register an endpoint

POST /v1/platform/webhooks

{ "url": "https://yourapp.example.com/hooks/baywise", "events": ["job.created", "job.delivered", "step.completed"] }

The response includes a signingSecret — store it securely. BayWise uses it to sign every delivery so you can verify requests came from us.

{ "id": "wh_...", "url": "https://yourapp.example.com/hooks/baywise", "events": ["job.created", "job.delivered", "step.completed"], "signingSecret": "a3f9...", "isActive": true }

Available events

Scheduler

EventWhen it fires
job.createdA new job is created
job.updatedAny field on a job changes
job.deliveredA job reaches the Delivered status
step.createdA new step is added to a job
step.updatedAny field on a step changes
step.completedA step is marked completed

The exact, current set of subscribable events is always shown in Settings → Developer when you register or edit a webhook — register only the ones you need.

Payload shape

Every webhook delivery sends a POST to your endpoint with a JSON body:

{ "event": "job.delivered", "occurredAt": "2026-06-15T09:42:00Z", "data": { "id": "...", "status": "delivered", "vehiclePlate": "ABC 123", ... } }

Verifying signatures

BayWise signs every delivery with HMAC-SHA256 using your signingSecret. Verify the signature to confirm the delivery is authentic.

The signature is in the X-BayWise-Signature request header:

X-BayWise-Signature: sha256=a1b2c3d4...

Verification steps

  1. Read the raw request body as a UTF-8 string (do not parse it first)
  2. Compute HMAC-SHA256(signingSecret, rawBody) and hex-encode the result
  3. Compare it to the value after sha256= in the header
import hmac, hashlib def verify_signature(secret: str, raw_body: bytes, signature_header: str) -> bool: expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest() received = signature_header.removeprefix("sha256=") return hmac.compare_digest(expected, received)
import { createHmac, timingSafeEqual } from 'node:crypto'; function verifySignature(secret, rawBody, signatureHeader) { const expected = createHmac('sha256', secret).update(rawBody).digest('hex'); const received = signatureHeader.replace('sha256=', ''); const a = Buffer.from(expected, 'hex'); const b = Buffer.from(received, 'hex'); return a.length === b.length && timingSafeEqual(a, b); }

Always use a constant-time comparison (hmac.compare_digest / timingSafeEqual) to prevent timing attacks.

Retry behaviour

If your endpoint returns a non-2xx response or times out (10 seconds), BayWise retries with exponential backoff:

AttemptDelay
1 (immediate)
21 minute
35 minutes
430 minutes
52 hours

After 5 failed attempts, the delivery is marked exhausted and no further retries occur. You can monitor delivery health in Settings → Integrations → Webhooks.

Respond quickly

Your endpoint should return 200 within 10 seconds. If processing takes longer, accept the webhook immediately and handle it asynchronously.

Managing registrations

ActionDescription
List webhooksGET /v1/platform/webhooks — see all registered endpoints
Update a webhookPATCH /v1/platform/webhooks/{id} — change the URL, events, or active state
Rotate the secretPATCH /v1/platform/webhooks/{id} with { "rotateSecret": true } — generates a new signing secret
Delete a webhookDELETE /v1/platform/webhooks/{id} — removes the registration and all delivery history