Skip to content

Rate limits, quotas and headers

Limit What it counts When exceeded
Rate (burst) requests per second per key (Hobby 1, Starter 5, Growth 15, Custom by contract) 429 rate_limited
Quota billable units in the billing period (Hobby 100 a month and at most 20 a day, Starter 2,500, Growth 10,000) 429 quota_exceeded (hard limit), or overage if you enabled it
Natural persons per day distinct natural persons (s.p.) returned to your organisation in a day (Hobby 20, Starter 200, Growth 1,000, Custom by contract) 429 natural_person_cap_exceeded

Every 429 carries a Retry-After header in seconds. The API tester in the dashboard uses no units and has its own limit: about 20 requests per minute per user and per organisation. The daily natural-person cap applies to it as well.

We use the IETF draft draft-ietf-httpapi-ratelimit-headers-11 plus the classic headers:

RateLimit-Policy: "burst";q=15;w=1, "monthly";q=10000;w=2592000
RateLimit: "burst";r=12;t=1, "monthly";r=8123;t=1209600
X-RateLimit-Limit: 15
X-RateLimit-Remaining: 12
X-RateLimit-Reset: 1792396800
X-Quota-Limit: 10000
X-Quota-Remaining: 8123
X-Quota-Reset: 1793606400
X-Quota-Warning: 80
  • X-RateLimit-Reset and X-Quota-Reset are Unix times in seconds.
  • X-Quota-Warning (80 or 100) appears once you cross the threshold. You also get the warnings by email.
async function call(url, init, tries = 4) {
for (let i = 0; ; i++) {
const r = await fetch(url, init);
if (r.status !== 429 && r.status < 500) return r;
if (i === tries - 1) return r;
const wait = Number(r.headers.get('Retry-After') ?? 2 ** i) * 1000;
await new Promise((s) => setTimeout(s, wait + Math.random() * 250));
}
}
  • ETag is a hash of the content and the data version. With If-None-Match you get 304 Not Modified, which is free.
  • Last-Modified is the FURS source date.
  • Responses to keyed requests carry Cache-Control: private, max-age=300.

The data changes at most once a day, so you can safely cache it until the next refresh (X-Data-As-Of). For natural persons the maximum is 30 days (Terms of use, in Slovenian).

GET /v1/usage returns the usage in the current period for the key and the organisation (0 units). A breakdown by day and endpoint is in the dashboard.

Source: FURS · unofficial source, not an official extract · Terms · Privacy · maticna.si