Skip to Content
Konventioner

API-konventioner

Regler som gäller alla resurser i v1.

OmrådeRegel
FormatJSON UTF-8. Requests med body skickar Content-Type: application/json.
ID:nPublika UUID:er. Interna numeriska ID:n exponeras aldrig.
DatumISO 8601. Tidpunkter i UTC (2026-07-08T09:30:00Z); kalenderdatum YYYY-MM-DD.
Base URLVersionerad i pathen: https://api.kinmu.app/v1 · Dev: https://api.dev.kinmu.app/v1.

Paginering (cursor)

Alla listor pagineras med cursor:

  • ?limit= (default 25, max 100) · ?cursor=<opak>.
  • Svar: { "data": [...], "meta": { "next_cursor": "…"|null, "has_more": true|false } }.
  • För nästa sida skickar du tillbaka cursor=<meta.next_cursor>. has_more=false eller next_cursor=null → slut.
curl "https://api.kinmu.app/v1/employees?limit=50&cursor=eyJpZCI6MTIzfQ" \ -H "Authorization: Bearer kinmu_sk_live_…"

cursor är opak: bygg den inte och parsa den inte — skicka tillbaka den som den är.

Inkrementell synkronisering (updated_since)

Alla listor accepterar ?updated_since=<ISO 8601> för att hämta endast det som ändrats sedan den tidpunkten (inkrementell polling för BI och ERP-system).

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

Spara tidpunkten för din senaste synkronisering och använd den som updated_since i nästa. Hela mönstret finns i BI-guiden.

Fel

Alla fel följer 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" } }

Programmera mot fältet code (stabilt), inte mot title/detail.

Kodtabell

codeHTTPNär
unauthenticated401Nyckeln saknas, är ogiltig, återkallad eller utgången.
invalid_scope403Nyckeln saknar det scope som krävs (errors.required_scope).
subscription_inactive403Företagets prenumeration är pausad eller saknas.
addon_disabled403Addonet Public API är inte aktivt för företaget.
validation_failed422Ogiltig body eller ogiltiga parametrar (errors med detaljer per fält).
not_found404Resursen finns inte eller tillhör ett annat företag.
conflict409Tillståndskonflikt (t.ex. besluta en redan beslutad frånvaro).
idempotency_conflict409Samma Idempotency-Key återanvändes med en annan body.
rate_limited429Minutgränsen överskriden (se Retry-After).
quota_exceeded429Månadskvoten förbrukad.
billing_required402Planen tillåter inte åtgärden (t.ex. ny medarbetare utan ledig plats).
internal_error500Internt fel.

Multitenant-isolering. Att begära en resurs som tillhör ett annat företag ger 404 (not_found), aldrig en 403 som avslöjar att den finns.

Rate limits och kvot

Varje svar (2xx och 4xx) innehåller:

HeaderBetydelse
X-RateLimit-LimitNyckelns gräns per minut.
X-RateLimit-RemainingÅterstående requests i det aktuella fönstret.
X-RateLimit-ResetUnix-timestamp när fönstret nollställs.
X-Kinmu-Quota-RemainingÅterstående requests av månadskvoten.

Limits: live 120/min, test 30/min. Månadskvot: live 10.000 + 1.000×empleados_activos (max 100 000); test 5.000.

Överskrids minutgränsen → 429 rate_limited med Retry-After: <sekunder>. När kvoten är förbrukad → 429 quota_exceeded. Försök igen med backoff och respektera 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

Håll koll på X-RateLimit-Remaining och X-Kinmu-Quota-Remaining och glesa ut dina requests innan du får en 429.

Idempotens

I muterande metoder (POST / PATCH / DELETE) kan du skicka Idempotency-Key: <unik>:

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" }'

Den första requesten körs och dess svar cachas i 24 h; skickar du om den med samma body får du det ursprungliga svaret tillbaka (utan att den körs om). Att återanvända samma key med en annan body409 idempotency_conflict.

Skapandet av webhooks är det enda undantaget: dess copy-once-secret cachas aldrig.

Last updated on