ŽIVĚ · AUDIT CHAIN · EU
SYSTÉM · 99,99 % DOSTUPNOST
v 1.0 ↗ VYROBENO V EU

Webhooky

Webhooky jsou způsob, jak se váš backend dozví o věcech, které se dějí asynchronně — konec relací, dokončení post-processingu nahrávání, ukotvení auditních řetězců na TSA. Zaregistrujte URL, ověřte podpis u každého POST, dispečujte podle typu události.

Typy událostí

UdálostKdy
session.createdNová relace přes SPA nebo veřejné API
session.completedRelace ukončena (ručně nebo přes API)
participant.joinedUživatel v terénu (nebo pozorovatel) se připojil k relaci
participant.leftÚčastník se odpojil
evidence.addedZachycen nový snímek / anotace / tabule / klip / dokument
recording.readyK dispozici post-processované artefakty nahrávání
audit.anchoredHlava řetězce ukotvena u jedné z nakonfigurovaných TSA
signature.completedPodepsané PDF (SES/AES/QES) je připraveno ke stažení
webhook.testVyvoláno tlačítkem „Test fire“ v administraci SPA, s malým syntetickým payloadem

Podoba obálky

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

id je stabilní napříč opakováními — použijte jej jako idempotency key na straně příjemce.

Hlavička podpisu

Každý POST nese hlavičku NB-Signature ve formátu ve stylu Stripe:

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

Hodnota v1 je HMAC-SHA256(secret, "{timestamp}.{body}") v hex. Hodnota t je Unixové časové razítko v okamžiku podpisu. 5minutové okno tolerance odchylky odmítá replaye starších payloadů.

Ověřování v kódu

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)

Chování opakování

Doručení je považováno za úspěšné, když váš endpoint vrátí 2xx do 30 s. Cokoli jiného spouští exponenciální backoff:

30s 5m 1h 6h 24h DROPPED

Po 50 po sobě jdoucích selháních napříč všemi událostmi se endpoint automaticky deaktivuje. Administrátor organizace jej může znovu povolit z administrace SPA, jakmile je příjemce opět v provozu.

Idempotence na vaší straně

Doručení webhooků se mohou opakovat. Použijte event.id jako klíč pro deduplikaci:

-- 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.

Podpisové tajné klíče

Každý registrovaný webhook endpoint má vlastní podpisový tajný klíč whsec_*. Prostý text se zobrazí právě jednou při registraci endpointu (nebo jeho rotaci); poté ukládáme kopii šifrovanou pomocí Fernet a zobrazujeme pouze prvních 6 znaků pro identifikaci.

Rotujte přes SPA → Admin → Webhooks → Rotate secret. Stávající příjemci budou odmítat podepsané události, dokud nebudou aktualizováni novým tajným klíčem — naplánujte rotaci na dobu nasazení.

Testovací odeslání

Každý registrovaný endpoint má v administraci SPA tlačítko „Test fire“, které odešle obálku webhook.test, abyste mohli ověřit svého příjemce před ostrým provozem. Testovací obálka má stejný tvar jako reálná událost, ale se syntetickým payloadem označeným "test": true v data.

Protokol doručení

SPA → Admin → Webhooks zobrazuje posledních 100 doručení na endpoint s HTTP stavem, počtem pokusů, posledním tělem odpovědi (zkráceným) a časovými razítky. Filtrujte podle stavu / endpointu pro ladění problémů příjemce.