Rate limits, quotas and headers
Three limits
Section titled “Three limits”| 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.
Headers
Section titled “Headers”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=2592000RateLimit: "burst";r=12;t=1, "monthly";r=8123;t=1209600X-RateLimit-Limit: 15X-RateLimit-Remaining: 12X-RateLimit-Reset: 1792396800X-Quota-Limit: 10000X-Quota-Remaining: 8123X-Quota-Reset: 1793606400X-Quota-Warning: 80X-RateLimit-ResetandX-Quota-Resetare Unix times in seconds.X-Quota-Warning(80or100) appears once you cross the threshold. You also get the warnings by email.
Retrying
Section titled “Retrying”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)); }}Caching and 304
Section titled “Caching and 304”ETagis a hash of the content and the data version. WithIf-None-Matchyou get304 Not Modified, which is free.Last-Modifiedis 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