🤖 This article was translated by AI.
Who is this article for?
For users and integrators who consume the Boond API from a script, connector, or third-party automation tool, and who want to optimize their number of calls — both to stay within the limits and to build a cleaner integration.
1. Rate limiting and quota
Your usage is governed by two independent mechanisms, which are cumulative:
Rate limiting smooths your throughput in the short term, per minute and per 10-second interval. If you go too fast, the API will temporarily respond with
429 Too Many Requests. The thresholds depend on the endpoint called. This mechanism is being rolled out and will apply from the end of September 2026: size your integration accordingly now.Quota caps your total number of calls per month; this monthly cap depends on your plan.
Threshold details are described in the dedicated article: Understanding API Call Limits.
A few clarifications on what is counted:
Only API calls are counted: your colleagues' navigation in the Boond interface does not count toward the quota.
A failed call is counted like any other — the counter increments at authentication, even before your request is processed. An integration that loops rejected calls will therefore waste its quota for nothing.
Calls from Apps developed by third parties (such as partners) do not consume your quota as long as the connection mode uses OAuth2 or JWTApp. If you share login/password information or your admin client key, their calls will be counted.
If you exceed your quota and the volume is not covered by your current plan, you can subscribe to additional API packs.
2. Reducing unnecessary calls
The first source of savings is simply the calls you don't make. And it's more valuable than it seems: each call replays the entire authentication sequence — token validation, instance resolution, account and rights loading, quota counting. Nothing is shared from one call to the next. So it's the number of calls, more than their content, that matters most.
Cache data that changes infrequently. Some data is not expected to change often: reference data, configuration, your instance structure. Retrieve it once, store it on your end, and refresh it at a reasonable frequency instead of every execution.
⚠️ Note: The API does not expose a revalidation mechanism — no ETag, no "nothing changed" response. Do not rely on the Last-Modified header either: it is returned with the response time, not the data's modification date — relying on it would make you think everything just changed, on every call. The last modification date is found in the response itself, on the record. Your cache should therefore be based on a fixed lifetime, or on webhooks (see §3).
One useful exception: the response for your instance parameters includes a version number that changes as soon as the configuration is modified. This is the only reliable signal to detect that a reference has changed without comparing everything.
Save static data. Historical data that no longer changes — old activity reports, closed invoices, completed projects — does not need to be re-extracted repeatedly. Save it once in your system, then only re-fetch recent or potentially changing periods.
Don't authenticate at every step. A common and costly reflex is to call a verification endpoint like current-user before every request. Authentication does not change during a process: a single check at the start of the session is enough.
Use a dedicated account for your integration if it runs in the backend. Running a flow on a collaborator's personal account poses two problems:
The flow inherits their perimeter: all records they are not allowed to see produce refused calls, which are counted and replayed each cycle.
If the collaborator changes roles or leaves the company, the integration does not stop — it continues with reduced data visibility, without any visible error.
A service account with an explicitly defined perimeter avoids both issues. If you use an integrated App or rely on the connected user's rights, a service account is not relevant and would bypass Boond's rights configuration.
Don't retry what was refused. An access denial is not a temporary incident: the record will remain inaccessible until rights change. Remember the refusal and stop requesting it each time. This is a frequent and costly mistake: tens of thousands of calls per month, all counted, for a known answer.
Fetch more data per call — but ask yourself the right question first. The number of results per page is adjustable, and leaving it at the default value mechanically increases your calls. Two caveats, however:
An out-of-bounds value is not raised to the maximum: it silently falls back to the default. Check the actual number of results returned rather than assuming your parameter was accepted.
Increasing the page size reduces the number of calls, not the request cost. For heavy collections, a very large page can be slower than several medium pages, possibly exceeding your timeout — and an interrupted call is still executed to the end and counted.
Above all, if you fetch a large volume only to extract a list of IDs and then call each record one by one, you should rethink the mechanism: you're paying twice. Consider what your process truly needs before adjusting page size.
Group calls rather than one per record. Sub-resources of a record are efficient for viewing one; used to browse all your records, they become the worst pattern — one call per entity, replayed each cycle. This is by far the biggest driver of high consumption. Whenever a search lets you fetch multiple known entities in one call, by listing their references, always prefer it — and apply this everywhere, not just where you first implemented it.
Avoid "just in case" calls. Every call should serve a real need. If you don't know if data has changed, target the change (see §3) rather than re-downloading everything just in case.
3. Synchronizing on changes
For data that changes, the rule is simple: only fetch what has changed since your last run. Several approaches, from simplest to most refined.
Limit your extractions to the useful window. An unbounded extraction — "everything, every time" — needlessly increases your usage. Always restrict to the window you actually need, filtering by date, period, or perimeter. An overly broad window not only increases volume: it overflows pages, and you end up paying for pagination of data you don't use. A significant portion of calls in a poorly bounded integration exist for this reason alone.
💡 Tip: To build any filtered call (extraction or activity log), apply the desired filter directly in the Boond interface, then open your browser's Network tab: you'll see the exact endpoint and parameters, ready to reproduce in your integration.
Switch to incremental. In practice: record the date of your last run and only process the delta — what was created or modified since. This often greatly reduces the call volume.
Consider the frequency. This is the most effective, yet often overlooked lever: before optimizing your calls, ask yourself how many times per day you really need to run them. Replaying a full cycle every hour on activity reports, absences, or projects — which don't change fourteen times a day — increases usage without benefit. Match the cadence to the freshness your use case needs, not what your scheduler allows.
⚠️ Attention: Not all data can be synchronized by delta. Times, absences, and activity reports do not offer a filter by modification date: in these collections, there is no "give me what has changed". The best practice is to strongly restrict the requested window — the current and previous week rather than the whole year — and supplement with the activity log to spot older changes.
Target precisely via the activity log. It lists creations, modifications, and deletions. When queried with filters, it tells you which records changed, and often which fields, over a given period — so you only need to re-fetch those, instead of everything.
Or switch to event-driven with webhooks. Subscribe to creation, update, and deletion events for the entities you care about: Boond notifies you in real time, instead of you polling in a loop.
⚠️ Attention: Webhook delivery is "best-effort" — short delay, no retry. If your data freshness relies solely on them, a missed event can create a lasting, silent gap. Plan a daily safety net: a catch-up pass on the activity log, or a delta resync on a rolling 24-48 hour window. This is also the only way to see deletions: a deleted record disappears from results without any signal, and a sync by modification date will never tell you.
4. Managing your throughput
Space out heavy extractions. Extraction, reporting, and export endpoints are among the most resource-intensive, with the strictest limits. Reserve them for scheduled and spaced-out processing — off-peak hours, chunking — rather than back-to-back series.
Request compression. API responses are compressed, but only if your client requests it, via the Accept-Encoding: gzip, deflate header. Without it, everything is sent uncompressed, several times larger. It's a line of configuration in your HTTP client, and one of the quickest wins — check that your library doesn't remove it.
Reporting cache is decided with your client. Reporting endpoints recalculate all their key indicators by default on every call: these are the most expensive in the API. They can serve a cached result, but it's not a simple request parameter: the option is set in the instance configuration, disabled by default, and its retention period — several days — is set by the client. Agree with them on activation and duration: the gain is significant, provided you accept the corresponding freshness.
Handle a 429 properly. It's not a blocking error, but a temporary signal:
Respect the
Retry-Afterheader: it tells you how many seconds to wait before retrying. Never retry immediately.Apply progressive back-off if no other signal — 1s, 2s, 4s, with some randomness — to avoid all your calls restarting at once.
Throttle your throughput on the client side, with a queue and a ceiling below the limit, rather than sending bursts.
By applying these principles, your integration calls less, updates faster, and helps preserve platform stability.
