> ## Documentation Index
> Fetch the complete documentation index at: https://tinyanalytics.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# API Rate Limits and CORS

> Understand per-key server ingestion limits, 429 responses, and the CORS rules that keep browser ingestion open while protecting private API calls.

tinyanalytics applies a **per-key rate limit to server-side ingestion** and restricts **which origins** may call the API. Browser tracking is deliberately open; authenticated reads and writes are locked to trusted origins.

## Ingestion rate limit

Server-side calls to [`POST /api/track`](/docs/api-reference/track-events-api) authenticated with an [API key](/docs/api-reference/api-authentication) are rate-limited **per key**. Exceed the limit and the request returns:

```
429 Too Many Requests
```

A few things worth knowing:

* The limit applies **only to keyed (server-side) ingestion**. Browser tracking and analytics reads are not rate-limited this way; [MCP](/docs/api-reference/mcp-server) 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).
* Stay within your window and space out bursts; if you're batching a backfill, add a short delay between requests and retry a `429` after a pause.

## MCP request limit

Calls to the [MCP server](/docs/api-reference/mcp-server) are limited to **120 requests per minute per API key**. Beyond that the endpoint returns `429 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:

| Paths                                                            | Origins                  | Credentials |
| ---------------------------------------------------------------- | ------------------------ | ----------- |
| Ingestion & assets — `/api/track`, `/api/identify`, `/script.js` | **Any origin**           | Never sent  |
| Everything else — reads, management                              | **Trusted origins only** | Sent        |

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`.

<Note>
  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.
</Note>

## Frequently asked questions

<AccordionGroup>
  <Accordion title="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`](/docs/api-reference/track-events-api). Space out bursts, and if you're batching a backfill, add a short delay between requests and retry a `429` after a pause.
  </Accordion>

  <Accordion title="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.
  </Accordion>

  <Accordion title="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.
  </Accordion>

  <Accordion title="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.
  </Accordion>
</AccordionGroup>

## Related

<Columns cols={2}>
  <Card title="API keys" icon="key" href="/docs/api-reference/api-authentication">
    Create the key ingestion is limited by.
  </Card>

  <Card title="Tracking API" icon="paper-plane" href="/docs/api-reference/track-events-api">
    The endpoint the limit applies to.
  </Card>

  <Card title="Configure the tracking script" icon="sliders" href="/docs/configure-tinyanalytics-tracking-script">
    Browser tracking needs no key or origin setup.
  </Card>

  <Card title="API reference" icon="book-open" href="/docs/api-reference/tinyanalytics-api">
    Authentication and response conventions.
  </Card>
</Columns>


## Related topics

- [Track Events API](/docs/api-reference/track-events-api.md)
- [API Authentication Keys](/docs/api-reference/api-authentication.md)
- [Connect an AI Agent with the MCP Server](/docs/api-reference/mcp-server.md)
