ePostman docs
Console

Limits & quotas

Request limits per plan, the RateLimit and RateLimit-Policy headers, the 429 response, document size and idempotency.

5 min read
  • #rate limit
  • #quotas
  • #ratelimit-policy
  • #retry-after
  • #429
  • #idempotency
Document size
10 MB
Idempotency
24 h

Every organisation has a limit on how many requests it can send in a given time. The limit depends on your plan and applies separately to each group of endpoints. Every response tells you what your limit is and how much of it is left. Once you exceed it you get a 429 with the exact time after which you can try again.

What is counted

CallThe limit is counted per
Enterprise API (/api/v1/…) with an API key or a sessionthe whole organisation — all its API keys and users together
SAPI-SK (/sapi/document…)each SAPI client separately (X-Peppol-Participant-Id)
Unauthenticated calls (registration, the SAPI token endpoint)IP address

Endpoint groups

Expensive operations have their own counter and do not count towards the general limit — validating in a loop will not block you from sending invoices.

GroupEndpoints
apieverything in the Enterprise API that is not in another group (sending and reading invoices…)
validatePOST /api/v1/documents/validate — pre-flight validation
reachabilityGET /api/v1/participants/:id/reachability — receiver reachability
company-lookupGET /api/v1/invoicing/company/:ico — buyer details by company ID (IČO)
invoicing-channelGET /api/v1/invoicing/channel — delivery channel before issuing an invoice
sapiSAPI-SK /sapi/document…

Limits per plan

GroupMINISTARTPROCORPORATEENTERPRISE
api20 / s50 / s100 / s100 / s200 / s
sapi (per client)10 / s25 / s50 / s50 / s100 / s
validate10 / min30 / min60 / min150 / min300 / min
reachability30 / min30 / min60 / min60 / min120 / min
company-lookup30 / min30 / min30 / min30 / min30 / min
invoicing-channel30 / min30 / min60 / min60 / min120 / min

If a limit is too tight, get in touch — an individual one can be agreed. It shows up in the headers of your responses right away.

How the limit is consumed

The limit is not a window that resets all at once at the top of the minute. Capacity is refilled continuously — with validate at 60 per minute, one call frees up every second.

On top of that you have a burst: several calls you can send at once without waiting. On the PRO plan that is 10 validations at once, then one per second on average. An unused burst refills while you are idle.

  • evenly spread calls within the limit never hit it,
  • a short spike is absorbed by the burst,
  • sustained load above the limit ends in a 429.

Headers

RateLimit-Policy: "validate";q=60;w=60
RateLimit: "validate";r=9;t=1
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 9
X-RateLimit-Reset: 1790668801
HeaderMeaning
RateLimit-Policyyour limit: the group, quota q and window w in seconds — here 60 requests per 60 s
RateLimitthe current state: r calls that would pass right now, t seconds until the burst is full again
X-RateLimit-Limitsame as q
X-RateLimit-Remainingsame as r
X-RateLimit-Resetwhen the burst is full again, as a Unix timestamp in seconds

RateLimit and RateLimit-Policy follow the IETF draft RateLimit header fields for HTTP. X-RateLimit-* is sent for older clients — the content is the same, reading one pair is enough.

The headers are on every response to a request that passed authentication and input checks — successful or not. They are missing from a response with which authentication rejects the request (401, 403 for a suspended account) and from 400/413 raised by the request shape check: those are answered before the request is counted, and they do not count towards the limit.

Exceeding the limit

HTTP/1.1 429 Too Many Requests
Retry-After: 1
RateLimit-Policy: "validate";q=60;w=60
RateLimit: "validate";r=0;t=10
{
  "statusCode": 429,
  "error": "RATE_LIMIT_EXCEEDED",
  "code": "ERR-429",
  "message": "Too many requests. Retry after 1 seconds.",
  "retry_after": 1
}

Retry-After is the exact number of seconds until the next call frees up, not an estimate. The retry_after field carries the same value. Do not confuse it with t in the RateLimit header — that is the time until the whole burst is back (10 validations on the PRO plan in this example). On SAPI-SK the 429 uses the SAPI-SK envelope with code SAPI-TEMP-002 and retryable: true.

A rejected call is not processed — no invoice is sent and no credit is used. Retrying it is safe.

  1. On a 429, wait Retry-After seconds and retry. Do not retry immediately or in a tight loop.
  2. Watch RateLimit during batch processing — slow down as r approaches zero, before a 429 arrives.
  3. Parallel processes share one organisation limit. Split the capacity between them or send through a single queue.
  4. Derive your pace from RateLimit-Policy — q / w is the average calls per second.
  5. Do not use pre-flight validation for bulk checks. A sent invoice is validated anyway; pre-flight validation is for checking before you send.
async function callWithLimit(url, options, attempts = 5) {
  for (let i = 0; i < attempts; i++) {
    const res = await fetch(url, options);
    if (res.status !== 429) return res;
    const wait = Number(res.headers.get("Retry-After") ?? 1);
    await new Promise((r) => setTimeout(r, wait * 1000));
  }
  throw new Error("Rate limit still exceeded after retries");
}