Utvecklardokumentation

Bolio Webhooks

Utgående HTTPS-anrop varje gång något viktigt händer i din arbetsyta — skapade kunder, offerter, jobb, besök, fakturor och betalningar. Kompatibla med Zapier, Make.com, n8n eller en egen HTTP-server.

Kom igång på 60 sekunder

  1. Skapa en Zap med triggern Webhook by Zapier → Catch Hook.
  2. Kopiera Zapier-URL:en.
  3. Gå till Inställningar → Webhooks i Bolio och klicka Ny webhook.
  4. Klistra in URL:en, välj vilka händelser du vill lyssna på, spara.
  5. Spara hemligheten som visas — den används för att verifiera att anropen kommer från Bolio.
  6. Klicka på Skicka test-ikonen så får Zapier ett exempel-event att bygga vidare på.

Payload-format

Alla anrop är POST med JSON-body. Följande headers sätts alltid:

Content-Type: application/json
X-Webhook-Event: invoice.paid
X-Webhook-Timestamp: 1783165005
X-Webhook-Delivery: 4c7d0f0e-9b8c-4c67-9c66-3f6b0f8d4e10
X-Webhook-Signature: t=1783165005,v1=<hex>
User-Agent: Bolio-Webhooks/1.0

Body-struktur:

{
  "event": "invoice.paid",
  "ts": 1783165005,
  "delivery_id": "4c7d0f0e-9b8c-4c67-9c66-3f6b0f8d4e10",
  "data": {
    "invoice_id": "…",
    "invoice_number": 1042,
    "total_amount": 12500,
    "amount_paid": 12500,
    "method": "swish"
  }
}

Idempotens: vid retry återanvänds samma delivery_id. Filtrera bort dubbletter i din integration genom att spara mottagna id:n.

Verifiera signaturen (HMAC-SHA256)

Signaturen räknas ut som HMAC_SHA256(secret, "{ts}.{body}") och skickas i headern X-Webhook-Signature som t=<ts>,v1=<hex>.

// Node.js
import { createHmac, timingSafeEqual } from "node:crypto";

function verifyBolio(req, secret) {
  const sig = req.headers["x-webhook-signature"] ?? "";
  const ts  = req.headers["x-webhook-timestamp"] ?? "";
  const m   = /t=(\d+),v1=([a-f0-9]+)/.exec(sig);
  if (!m || m[1] !== ts) return false;
  const expected = createHmac("sha256", secret)
    .update(ts + "." + req.rawBody).digest("hex");
  const a = Buffer.from(m[2]), b = Buffer.from(expected);
  return a.length === b.length && timingSafeEqual(a, b);
}
# Python
import hmac, hashlib, re
import { SITE_URL } from "@/lib/public-url";

def verify_bolio(headers, raw_body, secret):
    sig = headers.get("x-webhook-signature", "")
    ts  = headers.get("x-webhook-timestamp", "")
    m = re.match(r"t=(\d+),v1=([a-f0-9]+)", sig)
    if not m or m.group(1) != ts:
        return False
    expected = hmac.new(secret.encode(), f"{ts}.{raw_body}".encode(),
                        hashlib.sha256).hexdigest()
    return hmac.compare_digest(m.group(2), expected)

Retry & auto-paus

  • Timeout per försök: 5 sekunder.
  • Räknas som lyckad vid HTTP 2xx.
  • Vid fel görs upp till 5 försök med exponentiell backoff: 5 → 10 → 20 → 40 → 60 min.
  • Efter 20 misslyckade leveranser i rad pausas prenumerationen automatiskt och en notifikation skickas till org-adminen. Aktivera manuellt igen när URL:en fungerar.
  • Räknaren nollställs vid varje lyckad leverans.

Alla event-typer

client.createdclient.updatedrequest.receivedquote.createdquote.sentquote.approvedquote.declinedjob.createdjob.startedjob.completedvisit.createdvisit.updatedvisit.rescheduledvisit.assignedvisit.unassignedvisit.completedvisit.cancelledbooking.createdinvoice.createdinvoice.sentinvoice.overdueinvoice.paidinvoice.voidedpayment.received

Nya event läggs till löpande — dina zaps påverkas inte.