Analytics is metered on one number: events ingested per Project per month. Not users, not reports, not seats. This page says what counts, what does not, and what happens at the limit.
Figures verified 2026-09-28; plan limits can change, so read them from your Project rather than from here when the number matters.
Plans
A Project can also carry an explicit override in its settings (eventsPerMonth), which wins over the plan. null there means unlimited. That is how a bespoke arrangement is expressed without inventing a plan.
internal is the plan our own Projects run on.
What counts as an event
An event counts when it is committed to the Project's database, not when it is posted. The consequences are all in your favour:
- Events dropped by validation (no identifier, a rejected name, a duplicate id) never count.
- Events filtered as bot traffic never count.
- A batch refused with
429or401never counts. - A retry of an event you already sent, with the same
id, does not count twice.
Imported events count, and are also tracked separately as imported, so a one-off backfill is visible as a backfill rather than as a sudden change in your traffic.
Every event counts once, whatever route it arrived on: /v1/ingest, /v1/import, the identity routes and the Mixpanel-compatible endpoint all share one counter. An identify with traits is two events, because it produces $identify and $set.
The month is calendar UTC. The counter resets at the start of each month; there is no rollover.
Reading your usage
curl -s https://t.intelligent.page/v1/projects/acme-shop/usage \ -H 'Authorization: Bearer ipa_sec_REPLACE_ME'
{ "projectId": "acme-shop", "month": "2026-09", "events": 4821903, "imported": 1200000, "quota": 10000000 }
quota is null when the Project is unlimited. The same numbers are the bar in Project settings, and the full Project detail call (GET /v1/projects/:id) returns this month's usage alongside keys and members.
At the limit
Once the month's events reach the quota, keyed writes answer:
HTTP/1.1 429 Too Many Requests
{ "error": "quota_exceeded" }
Everything that follows is worth planning for before you meet it:
- The refusal is at acceptance, so nothing is queued for you. An event refused here is gone unless your client retries it.
/v1/importstops at the first refused batch and returns what landed:{ "accepted": 1500, "rejected": 500, "quota": { "exceeded": true }, "error": "quota_exceeded" }. Resume from the event after the accepted head.- The Mixpanel-compatible routes answer their own
429shape, body0, or{"status":0,"error":"rate limit exceeded"}withverbose=1. - Browsers of our own app stay silent with
204, because a quota problem must not become an error in a visitor's console. - Reads are unaffected. Every report you already have keeps working.
Do not confuse it with the other 429. rate_limited means 6 000 events a minute on one key and clears itself within the minute; quota_exceeded means the month and does not. See Limits and validation.
Bringing usage down
In the order that usually pays:
- Send the automatic events you actually use. Our SDKs send a
$pageviewperpage()call and nothing else unless you ask:data-page="0"on the script tag suppresses the automatic first pageview, and a router that callspage()on every history change on a site with many small route changes can double your volume on its own. They are real events on your plan. - Reconsider autocapture.
autocapture: falseturns it off.$autocaptureon a busy application can outnumber every named event you have. It is the right default while you are learning what to instrument and an expensive habit afterwards. - Drop the events nobody opens. Look at the event catalog for names with high volume and no report, board or funnel using them.
- Stop double-sending. A page view from both the SDK and your router, or an order from both the storefront pixel and the webhook, is the classic doubling. The connectors are built so the server-side event is authoritative.
- Batch on the server. Batching does not change the count, but it makes the rate limit far easier to live inside.
What does not help: sending fewer properties. Metering is per event, not per property or per byte.
Changing plan
Plan changes are made by us, not through the API: a plan change is a billing change. Ask through your usual contact with the Project id and the plan you want.
An override on a single Project (eventsPerMonth in settings) is also ours to set. Anyone managing a Project can read it back but should not expect to raise it themselves.
Growing past a plan
- More keys, not a bigger limit. The 6 000 events a minute limit is per key. A key per service gives each one its own bucket and tells you which service is noisy.
- One Project per product, not per environment mistake. Every Project has its own quota, and its own database. Splitting a product across Projects to dodge a quota also splits every report.
- Import out of hours. A backfill competes with live traffic for both the rate limit and the quota. Run it when neither matters.