Rate Limiting

Rate limiting is used to prevent abuse or excessive usage of an API, and ensure that the API remains available for all users.

Two separate limits apply: how often you may call the API, and how long any single query may run.

Request rate

LimitValue
Steady-state rate50 requests per second
Burst capacity100 requests

The burst allowance absorbs short spikes above the steady rate; sustained traffic is held to 50 requests per second. Requests beyond that are rejected with 429 Too Many Requests.

These limits are shared across all users of the Analytics API, not allocated per project. You are drawing from the same pool as everyone else, so the capacity available to you at any moment depends on what other clients are doing - and your own traffic affects theirs. Two consequences:

  • Be conservative rather than maximal. Do not treat 50 requests per second as a target. Sequential paging, or a small fixed pool of two or three workers, is enough to move millions of rows and leaves headroom for everyone.
  • Always handle 429. Because the pool is shared, you can be throttled even when your own request rate is modest. Retry with exponential backoff and jitter; jitter matters here, since synchronised retries from several clients recreate the spike that caused the throttling.

Avoid firing large batches of parallel requests, and spread scheduled extracts rather than starting them all on the hour.

Note that the per-plan quotas documented for the OpenAPI (Rate limiting) apply to api.tidio.com and are unrelated to the limits above.

In practice the limit you are far more likely to meet is the query timeout.

The 25-second query limit

Every query is given 25 seconds. If the database has not answered by then the request is aborted:

{
  "detail": "Request to database timed out after 25s. Please adjust your query."
}

returned with status 408 Request Timeout.

This is the single most common failure, and it is almost always caused by an unbounded read of a large table. Several tables hold hundreds of thousands of rows, and requesting one without a limit will time out:

# Times out after 25s
curl "https://taa.data.tidio.com/visitor_details" ...

# Returns immediately
curl "https://taa.data.tidio.com/visitor_details?limit=100" ...

How to stay inside the limit:

  • Always send a limit, or use Range headers (see Pagination).
  • Select only the columns you need - select= reduces both query time and payload size.
  • Narrow the date range before anything else; date columns are the cheapest filters.
  • Prefer Prefer: count=planned over count=exact on large tables. An exact count scans the entire table and is frequently what pushes a query over the limit.
  • Avoid leading-wildcard ilike (*text*) on large text columns - it cannot use an index and scans every row.
  • Page with a keyset cursor rather than a large offset for full extracts (see Keyset pagination for full extracts).

If a query times out consistently, split it by date and run several smaller requests rather than retrying the same one.


Did this page help you?