Ontwikkelaars · Begin hier
Conventies
JSON-conventies, centen, datums, fouten, rate limits en idempotency. Lees dit één keer en de rest is voorspelbaar.
Basis
- Base URL:
https://api.cijfr.com, alle paden beginnen met/api/v1. - Request- en response-bodies zijn JSON. Stuur
Content-Type: application/jsonbij een body. - Gelukt:
{ "data": … }. Mislukt:{ "error": "code" }met een passende HTTP-status. - Datums zijn
YYYY-MM-DD. Tijdstippen zijn ISO 8601 in UTC. - Bedragen zijn hele centen:
total_incl: 12100is €121,00. Geen kommagetallen. - Btw per regel is een
vatTreatment, bij producten een tarief in basispunten (vatRateBps, 2100 = 21%).
Lijsten, filters en paginatie
Lijst-endpoints pagineren met een cursor: ?limit= (1-100, standaard 50) en ?cursor= uit next_cursor van het vorige antwoord. De volgorde is created_at DESC, id DESC; het antwoord is { data: [...], has_more, next_cursor }. Filters verschillen per resource (q, status, customer_id, external_id, since) en staan per endpoint in de OpenAPI-spec.
Wijzigen en verwijderen kan voor concepten en stamdata via PATCH en DELETE. Een verstuurde (vergrendelde) factuur blijft ook voor de API onveranderbaar: correcties zijn creditnota's via POST /api/v1/invoices/{id}/credit-notes.
Rate limit en request-id
Per sleutel gelden 60 verzoeken per minuut, per organisatie 600 over alle sleutels. Elk antwoord draagt RateLimit-Limit, RateLimit-Remaining en RateLimit-Reset (seconden tot reset). Daarover antwoordt de API 429 met rate_limited en Retry-After.
Elk antwoord draagt ook X-Request-Id en hetzelfde request_id in het foutobject. Noem die id bij support, dan vinden wij het verzoek terug.
HTTP/1.1 429 Too Many Requests
Retry-After: 23
{"error":"rate_limited"}Idempotency
Elke POST accepteert een Idempotency-Key-header (maximaal 200 tekens). De API bewaart het antwoord per sleutel. Hetzelfde verzoek met dezelfde key speelt het bewaarde antwoord opnieuw af, zonder dubbel aan te maken. Dezelfde key met een ándere body is een 409 idempotency_conflict.
Loopt het eerste verzoek nog, dan krijgt een herhaling binnen twee minuten 409 idempotency_in_flight. Gebruik keys die uniek zijn per logische operatie, bijvoorbeeld je eigen order-id.
Fouten
| Status | error | Betekenis |
|---|---|---|
| 400 | validation | Body klopt niet met het schema, of een id bestaat niet in je organisatie. Het issues-veld benoemt het probleemveld |
| 404 | notFound | De resource bestaat niet in je organisatie |
| 409 | documentLocked | De factuur, offerte of creditnota is al uitgegeven en vergrendeld |
| 413 | payload_too_large | Body groter dan 512 kB |
| 401 | unauthorized | Sleutel ontbreekt, is onbekend, ingetrokken of verlopen |
| 402 | plan_limit_api | Je pakket heeft geen API-toegang (Studio nodig) |
| 402 | billing_readonly | Je abonnement blokkeert versturen; aanmaken als concept kan nog |
| 403 | forbidden | Scope ontbreekt of het profiel komt niet overeen |
| 409 | idempotency_conflict | Zelfde Idempotency-Key met een andere body |
| 409 | idempotency_in_flight | Zelfde key loopt nog, probeer het zo meteen opnieuw |
| 429 | rate_limited | Meer dan 60 verzoeken per minuut, zie Retry-After |
| 500 | generic | Fout aan de kant van Cijfr |
| 501 | unavailable | De API is tijdelijk niet beschikbaar |
Versies en status
De huidige versie is v1. Wijzigingen binnen v1 zijn backwards compatible: er kunnen velden bijkomen, bestaande velden verdwijnen niet.
GET https://api.cijfr.com/api/health is onbeveiligd en toont of de app en Supabase Auth gezond zijn. Handig voor een uptime-check.