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:
| Header | Innehåll |
|---|---|
webhook-id | Eventets unika id (idempotens i din mottagare). |
webhook-timestamp | Unix-timestamp för utskicket. |
webhook-signature | v1,<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):
Node.js
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.