Skip to Content

Webhooks

A webhook tells your system the moment something happens in Clorvia — an invoice is created, a payment is recorded, a customer is updated — by sending a signed POST request to a URL you choose. This replaces having to poll the API on a timer, so your integrations stay in sync and use far fewer requests.

Register a webhook

  1. Go to Settings → APIs & Webhooks.
  2. Under Webhooks, click Create webhook.
  3. Enter the URL Clorvia should POST to (must be HTTPS and publicly reachable).
  4. Choose the events you want (see below).
  5. Save. A signing secret is generated — you’ll use it to verify deliveries.

Choose events

Events are named object.action, for example:

PatternFires when…
invoice.createda new invoice is created
invoice.updatedan invoice changes (e.g. marked paid)
party.createda new customer or supplier is added
payment.createda payment is recorded

You can use wildcards:

  • *.created — anything created
  • invoice.* — any change to invoices
  • * — every change

What Clorvia sends

A POST with a JSON body like:

{ "eventName": "invoice.updated", "objectNameSingular": "invoice", "action": "updated", "recordId": "…", "updatedFields": ["status"], "record": { "id": "…", "invoiceNumber": "INV-1042", "status": "Paid", "totalAmount": 11800 }, "before": { "status": "Unpaid" }, "after": { "status": "Paid" }, "eventDate": "2026-06-04T10:15:00.000Z" }

Headers on every delivery:

HeaderMeaning
X-Clorvia-Eventthe event name (e.g. invoice.updated)
X-Clorvia-Timestampwhen it was sent (Unix seconds)
X-Clorvia-SignatureHMAC‑SHA256 signature (see below)
X-Clorvia-Deliverya unique id for this delivery

Verify the signature

Always verify that a delivery really came from Clorvia before trusting it. The signature is HMAC‑SHA256 of timestamp + "." + rawBody, using your webhook’s signing secret, hex‑encoded.

const crypto = require('crypto') function isValid(req, secret) { const timestamp = req.headers['x-clorvia-timestamp'] const signature = req.headers['x-clorvia-signature'] const expected = crypto .createHmac('sha256', secret) .update(timestamp + '.' + req.rawBody) // the RAW request body, not re-serialized .digest('hex') // constant-time compare return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected)) }

Also reject deliveries whose X-Clorvia-Timestamp is more than a few minutes old (replay protection).

Retries & reliability

  • If your endpoint doesn’t return a 2xx, Clorvia retries with backoff.
  • Make your handler idempotent — use X-Clorvia-Delivery to ignore a delivery you’ve already processed.
  • Respond quickly (do heavy work asynchronously); return 200 as soon as you’ve safely received the event.
  • You can see recent delivery attempts for each webhook in Settings → APIs & Webhooks.

Manage & remove

Edit a webhook’s URL, events, or secret any time, or delete it to stop deliveries. Deleting is immediate.