Limits
How many requests you can make.
Requests per minute
Each endpoint allows a fixed number of requests per minute. For the data endpoints and for reading the account, all keys and tokens of an account count together. Every request counts, even a rejected one.
| Endpoint | What | Limit per minute |
|---|---|---|
| fetch-organization | Company profile | 60 |
| fetch-person | Person profile | 60 |
| search-organizations | Search & Export | 60 |
| fetch-document | Documents | 5 |
| signals | Signals | 60 |
| account | Read the account | 30 |
| account, auth/tokens | Manage bearer tokens; create, update and delete keys, monitors and webhook endpoints | 10 |
| account/webhook-endpoints | Verify and test a webhook endpoint, rotate the secret | 6 |
Search, documents and Signals share a quota of 60 requests per minute. Documents also have their own, smaller limit.
Write requests to the account, Monitoring and webhooks also count toward the account limit. The same numbers are listed under “Costs and limits” on every endpoint page.
The limits are the same in every credit subscription. If you need more requests per minute, an Enterprise contract can give you higher limits.
Limit reached
Over the limit, the API answers with 429. The header Retry-After tells you after how many seconds you can send requests again. The same number is in the field retry_after.
Every response shows in headers how much room you have left:
| Header | Meaning | Example |
|---|---|---|
| X-RateLimit-Limit | This endpoint's limit per minute. |
30 |
| X-RateLimit-Remaining | How many more requests are possible in this minute. |
0 |
| Retry-After |
Only with 429: seconds until the next possible request.
|
17 |
| X-RateLimit-Reset |
Only with 429: the time when you can continue, as Unix time.
|
1793519682 |
1{2 "error": "Too many requests",3 "message": "Rate limit exceeded. Retry after 17 seconds.",4 "retry_after": 175}
When you send many requests, watch X-RateLimit-Remaining and slow down yourself before the API answers with 429. A request over the limit costs nothing.
Timeouts
Most responses arrive within a few seconds. AI Mode, the feature news, realtime fetches, fetch-person and documents take longer, because we fetch documents and realtime data directly from the register.
Set your client's timeout to at least 120 seconds, especially for Realtime, fetch-person and documents. A timeout that is too short aborts requests that are just about to finish.
For documents there is also async=true: the API answers right away with 202 and fetches the document in the background, see fetch-document.
408, for documents 504 with Retry-After. Nothing is billed. Retry the request a little later. If only the live fetch for Realtime fails, you get the company profile with the stored data, without the Realtime surcharge.
Retry without double charging
If your client aborts a request, it can still finish on our side and be billed. With the header Idempotency-Key, the retry then costs nothing.
Choose a separate key for each request and send it unchanged with the retry. A key has 1 to 128 characters: letters, digits, period, underscore, colon and hyphen, starting with a letter or a digit.
curl -G "https://handelsregister.ai/api/v1/fetch-organization" \ -H "x-api-key: YOUR_API_KEY" \ -H "Idempotency-Key: hetzner-profile-2026-11-01" \ --data-urlencode "q=Ansbach HRB 6089"
| Case | Data endpoints | Monitoring and webhooks |
|---|---|---|
| Key required | no, optional |
yes, otherwise 428
|
| Window | 24 hours | 24 hours |
| Same key, same parameters | Result again, without billing | Stored response with its status |
| Same key, different parameters |
422 idempotency_key_reused |
409 idempotency_conflict |
| After an error | Key stays free | The same error comes back, new key needed |
Data endpoints
fetch-organization, fetch-person, search-organizations and fetch-document accept the key as an option. If you repeat a request with the same key and the same parameters within 24 hours, you get the result again, without billing.
The first response carries the header Idempotency-Status: created, each retry Idempotency-Status: replayed and meta.request_credit_cost: 0. A retry needs no balance.
Only a delivered result binds the key. So after an error you can keep using the same key. The same key with different parameters gives 422 with idempotency_key_reused. The data endpoints ignore a key in a different format, so stick exactly to the format.
signals does not accept an idempotency key.
1{2 "error": "idempotency_key_reused",3 "message": "This Idempotency-Key was already used with different parameters.",4 "meta": {5 "request_credit_cost": 0,6 "credits_remaining": 1457 }8}
Monitoring and webhooks
Write requests to /v1/account/monitors, /v1/account/webhook-endpoints and /v1/account/webhook-deliveries need the key. Without it, the API answers with 428; a key in the wrong format gives 400.
Within 24 hours, the same key with the same parameters returns the stored response with its status, plus Idempotency-Status: replayed. This also applies to errors. For a new attempt, such as verifying again, you therefore use a new key.
The same key with different parameters gives 409 with idempotency_conflict. If the first request is still running, you get 409 with idempotency_in_progress.
Plan your retries
Not every error is worth a second attempt. Here is how to proceed:
- Retry:
408,429afterRetry-Afterand5xx. Wait longer between attempts each time, for example 2, 4 and 8 seconds, and stop after a few attempts. - Fix first, then resend:
400,401,402,403,404and422. Sending the same request again brings the same result. - Send an idempotency key with paid requests. Then a retry after an abort costs nothing.