> ## Documentation Index
> Fetch the complete documentation index at: https://docs.enrow.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Foutafhandeling

> Handel Enrow API-fouten netjes af — responsformaten, statuscodes, retry-logica en best practices

De Enrow API signaleert problemen met HTTP-statuscodes en een JSON-foutbody. Deze gids legt de foutresponsformaten uit, de meest voorkomende fouten en hoe je ze oplost, en hoe je betrouwbare retry-logica bouwt. Voor de volledige lijst met codes, zie [Statuscodes](/nl/status-codes).

## Hoe ziet een foutrespons eruit?

De meeste Enrow API-fouten retourneren een eenvoudig JSON-object met één `message`-veld:

```json theme={null}
{
  "message": "Human-readable error description"
}
```

De enige uitzondering is een fout wegens **onvoldoende krediet (402)** op **enkelvoudige** endpoints (email/phone find single, verify single), die een `reason`-veld naast `success` retourneert:

```json theme={null}
{
  "reason": "Insufficient credits",
  "success": false
}
```

Foutresponses bevatten nooit de velden `error`, `status` of `retry_after`. Lees de HTTP-statuscode om je logica te vertakken, en lees `message` (of `reason`) voor de leesbare beschrijving.

## Wat zijn de meest voorkomende fouten en hoe los ik ze op?

De onderstaande fouten dekken het overgrote deel van de mislukte verzoeken. Bij elk staat de responsbody die de API retourneert en de oplossing.

### Waarom krijg ik een 400 Bad Request?

Een `400` betekent dat de request-payload onjuist is opgemaakt of dat er een verplichte parameter ontbreekt:

```json theme={null}
{
  "message": "both company_domain and company_name are absent, input payload needs at least one of them"
}
```

**Oplossing**: Controleer of je alle verplichte parameters voor het endpoint meegeeft. [Find Single Email](/nl/api-reference/email-finder/find-single) vereist bijvoorbeeld `fullname` plus ofwel `company_domain` ofwel `company_name`.

### Waarom krijg ik een 401 Unauthorized?

Een `401` betekent dat de API-sleutel ontbreekt of ongeldig is:

```json theme={null}
{
  "message": "This apikey is not valid"
}
```

**Oplossing**: Controleer of de API-sleutel correct is en wordt verzonden in de `x-api-key`-header (niet `Authorization`). Zie [Authenticatie](/nl/authentication) voor hoe je de sleutel bij elk verzoek meegeeft.

### Waarom krijg ik een 402 Insufficient Credits?

Een `402` betekent dat het account niet genoeg credits heeft om het verzoek uit te voeren:

```json theme={null}
{
  "reason": "Insufficient credits",
  "success": false
}
```

Op **bulk**-endpoints wordt dezelfde `402` geretourneerd met de standaardvorm `{ "message": "..." }` in plaats daarvan.

