Rate limits
Limits apply per connected company, and depend on your plan. A company connected to your app is one bucket, and two companies never share one. Over a limit, the API answers 429 with a Retry-After header.
Limits by plan
| Plan | Requests per company per hour | Requests per company per minute | Connected companies | Webhooks |
|---|---|---|---|---|
| Connect | 300 | 30 | 10 | No |
| Partner | 1,000 | 100 | 250, then 3 kr each per month, ex VAT | Yes |
| Platform | 5,000 | 300 | Unlimited | Yes |
The per-minute figure is a burst limit: the most requests one company can send in a single minute, even when the hour has room left. Use webhooks instead of polling to stay under the limit.
Sandbox apps and an organisation's own API keys have no plan and are limited to 60 requests per minute and 300 per hour.
Write limits
Writes change a company's data, so they have their own, lower limits on top of the ones above. Both apply.
| Counted | Per minute | Per hour |
|---|---|---|
| Per company, for one app | 10 | 120 |
| Per company, all apps together | 30 | 300 |
When you hit the limit
Wait the number of seconds in Retry-After, then try again. A read answers like this:
HTTP/1.1 429 Too Many Requests
Retry-After: <seconds>
RateLimit-Limit: <limit of the window>
RateLimit-Remaining: 0
RateLimit-Reset: <seconds>
{ "error": "Rate limit exceeded." }A write answers with the error code:
HTTP/1.1 429 Too Many Requests
Retry-After: <seconds>
{ "error": "rate_limited", "error_description": "Too many write requests. Retry after the time in Retry-After." }Response headers
Every read response, success and 429 alike, carries three headers so you can back off before hitting the limit. They describe whichever of the minute and hour limits is closer:
RateLimit-Limit— the limit for that window.RateLimit-Remaining— requests left in that window.RateLimit-Reset— seconds until the window resets.
Token lifetime
Access tokens expire after 3,600 seconds. Use the refresh token to get a new one.