# Fouten en snelheidslimieten
Source: https://nordvec.com/nl/docs/guides/errors-and-rate-limits

De foutenvelop die elke mislukte aanvraag retourneert, de snelheidslimiet-headers en hoe je een schrijfopdracht veilig opnieuw kunt proberen.



Elke endpoint faalt op dezelfde manier, dus een client handelt fouten, snelheidslimieten en pogingen opnieuw af door die code één keer te schrijven en overal te hergebruiken, ook via [MCP](/docs/guides/mcp).

## De foutenvelop [#de-foutenvelop]

Elke niet-2xx-respons is één JSON-object:

```json
{
  "defined": false,
  "code": "TOO_MANY_REQUESTS",
  "message": "Too many requests",
  "data": { "reason": "rate_limit.exceeded", "retryAfterMs": 12000 }
}
```

* `code` is de fout op HTTP-niveau, bijvoorbeeld `UNAUTHORIZED`, `FORBIDDEN`,
  `NOT_FOUND`, `BAD_REQUEST` of `TOO_MANY_REQUESTS`.
* `data.reason`, indien aanwezig, is een preciezere machineleesbare reden zoals
  `auth.key_not_found` of `rate_limit.exceeded`. Baseer je hierop in plaats van op
  `message`, dat voor mensen is en kan veranderen.
* `defined` is `true` wanneer de bewerking die fout vermeldt in de
  [API-referentie](/docs/api), en `false` voor fouten die elke aanvraag kan tegenkomen
  (authenticatie, snelheidslimieten, een onbekende route).
* Een validatiefout antwoordt met `BAD_REQUEST` en de problemen in
  `data.formErrors` en `data.fieldErrors`.

Elke respons bevat ook een `X-Request-ID`. Vermeld deze wanneer je contact opneemt met support, zodat we die exacte aanvraag kunnen terugvinden.

## Gangbare statussen [#gangbare-statussen]

| Status | Code                    | Wat te doen                                                                    |
| ------ | ----------------------- | ------------------------------------------------------------------------------ |
| `400`  | `BAD_REQUEST`           | Corrigeer de aanvraag; `data.fieldErrors` benoemt de velden                    |
| `401`  | `UNAUTHORIZED`          | Verstuur een geldige sleutel of sessie                                         |
| `403`  | `FORBIDDEN`             | De sleutel heeft niet de vereiste scope of rol voor de bewerking               |
| `404`  | `NOT_FOUND`             | De resource bestaat niet, of je hebt geen toestemming om deze te zien          |
| `409`  | `CONFLICT`              | Een dubbele schrijfbewerking is nog bezig; probeer het kort daarna opnieuw     |
| `413`  | `PAYLOAD_TOO_LARGE`     | De aanvraagbody is groter dan 1 MB; splits een bulkpush op in kleinere batches |
| `422`  | `UNPROCESSABLE_CONTENT` | De aanvraag is correct gevormd maar kan niet worden toegepast                  |
| `429`  | `TOO_MANY_REQUESTS`     | Wacht `Retry-After`, probeer het dan opnieuw                                   |

## Snelheidslimieten [#snelheidslimieten]

Elke respons geeft de limiet aan waartegen deze is geteld, in twee vormen:

* de `X-RateLimit-*` headers;
* de IETF gestructureerde velden `RateLimit` (live status: `r` is het aantal resterende aanvragen, `t` de seconden tot het venster reset) en `RateLimit-Policy` (de quota: `q` is de limiet, `w` het venster in seconden).

Een `429` bevat ook `Retry-After` in seconden en `data.retryAfterMs`. Wacht minstens zo lang voordat je de volgende aanvraag doet; eerder opnieuw proberen wordt geteld en opnieuw geweigerd.

## Schrijfbewerkingen veilig opnieuw proberen [#schrijfbewerkingen-veilig-opnieuw-proberen]

Een schrijfbewerking die een `Idempotency-Key` header vermeldt in de
[API-referentie](/docs/api), kan opnieuw worden geprobeerd zonder het werk dubbel uit te voeren. Verstuur één sleutel per logische schrijfbewerking en herhaal dezelfde sleutel bij elke poging opnieuw:

* dezelfde sleutel met dezelfde body binnen 24 uur speelt de opgeslagen respons opnieuw af;
* dezelfde sleutel met een andere body wordt geweigerd met `422`;
* een duplicaat dat aankomt terwijl de eerste nog loopt, krijgt `409`.

Een bewerking zonder de header is niet idempotent, dus probeer deze alleen opnieuw als je zeker weet dat de eerste poging niet is geland.
