# Errors

Every Publisher API error comes in the same format: `application/problem+json` per RFC 9457.

```json
{
  "type": "https://docs.kalender-sync.de/en/api/errors/invalid_request",
  "title": "The request is invalid",
  "status": 400,
  "code": "invalid_request",
  "request_id": "req_…",
  "errors": [
    { "field": "end", "code": "end_before_start", "message": "end must not be before start." }
  ]
}
```

| Field | Meaning |
|---|---|
| `type` | Link to the explanation of the error in these docs. |
| `title` | Short description of the HTTP status. |
| `status` | HTTP status, as in the response. |
| `code` | **Stable, machine-readable error code.** Branch on this, not on `title` or `detail`. |
| `detail` | Optional: explanation for humans, may change. |
| `request_id` | Unique id of the request. Quote it when you contact support. |
| `errors` | Only with `invalid_request`: every field error with `field`, `code` and `message`. |

New error codes may be added. Handle unknown codes by their HTTP status: `4xx` means "fix the request", `429` and `5xx` mean "retry later".

## All error codes

| Code | Status | Meaning |
|---|---|---|
| [`missing_api_key`](https://docs.kalender-sync.de/en/api/errors/missing_api_key/) | 401 | No API key in the request. |
| [`invalid_api_key`](https://docs.kalender-sync.de/en/api/errors/invalid_api_key/) | 401 | The API key is invalid, revoked or expired. |
| [`insufficient_scope`](https://docs.kalender-sync.de/en/api/errors/insufficient_scope/) | 403 | The key lacks the required permission. |
| [`plan_required`](https://docs.kalender-sync.de/en/api/errors/plan_required/) | 403 | Your plan does not cover this live calendar. |
| [`calendar_blocked`](https://docs.kalender-sync.de/en/api/errors/calendar_blocked/) | 403 | We blocked this calendar. |
| [`terms_required`](https://docs.kalender-sync.de/en/api/errors/terms_required/) | 403 | Live calendars need your consent to the additional terms. |
| [`invalid_request`](https://docs.kalender-sync.de/en/api/errors/invalid_request/) | 400 | The request is invalid. |
| [`invalid_external_id`](https://docs.kalender-sync.de/en/api/errors/invalid_external_id/) | 400 | The external_id of a batch operation is invalid. |
| [`invalid_cursor`](https://docs.kalender-sync.de/en/api/errors/invalid_cursor/) | 400 | The pagination cursor is invalid. |
| [`invalid_idempotency_key`](https://docs.kalender-sync.de/en/api/errors/invalid_idempotency_key/) | 400 | The Idempotency-Key is too long. |
| [`idempotency_key_reused`](https://docs.kalender-sync.de/en/api/errors/idempotency_key_reused/) | 409 | The Idempotency-Key was used for a different request. |
| [`idempotency_in_progress`](https://docs.kalender-sync.de/en/api/errors/idempotency_in_progress/) | 409 | The first request with this Idempotency-Key is still running. |
| [`not_found`](https://docs.kalender-sync.de/en/api/errors/not_found/) | 404 | This endpoint does not exist. |
| [`calendar_not_found`](https://docs.kalender-sync.de/en/api/errors/calendar_not_found/) | 404 | No calendar with this id for this key. |
| [`event_not_found`](https://docs.kalender-sync.de/en/api/errors/event_not_found/) | 404 | No event with this external_id in this calendar. |
| [`sync_not_found`](https://docs.kalender-sync.de/en/api/errors/sync_not_found/) | 404 | No full sync with this id for this calendar. |
| [`sync_expired`](https://docs.kalender-sync.de/en/api/errors/sync_expired/) | 409 | The full sync has expired. |
| [`sync_completed`](https://docs.kalender-sync.de/en/api/errors/sync_completed/) | 409 | The full sync is already complete. |
| [`calendar_limit_reached`](https://docs.kalender-sync.de/en/api/errors/calendar_limit_reached/) | 409 | The account already has as many calendars as allowed. |
| [`event_limit_reached`](https://docs.kalender-sync.de/en/api/errors/event_limit_reached/) | 409 | The calendar holds the maximum number of events. |
| [`sequence_mismatch`](https://docs.kalender-sync.de/en/api/errors/sequence_mismatch/) | 409 | The event changed since the sequence you sent. |
| [`large_delete`](https://docs.kalender-sync.de/en/api/errors/large_delete/) | 409 | The full sync would delete more than half of the events. |
| [`invalid_image`](https://docs.kalender-sync.de/en/api/errors/invalid_image/) | 400 | No image in the request body. |
| [`image_too_large`](https://docs.kalender-sync.de/en/api/errors/image_too_large/) | 413 | The image is too large. |
| [`unsupported_image_type`](https://docs.kalender-sync.de/en/api/errors/unsupported_image_type/) | 415 | The image is not PNG, JPEG or WebP. |
| [`payload_too_large`](https://docs.kalender-sync.de/en/api/errors/payload_too_large/) | 413 | The request body is too large. |
| [`unsupported_media_type`](https://docs.kalender-sync.de/en/api/errors/unsupported_media_type/) | 415 | This endpoint does not accept the Content-Type. |
| [`rate_limited`](https://docs.kalender-sync.de/en/api/errors/rate_limited/) | 429 | Too many requests. |
| [`internal_error`](https://docs.kalender-sync.de/en/api/errors/internal_error/) | 500 | Unexpected error on our side. |

Field errors inside `invalid_request` (for example `invalid_timezone` or `unsupported_rrule`) are listed under [Events: validation errors](https://docs.kalender-sync.de/en/api/events/#validation-errors).