Skip to Content
Webhooks

Webhooks

I stället för att polla kan du prenumerera på utgående events: Kinmu skickar en POST till din HTTPS-endpoint när något relevant inträffar. Varje leverans är signerad enligt konventionen Standard Webhooks verifiera alltid signaturen innan du bearbetar eventet.

Hantering av endpoints kräver scopet webhooks:manage och görs från dashboarden eller via endpoints under /v1/webhook-endpoints.

Prenumeration

Skapa en endpoint genom att ange din URL (HTTPS) och de events du vill ha:

curl -s -X POST "https://api.kinmu.app/v1/webhook-endpoints" \ -H "Authorization: Bearer kinmu_sk_live_…" \ -H "Content-Type: application/json" \ -d '{ "url": "https://tu-app.example.com/webhooks/kinmu", "events": ["absence.approved", "checkin.created"], "description": "Sync con nuestro ERP" }'

Svaret innehåller signeringssecretet (whsec_…), synligt en enda gång. Spara det: du behöver det för att verifiera signaturerna.

Tillgänglig hantering: GET (lista), GET /{id}, PATCH /{id} (events/status), DELETE /{id}, POST /{id}/test (skickar ett ping), GET /{id}/deliveries (senaste leveranserna) och POST /{id}/deliveries/{deliveryId}/retry (köar om en specifik leverans). Max 5 aktiva endpoints per företag.

Events

employee.created, employee.updated, employee.terminated, checkin.created, absence.requested, absence.approved, absence.denied, absence.cancelled, vacation_balance.updated, report.completed, ping.

Eventets payload

{ "id": "evt_…", "type": "absence.approved", "created_at": "…", "company_id": "…", "data": { } }

data innehåller publika id:n + status (minimalt); hämta den fullständiga resursen via GET när du behöver alla fält.

Verifiera signaturen

Varje leverans kommer med tre headers:

HeaderInnehåll
webhook-idEventets unika id (idempotens i din mottagare).
webhook-timestampUnix-timestamp för utskicket.
webhook-signaturev1,<signatur> (flera kan förekomma, separerade med mellanslag).

Algoritm: signatur = base64( HMAC_SHA256( key, "{webhook-id}.{webhook-timestamp}.{raw_body}" ) ), prefixad med v1,. Nyckeln är delen efter whsec_ i secretet (visas en enda gång när webhooken skapas), base64-avkodad till bytes. Signaturen beräknas över rå body (exakt de bytes du tog emot), inte över omserialiserad JSON.

Verifiering (avvisa om signaturen inte stämmer eller om webhook-timestamp avviker > 5 min från din klocka):

const crypto = require('crypto'); function verify(secret, headers, rawBody) { const id = headers['webhook-id']; const ts = headers['webhook-timestamp']; if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false; // ±5 min const key = Buffer.from(secret.replace(/^whsec_/, ''), 'base64'); const expected = 'v1,' + crypto .createHmac('sha256', key) .update(`${id}.${ts}.${rawBody}`) .digest('base64'); return headers['webhook-signature'] .split(' ') .some(sig => crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))); }

Verifiera och signera över rå body (exakt de bytes du tog emot), inte över omserialiserad JSON — varje omformatering gör signaturen ogiltig. Använd webhook-id som idempotensnyckel i din mottagare för att kasta omsändningar.

Omförsök

Vid fel (eller svar ≠ 2xx) gör Kinmu omförsök med backoff: 1 min, 5 min, 30 min, 2 h, 12 h, 24 h. Svara 2xx snabbt; bearbeta asynkront om det tar tid. En endpoint som misslyckas 7 dagar i rad inaktiveras automatiskt.

Du kan köa om en misslyckad leverans manuellt med POST /v1/webhook-endpoints/{id}/deliveries/{deliveryId}/retry (använd leveransens id från GET /{id}/deliveries).

Bästa praxis

Svara snabbt, bearbeta i bakgrunden

Verifiera signaturen, lägg jobbet i kö och svara 2xx direkt.

Verifiera alltid signaturen

Bearbeta aldrig en payload utan att verifiera webhook-signature. Behandla secretet som en credential.

Var idempotent

Deduplicera på webhook-id. Omförsök är normalt.

Testa med ping

Använd POST /v1/webhook-endpoints/{id}/test för att ta emot ett ping-event och validera din integration hela vägen.

Last updated on