registercheckby openlaw group
Get started

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

StatuscodeMeaningWhat to do
301company_mergedThe company was merged into another.Follow merged_into.
400invalid_requestThe body cannot be parsed at all: it is not JSON, or not a JSON object.Fix the body.
400validation_failedA 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.
401unauthorizedNo valid API key: it is wrong, revoked, disabled or expired.Check the Authorization: Bearer header and the key.
402insufficient_creditsNot enough credits. The call did not run and was not charged.Top up.
403forbiddenYour role in the workspace does not allow this action.Ask a workspace administrator.
403destination_requires_planWithout 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.
403monitor_limit_reachedYou 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.
404not_foundNo such resource, or not yours — the two are indistinguishable.Check the id.
409conflictIt 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.
409route_endpointThe 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.
409register_identity_ambiguousA register identity matched several companies. candidates lists them.Retry with the subject_id of the one you mean.
409idempotency_request_in_progressA request with this Idempotency-Key is still running.Retry when it has finished.
410endpoint_retiredA path that was renamed (see the migration guide) or that belongs to the retired /api surface. detail names its replacement.Call the replacement.
422idempotency_key_reusedThis Idempotency-Key was used with a different request.Use a new key.
422prompt_not_understoodPOST /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.
422filter_not_monitorablePOST /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.
422operation_not_allowedSearch 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.
422question_not_supportedPOST /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.
429rate_limitedToo 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.
500internal_errorSomething failed on our side. Nothing was charged.Retry with backoff.
503service_unavailableA 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.

On this page