---
title: "Errors"
description: "Every error answer is application/problem+json following RFC 9457. The code is the contract, type points at its page in this portal."
lang: en
url: https://developers.bodo-app.com/en/guides/errors/
apiVersion: 2026-11-01
---

# Errors

Every error answer is application/problem+json following RFC 9457. The code is the contract, type points at its page in this portal.

## Anatomy of an error answer

Branch on `code` in your client, never on the text. Quote the `requestId` in support requests.

**POST /v1/contacts**

```http
HTTP/1.1 422 Unprocessable Content
Content-Type: application/problem+json
Content-Language: en
Request-Id: req_01JBA7Q2M4X9C3T8V5N6K1W0PZ

{
  "type": "https://developers.bodo-app.com/problems/VALIDATION_FAILED",
  "title": "Validation failed",
  "status": 422,
  "detail": "A field has an invalid value.",
  "instance": "/v1/contacts",
  "code": "VALIDATION_FAILED",
  "requestId": "req_01JBA7Q2M4X9C3T8V5N6K1W0PZ",
  "errors": [
    {
      "field": "email",
      "code": "INVALID_FORMAT",
      "message": "Not a valid email address."
    }
  ]
}
```

`title` and `detail` come in German and English, following `Accept-Language`. More under [Language](/en/guides/language/).

## Codes

Every answer carries `Request-Id` in the header and `requestId` in the body, for 401, 429 and 500 too.

| Situation | Status · code |
| --- | --- |
| Input | [400 INVALID_REQUEST](/en/problems/INVALID_REQUEST/) · [422 VALIDATION_FAILED](/en/problems/VALIDATION_FAILED/) |
| Key invalid, expired, revoked, paused, IP not allowed, API of the organization off | [401 UNAUTHENTICATED](/en/problems/UNAUTHENTICATED/) |
| Permission or scope missing, organization closed or scheduled for deletion | [403 FORBIDDEN](/en/problems/FORBIDDEN/) |
| Organization header does not match the key | [403 ORGANIZATION_MISMATCH](/en/problems/ORGANIZATION_MISMATCH/) |
| Public API module not enabled for the organization, for OAuth tokens too | [403 API_MODULE_DISABLED](/en/problems/API_MODULE_DISABLED/) |
| Family blocked, such as deleting, finalizing or sending an invoice | [403 RISK_FAMILY_BLOCKED](/en/problems/RISK_FAMILY_BLOCKED/) |
| Object invisible or unknown | [404 NOT_FOUND](/en/problems/NOT_FOUND/) |
| Operation not in the version or without the preview header | [404 OPERATION_NOT_IN_VERSION](/en/problems/OPERATION_NOT_IN_VERSION/) |
| Idempotency | [409 IDEMPOTENCY_IN_PROGRESS](/en/problems/IDEMPOTENCY_IN_PROGRESS/) · [422 IDEMPOTENCY_PAYLOAD_MISMATCH](/en/problems/IDEMPOTENCY_PAYLOAD_MISMATCH/) |
| Version switched off | [410 VERSION_SUNSET](/en/problems/VERSION_SUNSET/) |
| Precondition | [412 PRECONDITION_FAILED](/en/problems/PRECONDITION_FAILED/) · [428 PRECONDITION_REQUIRED](/en/problems/PRECONDITION_REQUIRED/) |
| Lists and parameters | [400 CURSOR_MISMATCH](/en/problems/CURSOR_MISMATCH/) · [400 UNKNOWN_PARAMETER](/en/problems/UNKNOWN_PARAMETER/) |
| Files | [409 UPLOAD_INCOMPLETE](/en/problems/UPLOAD_INCOMPLETE/) · [422 UPLOAD_CHECKSUM_MISMATCH](/en/problems/UPLOAD_CHECKSUM_MISMATCH/) · [422 UPLOAD_REJECTED](/en/problems/UPLOAD_REJECTED/) |
| Batch | [400 BATCH_TOO_LARGE](/en/problems/BATCH_TOO_LARGE/) · [422 BATCH_FAMILY_NOT_ALLOWED](/en/problems/BATCH_FAMILY_NOT_ALLOWED/) |
| Webhooks | [422 WEBHOOK_URL_INVALID](/en/problems/WEBHOOK_URL_INVALID/) · [409 WEBHOOK_ENDPOINT_LIMIT_REACHED](/en/problems/WEBHOOK_ENDPOINT_LIMIT_REACHED/) |
| Throttling | [429 RATE_LIMITED](/en/problems/RATE_LIMITED/) · [429 OVERLOADED](/en/problems/OVERLOADED/) · [429 QUOTA_EXHAUSTED](/en/problems/QUOTA_EXHAUSTED/) |
| API paused by the operator (emergency stop) | [503 API_PAUSED](/en/problems/API_PAUSED/) |
| Service behind | [502 UPSTREAM](/en/problems/UPSTREAM/) · [503 INSTANCE_PENDING](/en/problems/INSTANCE_PENDING/) · [500 INTERNAL](/en/problems/INTERNAL/) |

Every credential reason gives the same 401 without `detail`. The owner sees the exact reason in the request log in Bodo. All codes with their pages: [Problem types](/en/problems/).

## 403 API_MODULE_DISABLED during the preview

The door checks the module publicApi of the organization first, then the API level the organization chooses itself.

Answer by module publicApi and API level of the organization

| Module publicApi | API level of the organization: off | API level of the organization: read | API level of the organization: on |
| --- | --- | --- | --- |
| off | 403 `API_MODULE_DISABLED`, module first, level does not matter | 403 `API_MODULE_DISABLED`, module first, level does not matter | 403 `API_MODULE_DISABLED`, module first, level does not matter |
| on | 401 `UNAUTHENTICATED`, like any invalid key | 403 `FORBIDDEN`, only for writes, reads go through | 2xx, call goes through |

While the module is off, keys, subscriptions and tokens rest. Nothing is deleted, and everything continues once it is switched on again. Events from the time it was off are not delivered later; syncing with `updatedSince` still works.

## Answer in German

**Example response**

```http
GET /v1/contacts

HTTP/1.1 403 Forbidden
Content-Type: application/problem+json
Content-Language: de

{
  "type": "https://developers.bodo-app.com/problems/API_MODULE_DISABLED",
  "title": "Öffentliche API nicht freigeschaltet",
  "status": 403,
  "detail": "Für diese Organisation ist das Modul Öffentliche API nicht freigeschaltet. Dein Bodo-Ansprechpartner schaltet es frei.",
  "code": "API_MODULE_DISABLED",
  "requestId": "req_01JBF2K8N3Q7R5T9V1X4Z6B0CD"
}
```

## Answer in English

**Example response**

```http
GET /v1/contacts · Accept-Language: en

HTTP/1.1 403 Forbidden
Content-Type: application/problem+json
Content-Language: en

{
  "type": "https://developers.bodo-app.com/problems/API_MODULE_DISABLED",
  "title": "Public API not enabled",
  "status": 403,
  "detail": "The Public API module is not enabled for this organization. Your Bodo contact can enable it.",
  "code": "API_MODULE_DISABLED",
  "requestId": "req_01JBG3L9P4R8S6U0W2Y5A7C1DE"
}
```