**Oplossing**: Controleer het kredietsaldo op het [Dashboard](https://app.enrow.io) of via `GET /account/info`. Vul credits aan of upgrade het plan op [enrow.io/pricing](https://enrow.io/pricing). Zie [Credits en facturatie](/nl/credits-billing) voor hoe credits per endpoint worden verbruikt.

### Waarom krijg ik een 429 Rate Limit Exceeded?

Een `429` betekent dat er te veel verzoeken in een korte periode zijn verzonden:

```json theme={null}
{
  "message": "Too Many Requests"
}
```

**Oplossing**: Wacht en probeer het opnieuw met exponentiële backoff. Zie [Rate limits](/nl/rate-limits) voor de limieten per plan.

### Waarom krijg ik een 500 Internal Server Error?

Een `500` betekent dat er iets is misgegaan aan de kant van Enrow:

```json theme={null}
{
  "message": "An unexpected error occurred"
}
```

**Oplossing**: Probeer het verzoek opnieuw met backoff. Als het probleem aanhoudt, neem dan contact op met [api@enrow.io](mailto:api@enrow.io).

## Hoe handel ik fouten af in code?

Controleer de HTTP-status voordat je de succesbody parseert, en gooi vervolgens een fout die de statuscode meedraagt, zodat je retry-logica erop kan vertakken. Het `message`-veld bevat de beschrijving voor de meeste fouten, en `reason` bevat deze voor `402`-responses op enkelvoudige endpoints.

<CodeGroup>
  ```javascript Node.js theme={null}
  async function findEmail(contact) {
    const response = await fetch('https://api.enrow.io/email/find/single', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': process.env.ENROW_API_KEY
      },
      body: JSON.stringify(contact)
    });

    if (!response.ok) {
      const body = await response.json();
      const error = new Error(`Enrow API error ${response.status}: ${body.message || body.reason}`);
      error.status = response.status;
      throw error;
    }

    return await response.json();
  }
  ```

  ```python Python theme={null}
  import requests
  import os

  def find_email(contact):
      response = requests.post(
          "https://api.enrow.io/email/find/single",
          json=contact,
          headers={
              "Content-Type": "application/json",
              "x-api-key": os.getenv("ENROW_API_KEY")
          }
      )

      if not response.ok:
          error = response.json()
          message = error.get("message") or error.get("reason")
          raise Exception(f"Enrow API error {response.status_code}: {message}")

      return response.json()
  ```
</CodeGroup>

## Hoe probeer ik mislukte verzoeken opnieuw?

Probeer alleen de fouten opnieuw die de moeite waard zijn — `429` en `5xx` — en gebruik exponentiële backoff tussen pogingen. Clientfouten in de `4xx`-reeks (behalve `429`) wijzen op een probleem met het verzoek zelf, dus opnieuw proberen helpt niet.

```javascript theme={null}
async function requestWithRetry(fn, maxRetries = 3, baseDelay = 1000) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await fn();
    } catch (error) {
      const isLastAttempt = attempt === maxRetries - 1;

      // Don't retry client errors (except rate limits)
      if (error.status >= 400 && error.status < 500 && error.status !== 429) {
        throw error;
      }

      if (isLastAttempt) throw error;

      const delay = baseDelay * Math.pow(2, attempt);

      await new Promise(resolve => setTimeout(resolve, delay));
    }
  }
}
```

## Best practices

* **Probeer 4xx-fouten niet opnieuw** (behalve 429) — corrigeer in plaats daarvan het verzoek
* **Probeer 429-fouten opnieuw** — gebruik exponentiële vertragingen voordat je het opnieuw probeert
* **Probeer 5xx-fouten opnieuw** — met exponentiële backoff
* **Gebruik webhooks** in plaats van polling om te voorkomen dat je onnodig tegen rate limits aanloopt — zie [Hoe webhooks werken](/nl/how-webhooks-work)
* **Log fouten met context** — neem het endpoint, de parameters en de timestamp op voor debugging

## FAQ

<AccordionGroup>
  <Accordion title="Hoe onderscheid ik een 402 op enkelvoudige versus bulk-endpoints?">
    Op enkelvoudige endpoints (email/phone find single, verify single) retourneert een `402` `{ "reason": "Insufficient credits", "success": false }`. Op bulk-endpoints retourneert dezelfde `402` de standaardvorm `{ "message": "..." }`. Door zowel `message` als `reason` te lezen (zoals de codevoorbeelden doen) handel je beide gevallen af.
  </Accordion>

  <Accordion title="Welke fouten moet ik automatisch opnieuw proberen?">
    Probeer `429`-fouten (rate limit) en `5xx`-fouten (server) opnieuw met exponentiële backoff. Probeer andere `4xx`-fouten zoals `400`, `401` of `402` niet opnieuw — die wijzen op een probleem met het verzoek, de API-sleutel of het kredietsaldo dat alleen opnieuw proberen niet oplost.
  </Accordion>

  <Accordion title="Is er een retry_after-header die aangeeft hoe lang ik moet wachten?">
    Nee. Foutresponses bevatten nooit de velden `retry_after`, `error` of `status`. Gebruik je eigen exponentiële backoff tussen pogingen. Zie [Rate limits](/nl/rate-limits) voor de limieten die op jouw plan van toepassing zijn.
  </Accordion>

  <Accordion title="Waar lees ik de foutmelding in de respons?">
    Voor de meeste fouten staat de beschrijving in het `message`-veld. Voor een `402` wegens onvoldoende krediet op een enkelvoudig endpoint staat deze in plaats daarvan in het `reason`-veld. Vertak je logica altijd op de HTTP-statuscode in plaats van de tekst van de melding te parseren.
  </Accordion>
</AccordionGroup>

## Volgende stappen

<CardGroup cols={2}>
  <Card title="Statuscodes" icon="list-check" href="/nl/status-codes">
    De volledige lijst met HTTP-statuscodes en hun betekenis.
  </Card>

  <Card title="Rate limits" icon="gauge-high" href="/nl/rate-limits">
    Begrijp de verzoeklimieten per plan om 429-fouten te voorkomen.
  </Card>

  <Card title="Authenticatie" icon="key" href="/nl/authentication">
    Hoe je je API-sleutel meegeeft in de x-api-key-header.
  </Card>

  <Card title="Credits en facturatie" icon="coins" href="/nl/credits-billing">
    Bekijk hoe credits voor elk endpoint worden verbruikt.
  </Card>
</CardGroup>
