Errors
The problem document every error returns, every code, and how to retry safely.
Every error is an RFC 9457 problem document, sent as
application/problem+json. Branch on code — it is stable. title and detail are for people.
{
"type": "https://docs.registercheck.de/errors/validation_failed",
"title": "Validation failed",
"status": 400,
"detail": "1 field failed validation.",
"code": "validation_failed",
"request_id": "9b0c2f5e-4d1a-4c3e-9a8e-6f0b1d2c3e4f",
"errors": [
{
"location": "path",
"name": "company_id",
"detail": "is a person id (per_…); this takes a company id (cmp_…)"
}
]
}A 400 validation_failed lists every field that failed in errors: where it was
(location: path, query, header or body), its name, and what is wrong with it. Quote
request_id (also sent as the Request-Id header) when you contact support.
Any call can answer 400, 401, 429, 500 and 503, and a call with an id in its path can
answer 404. Each operation's page in the reference lists which of 402, 403, 409 and
410 it can answer as well.
Codes
| Status | code | Meaning | What to do |
|---|---|---|---|
301 | company_merged | The company was merged into another. | Follow merged_into. |
400 | invalid_request | The body cannot be parsed at all: it is not JSON, or not a JSON object. | Fix the body. |
400 | validation_failed | A field failed validation: a path, query, header or body field, a cursor, or an id of the wrong kind (a person id where a company id belongs). errors names each one. | Fix the fields errors names. |
401 | unauthorized | No valid API key: it is wrong, revoked, disabled or expired. | Check the Authorization: Bearer header and the key. |
402 | insufficient_credits | Not enough credits. The call did not run and was not charged. | Top up. |
403 | forbidden | Your role in the workspace does not allow this action. | Ask a workspace administrator. |
403 | destination_requires_plan | Without a plan, notifications can only go to your own verified sign-in address. | Use that address, or choose a plan for more addresses and webhooks. |
403 | monitor_limit_reached | You already monitor as many companies as the plan allows (limit; the free plan's when the workspace has none). Resuming a monitor created in the dashboard (PATCH /monitors/{monitor_id} with "status": "active") changed nothing, and it stays paused. | Stop a monitor with DELETE /monitors/{monitor_id}, or pause one, or choose a plan. |
404 | not_found | No such resource, or not yours — the two are indistinguishable. | Check the id. |
409 | conflict | It already exists. existing_id names the existing resource, or is null when it cannot be named (two requests raced). | Use or change the existing one; list to find it when existing_id is null. |
409 | route_endpoint | The destination is a monitor's delivery route: it is told at the monitor's check, always instant. | Change the monitor's check speed, or add your own destination for this address. |
409 | register_identity_ambiguous | A register identity matched several companies. candidates lists them. | Retry with the subject_id of the one you mean. |
409 | idempotency_request_in_progress | A request with this Idempotency-Key is still running. | Retry when it has finished. |
410 | endpoint_retired | A path that was renamed (see the migration guide) or that belongs to the retired /api surface. detail names its replacement. | Call the replacement. |
422 | idempotency_key_reused | This Idempotency-Key was used with a different request. | Use a new key. |
422 | prompt_not_understood | POST /companies/find: the prompt and filters together name no criterion this search can filter on. Nothing was charged. | Say what to look for: an industry, a federal state, a city, a legal form, founding years, capital, or the board's age. |
422 | filter_not_monitorable | POST /monitors with prompt or filter: the subject names criteria a search cannot hold, or event types a search cannot watch. detail names each one. Nothing was created and nothing was charged. | Take the criteria it names out, or name what a search watches: an industry section, a federal state, a city, a legal form, capital; new companies or changes by their event types. |
422 | operation_not_allowed | Search monitors are not served for this workspace yet: they arrive with the API Playground, and the workspace's saved searches must be switched on. Nothing was created or changed and nothing was charged. | Wait for the workspace's switch-on; monitor one company (subject_id or register) in the meantime. |
422 | question_not_supported | POST /answers: the question asks for none of the six kinds of answer (representation, beneficial owners, representatives, shareholders, seat, status), or it names no company. detail says which, in German. Nothing was charged. | Ask about one of the six, and name the company by its name or its register number. |
429 | rate_limited | Too many requests for this key, or its monthly request allowance is used up. The key is still valid. | Wait the Retry-After seconds it gives, not less. For a used-up allowance that can be days. Without Retry-After the key does not refill: use another key. |
500 | internal_error | Something failed on our side. Nothing was charged. | Retry with backoff. |
503 | service_unavailable | A dependency is unavailable, including the API key check (the key was not rejected). | Retry with backoff; do not rotate the key. |
Retrying
Retry 500 and 503 with exponential backoff and jitter. A 429 says when to come back in
Retry-After: wait that long, not less — a request made before then is refused again and still
counts against your account's shared allowance. A 429 without Retry-After comes from a key
issued with a fixed number of requests and no refill: it will not succeed again. Do not retry 400, 401, 402, 403, 404
or 422 unchanged — they will not succeed on a second attempt.
Retry writes with an Idempotency-Key
A timeout does not mean a write failed; it may have landed. Send an Idempotency-Key header —
a random UUID per logical request — on every POST, and reuse it on the retry:
curl -X POST https://api.registercheck.de/v1/monitors \
-H "Authorization: Bearer $RC_KEY" \
-H "Idempotency-Key: 6f1c9f3a-8e5b-4c6d-9a2e-1b3c4d5e6f70" \
-H "Content-Type: application/json" \
-d '{"subject_id": "cmp_01h455vb4pex5vsknk084sn02q"}'Within 24 hours, the same key with the same request answers the first response with
Idempotent-Replayed: true — nothing is created or charged a second time. The same key with a
different body answers 422 idempotency_key_reused; a retry while the first request is still
running answers 409 idempotency_request_in_progress.
Only a success (2xx) is stored. An error changed nothing and cost nothing, so a retry with the
same key runs again — after a top-up, a 402 retry goes through instead of replaying the 402.
Creating a webhook destination is never replayed, because its signing secret is not
stored a second time: a retry after a lost response answers 409 with existing_id.