Ingestion rate limit
Server-side calls toPOST /api/track authenticated with an API key are rate-limited per key. Exceed the limit and the request returns:
- The limit applies only to keyed (server-side) ingestion. Browser tracking and analytics reads are not rate-limited this way; MCP has its own per-key limit, described below.
- A request with no or an invalid API key isn’t rejected with
429— it falls through to the normal browser-equivalent path (untrusted, with bot filtering on). - A valid restricted key without Event ingestion: Write receives
403; it does not fall back to untrusted browser ingestion. - Stay within your window and space out bursts; if you’re batching a backfill, add a short delay between requests and retry a
429after a pause.
API key creation limit
Creating API keys is limited to 10 attempts per signed-in user per hour. Invalid request bodies count toward the same security window. When the limit is reached, TinyAnalytics returns429 Too Many Requests with Retry-After; if the shared security limiter is temporarily unavailable, key
creation fails closed with 503 instead of minting an unbounded key.
MCP request limit
Calls to the MCP server are limited to 120 requests per minute per API key. Beyond that the endpoint returns429 Too Many Requests with a Retry-After header. This limit is separate from the ingestion limit above, and it’s sized for normal agent work — building a dashboard, where each card is previewed before it’s saved, is typically 30–60 calls over a couple of minutes.
CORS: which origins can call the API
TinyAnalytics splits the API into two CORS zones:
This is what lets the tracking script POST from any of your visitors’ pages while ensuring a third-party site can’t read your logged-in analytics. A state-changing request from an untrusted origin is rejected with a
403.
Server-to-server calls aren’t subject to CORS — it’s a browser mechanism. Reading analytics from your backend with a Bearer key works regardless of origin; CORS only governs requests made from a web page.
Frequently asked questions
What happens when I exceed the ingestion rate limit?
What happens when I exceed the ingestion rate limit?
The request returns
429 Too Many Requests. The limit applies per API key to server-side calls to POST /api/track. Space out bursts, and if you’re batching a backfill, add a short delay between requests and retry a 429 after a pause.Are browser tracking and analytics reads rate-limited too?
Are browser tracking and analytics reads rate-limited too?
No. The per-key rate limit applies only to keyed server-side ingestion. Browser tracking and analytics reads are not rate-limited this way.
Does a request without an API key get a 429?
Does a request without an API key get a 429?
No. A request with no API key, or an invalid one, isn’t rejected with
429 — it falls through to the normal browser-equivalent path, which is untrusted and has bot filtering on.What happens if my restricted key cannot ingest events?
What happens if my restricted key cannot ingest events?
A valid restricted key without Event ingestion: Write receives
403 on
POST /api/track. Remove the Authorization header for ordinary browser-style
ingestion, or add that write grant for trusted server-side ingestion.Does CORS apply to calls from my backend?
Does CORS apply to calls from my backend?
No. CORS is a browser mechanism, so server-to-server calls aren’t subject to it. Reading analytics from your backend with a Bearer key works regardless of origin.
Related
API keys
Create the key ingestion is limited by.
Tracking API
The endpoint the limit applies to.
Configure the tracking script
Browser tracking needs no key or origin setup.
API reference
Authentication and response conventions.