Quotas, errors, and recommended back-off
OpenRegistry surfaces three distinct kinds of failure with structured responses so AI agents can branch on them: rate limits (429), statutorily-restricted registers (501 by design), and upstream errors (5xx). Honour the structured retry hints — don't add ad-hoc exponential back-off on top.
Rate limits
Per-IP for anonymous, per-user for signed-in. The cross-border fan-out cap
is a separate counter that limits how many distinct jurisdictions a caller
can hit via search_companies in a rolling 60-second window.
When you exceed either limit, the response is HTTP 429:
{
"jsonrpc": "2.0",
"error": {
"code": -32000,
"message": "rate-limited",
"data": {
"reason": "rate-limited",
"retry_after_ms": 12400,
"scope": "ip" // or "user" or "fanout"
}
}
}
The HTTP layer also sets the standard Retry-After: 13 header
(seconds, rounded up). Honour retry_after_ms exactly —
exponential back-off on top is unnecessary; the limit window is fixed-rolling,
not adaptive. Fan-out cap (scope: "fanout") is a 60-second rolling
window — the second your oldest country falls off, you can hit a new one.
Pro tier caps at 10 distinct countries / 60s, Max at 30, Enterprise unlimited.
Statutorily restricted (CJEU C-37/20 and similar)
Some beneficial-ownership registers became access-restricted to AML-obliged
entities post-CJEU C-37/20
(DE, ES, IT, NL, LU, AT, MT, PT) and the Cayman Beneficial Ownership Transparency
Act 2023. We don't proxy these — the tool returns HTTP 501 with
structured guidance:
{
"jurisdiction": "DE",
"error": "not_proxied_by_design",
"reason": "CJEU-C-37-20",
"alternative_url": "https://www.transparenzregister.de",
"alternative_access": "AML-obliged entities only (banks, lawyers, notaries, etc.)",
"human_message": "The German Transparency Register is statutorily gated since 22 Nov 2022."
}
This is a design response, not a transient failure — retrying won't help.
The alternative_url is the canonical statutory portal where qualified
entities can register for access.
Upstream errors and tool-level structured 501s
When the upstream registry has its own outage, we surface its error verbatim with a structured wrapper:
{
"jurisdiction": "ES",
"error": "upstream_error",
"upstream_status": 524,
"human_message": "Spain BORME upstream timed out (Madrid bulletin renderer slow). Retry in 30-60s.",
"retry_after_ms": 45000
}
Some tools also return 501 with an alternative tool
suggestion when the upstream registry doesn't expose the requested concept
(e.g. CZ political parties don't have officers in the standard sense — call
search_specialised_records with source="rpsh" instead):
{
"error": "alternative_tool_required",
"alternative_tool": "search_specialised_records",
"alternative_args": { "jurisdiction": "CZ", "source": "rpsh", "...": "..." },
"human_message": "Czech political parties register is exposed via the RPSH sub-source."
}
Recommended client back-off
| Error | Action |
|---|---|
429 rate-limited | Sleep retry_after_ms, then retry once. |
429 fanout | Don't retry the same call; route the next request to a country you've already hit in the window. |
501 not_proxied_by_design | Don't retry. Surface alternative_url to the user. |
501 alternative_tool_required | Re-issue with alternative_tool + alternative_args. |
5xx upstream_error | Sleep retry_after_ms if present, else 30s. Max 3 retries. |
4xx not_found | Don't retry. Re-search with search_companies to discover a valid id. |
Reference back-off implementations are published in every framework integration guide under /docs/integrations.