Skip to content

Limits (rate limits)

The per-minute limits use a sliding window: the requests of the last 60 seconds are counted, not those since the full minute.

LimitValueWindow
Read requests per token120sliding, 1 minute
Write requests per token20sliding, 1 minute
All requests per organization600sliding, 1 minute
All requests per IP address300sliding, 1 minute
Failed sign-ins per IP address20sliding, 1 minute
New imports per token (POST /v1/tenant-imports)20sliding, 1 hour
New imports per account (creator of the token, all of its imports together; fixed)20sliding, 10 minutes
Open imports per organization (created via the API)50no window: until taken over or deleted
Imports in total per organization (file and API, including completed ones; fixed)500no window: completed imports are deleted after 30 days, open ones after 90 days
New DATEV exports per organization (POST /v1/datev/exports)301 hour
New prospect enquiries per token (POST /v1/prospects)301 hour
New prospect enquiries per token and email address524 hours
Webhooks per organization10—
Active tokens per organization25—
Entries per list pageat most 200—

Limits for imports

So that a misused token cannot block your organization's imports, POST /v1/tenant-imports has limits of its own:

LimitDefaultResponse when exceeded
Open imports per organization (created via the API)50422 import_limit_reached
New imports per token and hour20429 import_rate_limited
New imports per account (creator of the token) in 10 minutes; fixed, cannot be raised20429 rate_limited
Imports in total per organization (file and API, including completed ones; fixed)500422 import_total_limit_reached
Records per import500400 validation_error
Request size (import · takeover)1 MB · 64 KB413 payload_too_large

An import counts as open until all of its records have been taken over or deleted in the management app. The values that apply to your organization and the number of open imports are shown under Administration → API access; when a limit is exceeded, error.details states the limit and the current count (e.g. { "limit": 50, "open": 50 }). If you need more, contact support — the limits can be raised per organization. A retry with an Idempotency-Key that has already been used does not count as a new import. You release API imports you no longer need yourself: DELETE /v1/tenant-imports/{id} (see Cancel an import).

Quota headers

As soon as the token is known, all responses — including errors such as 400, 403, 404 or 409 — carry X-RateLimit-Limit (the token's limit per minute: read or write), X-RateLimit-Remaining (calls still available) and X-RateLimit-Reset (seconds until all calls counted so far have left the sliding window; at most 60). Without a known token they are absent: with 401, with an unknown address (route_not_found) and with 503 before the check. With 429 rate_limited, the Retry-After header states the waiting time in seconds until the next call is possible (also for the per-organization limit); X-RateLimit-Reset then has the same value. Wait at least that long and double the waiting time on repeated 429 or 503 responses.

429 in detail: special cases

Every 429 carries Retry-After (whole seconds, at least 1) — that is the binding wait. The number depends on the limit that was hit; for the special cases below X-RateLimit-Remaining says nothing about the cause, because it keeps counting the minute limit of the token.

Limit hitAnswerRetry-Aftererror.details
Minute limit per token or organization429 rate_limitedseconds until the next call is possible (at most 60)—
Overall limit or failed attempts per IP address429 rate_limitedas above; without quota headers (X-RateLimit-*) if the token had not been checked yet—
Webhook replay: 1000 deliveries per webhook and hour429 rate_limited1 to 3600: until there is room in the hourly quota again{ "limit": 1000, "retry_after": 1800 }
Test events: at most 3 waiting per webhook429 rate_limited60{ "limit": 3 }
New imports per token and hour429 import_rate_limited3600{ "limit": 20, "used": 20 }
Imports: 20 in 10 minutes per account429 rate_limited600—
Prospect submissions per token (hour, day per email address)429 rate_limitedwait until there is room again{ "limit": 30 }

Minute limit (most common case)

HTTP/1.1 429 Too Many Requests
Retry-After: 23
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 23
X-Request-Id: req_8c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f

{
  "success": false,
  "error": {
    "code": "rate_limited",
    "message": "<explanatory text in German>"
  },
  "request_id": "req_8c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f"
}

Replay limit of a webhook

HTTP/1.1 429 Too Many Requests
Retry-After: 1800
X-RateLimit-Limit: 20
X-RateLimit-Remaining: 17
X-RateLimit-Reset: 1800
X-Request-Id: req_8c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f

{
  "success": false,
  "error": {
    "code": "rate_limited",
    "message": "<explanatory text in German>",
    "details": {
      "limit": 1000,
      "retry_after": 1800
    }
  },
  "request_id": "req_8c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f"
}

What X-RateLimit-Reset means: on normal responses the seconds until all calls counted so far have left the sliding minute window (at most 60). On a 429 with Retry-After it carries the same value as Retry-After — for the hourly limits that is up to 3600, not only up to 60. Schedule your retry by Retry-After; repeat the request unchanged for replay and imports, writing calls with the same Idempotency-Key. A replay that fails on the hourly limit has queued nothing; do not let several processes restore at the same time.