Dokumentácia
Webhooky
Posledná aktualizácia: 15. januára 2026
Webhooky doručujú event-driven notifikácie do vášho systému keď sa zmení obsah platformy — nová povinnosť, schválený zmenový návrh, blížiaci sa termín. Každý payload je podpísaný HMAC SHA-256.
1. Eventy
obligation.published— nová povinnosť bola publikovanáobligation.updated— zmena v existujúcej povinnostiobligation.deprecated— povinnosť bola označená ako neaktuálnachange_proposal.approved— admin schválil návrh zmenydeadline.upcoming— termín do 30/14/7/1 dní (per company)statute.created— nový právny predpis pridaný do katalógu
2. Registrácia subscription
POST /api/v1/webhooks/subscriptions s body:
{
"url": "https://your-app.example.com/webhooks/clg",
"events": ["obligation.published", "obligation.updated"],
"active": true
}Response obsahuje secret (zobrazený iba raz) — uložte si ho. Tento tajomný kľúč slúži na overenie HMAC podpisu pri každom doručenom payload-e.
3. Payload formát
POST /your-receiver
Content-Type: application/json
X-CLG-Event: obligation.published
X-CLG-Delivery-ID: del_a1b2c3d4
X-CLG-Signature-256: sha256=7f3c8e9d...
X-CLG-Timestamp: 1719859200
{
"event": "obligation.published",
"deliveryId": "del_a1b2c3d4",
"occurredAt": "2026-01-15T10:30:00.000Z",
"data": {
"id": 247,
"title": "Štvrťročný report o flexibilnej kapacite",
"type": "FIXED",
"deadline": { "raw": "do 15. dňa po skončení Q", "date": null },
"_links": {
"self": "https://compliance.capitol-legal.com/api/v1/obligations/247",
"web": "https://compliance.capitol-legal.com/obligations/247"
}
}
}4. Overenie HMAC podpisu
Kanonická správa =
timestamp + "." + raw_body. HMAC SHA-256 s vaším secret. Porovnanie konstantnou-časovou funkciou (timing-safe).
Node.js / TypeScript receiver
import crypto from 'node:crypto';
import express from 'express';
const app = express();
const SECRET = process.env.CLG_WEBHOOK_SECRET!;
// IMPORTANT: získať raw body PRED akýmkoľvek JSON parserom
app.post(
'/webhooks/clg',
express.raw({ type: 'application/json' }),
(req, res) => {
const sig = req.header('X-CLG-Signature-256') ?? '';
const ts = req.header('X-CLG-Timestamp') ?? '';
const body = req.body as Buffer;
// Replay protection — odmietni eventy staršie ako 5 min
const ageSec = Date.now() / 1000 - Number(ts);
if (!Number.isFinite(ageSec) || Math.abs(ageSec) > 300) {
return res.status(400).send('stale timestamp');
}
const expected =
'sha256=' +
crypto
.createHmac('sha256', SECRET)
.update(`${ts}.${body.toString('utf8')}`)
.digest('hex');
const ok = crypto.timingSafeEqual(
Buffer.from(sig),
Buffer.from(expected),
);
if (!ok) return res.status(401).send('bad signature');
const event = JSON.parse(body.toString('utf8'));
console.log('CLG event:', event.event, event.data);
// Odpovedz 2xx do 5 sekúnd, inak retry policy stop
res.status(200).end();
},
);
app.listen(3001);5. Retry policy
Pri neúspešnom doručení (HTTP status >= 400 alebo timeout 5s) opakujeme s exponenciálnym backoff-om:
- 1. retry — po 30 sekundách
- 2. retry — po 5 minútach
- 3. retry — po 30 minútach
- 4. retry — po 6 hodinách
- 5. retry — po 24 hodinách
Po 5 neúspešných pokusoch endpoint auto-deactivuje. Manuálnu reaktiváciu urobíte v /account/webhooks alebo cez API. Posledných 30 dní deliveries je viditeľných v UI s payload + status pre debugging.
6. Bezpečnostné odporúčania
- Vždy overujte HMAC podpis pred spracovaním payload-u.
- Implementujte idempotency cez
deliveryId— opakovaný retry doručí ten istý event s rovnakým ID. - Receiver endpoint nech beží len cez HTTPS (HTTP 1.1+). Self-signed certifikáty sú odmietnuté.
- Whitelist náš egress IP rozsah (nájdete v
/status) ak váš firewall obmedzuje inbound traffic. - Tajomný kľúč nikdy nelogujte ani neukladajte do repozitára. Použite environment variable alebo secret manager (AWS Secrets Manager, GCP Secret Manager, HashiCorp Vault).