---
title: "Errors and limits · EenFactuurMaken.nl"
description: "What EenFactuurMaken.nl REST API errors look like, all error codes per HTTP status, rate limits, plan limits and how to retry."
url: "https://eenfactuurmaken.nl/en/docs/api/errors"
markdown_url: "https://eenfactuurmaken.nl/en/docs/api/errors.md"
language: "en-GB"
---

# Errors and limits

What EenFactuurMaken.nl REST API errors look like, all error codes per HTTP status, rate limits, plan limits and how to retry.

## The error shape

Every error has the same shape:

```json
{
  "statusCode": 409,
  "statusMessage": "This invoice has been issued and can no longer be changed. Create a credit note to correct it.",
  "data": {
    "code": "invoice_locked",
    "message": "This invoice has been issued and can no longer be changed. Create a credit note to correct it.",
    "details": { "status": "issued" }
  }
}
```

- `data.code` is a stable snake\_case code. Use **that** in your code; the messages may change.
- `data.details` sometimes adds more information, like the fields for `validation_failed` or the check results for `invoice_not_compliant`.

### Validation errors

With `422 validation_failed`, `details` lists the field (`path`) and what's wrong for each problem:

```json
{
  "data": {
    "code": "validation_failed",
    "details": [
      { "path": ["lines", 0, "unitPriceCents"], "message": "Invalid input: expected number, received string" }
    ]
  }
}
```

### Invoice not compliant

With `422 invoice_not_compliant` (when issuing), `details` is a list of check results, each with `level` (`error`, `warning`, `info`), `field` and `code`. All codes and how to fix them are in [Invoice checks](https://eenfactuurmaken.nl/en/docs/invoices/checks).

## Error codes

| Status | Codes |
| --- | --- |
| 401 | `unauthenticated`, `invalid_api_key`, `invalid_token` |
| 402 | `plan_limit_reached` (monthly invoice limit, or 25 customers or products on Free), `plan_upgrade_required` (the feature is part of Pro) |
| 403 | `bad_origin`, `email_recipient_not_allowed`, `email_sending_paused`, `forbidden`, `insufficient_scope`, `session_not_fresh`, `session_required` |
| 404 | `not_found`, `link_invalid` |
| 409 | `invoice_locked`, `invoice_not_issued`, `invoice_cancelled`, `invoice_not_cancellable`, `invoice_has_credit_notes`, `invoice_not_creditable`, `invoice_fully_credited`, `credit_note_draft_exists`, `invoice_already_paid`, `invoice_not_paid`, `invoice_not_remindable`, `reminder_too_early`, `reminder_in_progress`, `number_taken`, `peppol_kvk_required`, `layout_limit_reached`, `layout_read_only`, `recurring_inactive`, `recurring_run_in_progress`, `email_domain_exists`, `email_domain_taken`, `email_domain_provider_conflict`, `already_subscribed`, `no_active_subscription`, `not_cancelled`, `subscription_ended` |
| 410 | `link_expired`, `public_link_expired` |
| 413 | `logo_too_large` (logo larger than 500 KB) |
| 415 | `logo_unsupported_type` (PNG and JPEG only) |
| 422 | `validation_failed`, `invoice_not_compliant`, `no_recipient`, `too_many_recipients`, `unknown_layout`, `recurring_template_invalid`, `email_domain_invalid`, `email_domain_public`, `exchange_rate_unknown_currency` |
| 429 | `rate_limited`, `email_daily_limit`, `email_rate_limited`, `invoice_resend_limit`, `email_platform_limit` |
| 502 | `email_send_failed` |
| 503 | `billing_unavailable`, `exchange_rate_unavailable` |

The most common ones:

| Code | What to do |
| --- | --- |
| `invoice_locked` | The invoice is finalised. Create a [credit note](https://eenfactuurmaken.nl/en/docs/credit-notes). |
| `invoice_not_compliant` | Fix the items with `level: "error"` and try again. |
| `number_taken` | The number you passed to `issue` already exists. Leave it out to get the next number. |
| `plan_limit_reached` | Wait until next month, delete an unused draft or upgrade to Pro. `details.limit` tells you which limit. |
| `email_recipient_not_allowed` | On Free you can only email the customer's address or your own. |
| `peppol_kvk_required` | Without a KvK number there's no UBL. See [PDF and e-invoice](https://eenfactuurmaken.nl/en/docs/invoices/pdf-and-ubl#no-ubl). |

## Rate limits

| Limit | Value |
| --- | --- |
| Per API key | 120 requests a minute (`429 rate_limited` with `Retry-After`) |
| Per IP address | 300 requests a minute |
| VIES check (`/vat-check`) | 20 a minute |
| Email | See [Sending by email](https://eenfactuurmaken.nl/en/docs/invoices/sending#limits) |
| Request size | 2 MB |

## Retrying

- **429**: wait the number of seconds in `Retry-After` (or a minute) and try again.
- **502 and 503**: temporary. Retry with an increasing delay (for example 2, 4 and 8 seconds).
- **4xx** (except 429): don't retry without changing something.
- Be careful retrying `POST /invoices`, `/send` and `/remind`: if the first request did succeed, you create or send it twice. Check with a `GET` first.

Last updated on 13 October 2026
