LIVE · AUDIT-KEDJA · EU-VÄRD
SYSTEM · 99,99 % DRIFTSTID
v 1.0 ↗ TILLVERKAT I EU

Webhooks

Webhooks är hur din backend får reda på saker som händer asynkront — sessioner som avslutas, inspelningar som blir klara med efterbearbetning, granskningskedjor som förankras hos TSA:n. Registrera en URL, verifiera signaturen på varje POST, dirigera på händelsetyp.

Händelsetyper

HändelseNär
session.createdNy session via SPA eller publikt API
session.completedSession avslutad (manuellt eller via API)
participant.joinedFältanvändare (eller observatör) anslöt till en session
participant.leftDeltagare kopplades från
evidence.addedNy skärmdump / anteckning / whiteboard / klipp / dokument fångad
recording.readyEfterbearbetade inspelningsartefakter tillgängliga
audit.anchoredKedjehuvud förankrat hos en av de konfigurerade TSA:erna
signature.completedEn signerad PDF (SES/AES/QES) är klar för nedladdning
webhook.testAvfyrad av knappen "Test fire" i SPA-adminen, med en liten syntetisk payload

Kuvertets form

{
  "id": "evt_01HGB9...",
  "type": "session.completed",
  "created_at": "2026-05-23T11:42:15Z",
  "org_id": 42,
  "data": {
    /* event-specific payload — full resource shape */
  }
}

id är stabilt över omförsök — använd det som din idempotensnyckel på mottagarsidan.

Signaturheader

Varje POST bär en NB-Signature-header i Stripe-liknande format:

NB-Signature: t=1716461235,v1=5257a8...3e2c1f

Värdet v1 är HMAC-SHA256(secret, "{timestamp}.{body}") i hex. Värdet t är en Unix-tidsstämpel vid signeringstillfället. Ett skevningsfönster på 5 minuter avvisar återuppspelningar av äldre payloads.

Verifiera i kod

Node

import { NexBasira, InvalidSignatureError } from "@nexbasira/node";

const nb = new NexBasira({ apiKey: "...", apiSecret: "..." });

// Express handler — important: use express.raw() so the body is the
// untouched bytes the signature was computed over.
app.post("/nb-webhook", express.raw({ type: "application/json" }), (req, res) => {
  const sig = req.header("NB-Signature")!;
  const secret = process.env.NB_WEBHOOK_SECRET!;
  let event;
  try {
    event = nb.webhooks.constructEvent(req.body, sig, secret);
  } catch (err) {
    if (err instanceof InvalidSignatureError) {
      return res.status(401).send("bad signature");
    }
    throw err;
  }
  // event is now type-narrowed by event.type
  return handleEvent(event, res);
});

Python

from nexbasira import NexBasira, InvalidSignatureError

nb = NexBasira(api_key="...", api_secret="...")

# Flask handler — get the raw body, not request.get_json()
@app.post("/nb-webhook")
def webhook():
    sig = request.headers["NB-Signature"]
    secret = os.environ["NB_WEBHOOK_SECRET"]
    try:
        event = nb.webhooks.construct_event(request.data, sig, secret)
    except InvalidSignatureError:
        return ("bad signature", 401)
    return handle_event(event)

Omförsöksbeteende

En leverans anses lyckad när din endpoint returnerar en 2xx inom 30s. Allt annat utlöser exponentiell backoff:

30s 5m 1h 6h 24h DROPPED

Efter 50 misslyckanden i följd över alla händelser avaktiveras endpointen automatiskt. Org-adminen kan återaktivera från SPA-adminen när mottagaren är tillbaka.

Idempotens på din sida

Webhook-leveranser kan upprepas. Behandla event.id som deduplikationsnyckel:

-- Postgres example
INSERT INTO webhook_deliveries (event_id, processed_at)
VALUES ($1, NOW())
ON CONFLICT (event_id) DO NOTHING
RETURNING event_id;
-- If RETURNING is empty, this is a duplicate — skip the side-effect.

Signeringshemligheter

Varje registrerad webhook-endpoint har sin egen whsec_*-signeringshemlighet. Klartexten visas exakt en gång när du registrerar endpointen (eller roterar den); därefter lagrar vi en Fernet-krypterad kopia och visar bara de första 6 tecknen för identifiering.

Rotera från SPA → Admin → Webhooks → Rotera hemlighet. Befintliga mottagare kommer att avvisa signerade händelser tills de uppdaterats med den nya hemligheten — schemalägg rotationen med ett deploy-fönster.

Test fire

Varje registrerad endpoint har en "Test fire"-knapp i SPA-adminen som skickar ett webhook.test-kuvert så att du kan verifiera din mottagare innan du går live. Testkuvertet har samma form som en riktig händelse men med en syntetisk payload taggad "test": true i data.

Leveranslogg

SPA → Admin → Webhooks visar de senaste 100 leveranserna per endpoint med HTTP-status, försök, senaste svarskropp (avkortad) och tidsstämplar. Filtrera på status / endpoint för att felsöka mottagarproblem.