Skip to Content
Conventies

API-conventies

Regels die voor alle resources van v1 gelden.

OnderwerpRegel
FormaatJSON UTF-8. Requests met een body sturen Content-Type: application/json mee.
IDsPublieke UUID’s. Interne numerieke IDs worden nooit blootgesteld.
DatumsISO 8601. Tijdstippen in UTC (2026-07-08T09:30:00Z); kalenderdatums als YYYY-MM-DD.
Base URLVersie in het pad: https://api.kinmu.app/v1 · Dev: https://api.dev.kinmu.app/v1.

Paginering (cursor)

Alle lijst-endpoints pagineren met een cursor:

  • ?limit= (default 25, max 100) · ?cursor=<opaak>.
  • Response: { "data": [...], "meta": { "next_cursor": "…"|null, "has_more": true|false } }.
  • Stuur voor de volgende pagina cursor=<meta.next_cursor> mee. has_more=false of next_cursor=null → einde.
curl "https://api.kinmu.app/v1/employees?limit=50&cursor=eyJpZCI6MTIzfQ" \ -H "Authorization: Bearer kinmu_sk_live_…"

De cursor is opaak: bouw of parse hem niet zelf, maar stuur hem ongewijzigd terug.

Incrementele synchronisatie (updated_since)

Alle lijst-endpoints accepteren ?updated_since=<ISO 8601> om alleen wat er sinds dat moment is gewijzigd op te halen (incrementeel pollen voor BI en ERP’s).

curl "https://api.kinmu.app/v1/employees?updated_since=2026-07-01T00:00:00Z" \ -H "Authorization: Bearer kinmu_sk_live_…"

Bewaar het tijdstip van je laatste synchronisatie en gebruik het als updated_since bij de volgende. Zie het volledige patroon in de BI-gids.

Fouten

Alle fouten volgen RFC 9457 (application/problem+json):

{ "type": "https://docs.kinmu.app/errors/invalid_scope", "title": "Scope insuficiente", "status": 403, "code": "invalid_scope", "detail": "La API key no tiene el scope requerido: org:empleados:read.", "errors": { "required_scope": "org:empleados:read" } }

Programmeer tegen het veld code (stabiel), niet tegen title/detail.

Codetabel

codeHTTPWanneer
unauthenticated401De key ontbreekt, is ongeldig, ingetrokken of verlopen.
invalid_scope403De key mist de vereiste scope (errors.required_scope).
subscription_inactive403Het abonnement van het bedrijf is opgeschort of ontbreekt.
addon_disabled403De addon Public API is niet actief voor het bedrijf.
validation_failed422Ongeldige body/parameters (errors met details per veld).
not_found404De resource bestaat niet of hoort bij een ander bedrijf.
conflict409Statusconflict (bijv. beslissen over een al besliste afwezigheid).
idempotency_conflict409De Idempotency-Key is hergebruikt met een andere body.
rate_limited429Limiet per minuut overschreden (zie Retry-After).
quota_exceeded429Maandelijkse quota opgebruikt.
billing_required402Het plan staat de actie niet toe (bijv. medewerker aanmaken zonder seat).
internal_error500Interne fout.

Multitenant-isolatie. Een resource van een ander bedrijf opvragen geeft 404 (not_found), nooit een 403 die het bestaan ervan verraadt.

Rate limits en quota

Elke response (2xx en 4xx) bevat:

HeaderBetekenis
X-RateLimit-LimitLimiet per minuut van de key.
X-RateLimit-RemainingResterende requests in het huidige venster.
X-RateLimit-ResetUnix-timestamp waarop het venster reset.
X-Kinmu-Quota-RemainingResterende requests van de maandelijkse quota.

Limieten: live 120/min, test 30/min. Maandelijkse quota: live 10.000 + 1.000×actieve_medewerkers (max 100.000); test 5.000.

Overschrijd je de minuutlimiet → 429 rate_limited met Retry-After: <seconden>. Is de quota op → 429 quota_exceeded. Retry met backoff en respecteer Retry-After.

import time, requests def call_with_retry(session, method, url, **kwargs): for attempt in range(5): resp = session.request(method, url, **kwargs) if resp.status_code != 429: return resp wait = int(resp.headers.get("Retry-After", 2 ** attempt)) time.sleep(wait) resp.raise_for_status() return resp

Houd X-RateLimit-Remaining en X-Kinmu-Quota-Remaining in de gaten en spreid je requests voordat je een 429 krijgt.

Idempotentie

Bij muterende methodes (POST / PATCH / DELETE) kun je Idempotency-Key: <uniek> meesturen:

curl -s -X POST "https://api.kinmu.app/v1/check-ins" \ -H "Authorization: Bearer kinmu_sk_live_…" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: 3f9a…-uuid" \ -d '{ "employee_id": "…", "type": "in", "timestamp": "2026-07-08T08:00:00Z" }'

De eerste request wordt uitgevoerd en de response wordt 24 uur gecachet; een herhaalde request met dezelfde body krijgt de oorspronkelijke response terug (zonder opnieuw uit te voeren). Dezelfde key hergebruiken met een andere body409 idempotency_conflict.

Het aanmaken van een webhook is de enige uitzondering: het copy-once secret wordt nooit gecachet.

Last updated on