Rate Limits and Quotas

Bokio enforces request-rate limits, failed-request and monthly quotas, and concurrent-write limits for each integration.

📘

Production limits

  • Send at most 200 requests in a rolling 60-second window per bearer token.
  • Private integrations can send up to 5,000 requests per company each month.
  • Send only one concurrent write for the same HTTP method and URL path.

Error response contract

Error responses include a machine-readable code, a human-readable message, and bokioErrorId (a unique UUID for support and log correlation). Branch on code; never use bokioErrorId for application logic.

ConditionStatuscodeRetry guidance
Short/standard rate limit429rate-limit-exceededWait for Bokio-RateLimit-RetryAfter.
Daily failed-request quota403quota-exceededWait for Retry-After.
Monthly company quota403quota-exceededWait for Retry-After.
Concurrent write429concurrency-limit-exceededSerialize writes; retry after the active request completes.

Rate limits

The API returns these headers for rate-limit state:

  • Bokio-RateLimit-Limit: The maximum number of requests in the applicable rate-limit window.
  • Bokio-RateLimit-Remaining: The number of requests remaining in the applicable rate-limit window.
  • Bokio-RateLimit-RetryAfter: The retry delay, in seconds, returned with a rate-limit response.

Handle rate-limit responses

When you exceed either request-rate limit, the API returns 429 Too Many Requests. Monitor Bokio-RateLimit-Remaining and wait for the interval in Bokio-RateLimit-RetryAfter before retrying.

{
  "code": "rate-limit-exceeded",
  "message": "The API rate limit has been reached. Please retry after the interval specified by the Bokio-RateLimit-RetryAfter header. For more information see https://docs.bokio.se/reference/rate-limits",
  "bokioErrorId": "9b408943-7a1e-47ac-85a7-ac52b2c210d3"
}

Monthly quota for private integrations

Private integrations can make up to 5,000 API requests per company each month. When a company reaches its monthly quota, the API returns 403 Forbidden.

Wait for the interval in the standard Retry-After header before retrying. For information about integration types, see Public vs Private Integrations.

{
  "code": "quota-exceeded",
  "message": "The monthly API request quota for this company has been reached. Please retry after the interval specified by the Retry-After header. For more information see https://docs.bokio.se/reference/rate-limits",
  "bokioErrorId": "9b408943-7a1e-47ac-85a7-ac52b2c210d3"
}

Concurrency limits

Concurrency limits restrict writes processed at the same time. The API permits one concurrent write for the same HTTP method and URL path.

When another write is active for that HTTP method and URL path, the API returns 429 Too Many Requests. No retry-delay header applies. Serialize writes and retry only after the active request completes.

{
  "code": "concurrency-limit-exceeded",
  "message": "Concurrency limit exceeded.",
  "bokioErrorId": "9b408943-7a1e-47ac-85a7-ac52b2c210d3"
}

Serialize writes

Do not send writes for the same HTTP method and URL path in parallel. For example, do not use Promise.all() for multiple requests to the same write path. Wait for each active request to complete before sending the next request.

Bad (parallel):

await Promise.all([req1, req2, req3, req4, req5]);

Good (sequential):

for (const req of requests) {
  await sendRequest(req);
}