Limits & Pricing
Public workspace plans
Section titled “Public workspace plans”This table is a derived view of the canonical product kernel in
packages/shared/src/lib/product-kernel.ts.
| Free | Starter | Pro | Enterprise | |
|---|---|---|---|---|
| Monthly price | €0 | €7 excl. VAT | €24 excl. VAT | Quote |
| Included sites | 3 | 10 | 50 | Custom |
| Included events / month | 25,000 | 100,000 | 1,000,000 | Custom |
| Included users | 1 | 3 | 10 | Custom |
| Public retention target | 60 days | 13 months | 24 months | Custom |
| Additional events | No | €2 / million | €2 / million | Custom |
| Additional users | No | €3 / user / month | €3 / user / month | Custom |
| Automatic public overage on site count | No | No | No | No |
These limits correspond to the public workspace packaging used by pricing, upgrade prompts, and dashboard consumption surfaces.
Self-serve API policy
Section titled “Self-serve API policy”This table is also derived from the same product kernel. It stays distinct from the public workspace packaging above for route families, unit caps, and rate limits. API retention itself still follows the same canonical plan-retention grid, and remains distinct only from the site-level technical retention setting available in Settings > Sites > Collection.
| Free | Starter | Pro | |
|---|---|---|---|
| API availability | Not included | Limited | Standard |
| API read retention (derived) | Not included | 395 days | 730 days |
| Monthly included API units | Not included | 100,000 | 1,000,000 |
| API hard cap (monthly) | Not included | 250,000 | 2,000,000 |
| API rate limit | Not included | 15 req/s | 30 req/s |
| API hourly interval | No | Yes | Yes |
| Reports endpoints | No | No | Yes |
| Goals endpoints | No | No | Yes |
| Tenant endpoints | No | No | Yes |
| Tenant dimensions | No | No | Yes |
Starter keeps a deliberately limited API surface. Report, goal, and tenant routes stay unavailable until the active API policy enables them.
The runtime API now transports this policy explicitly:
GET /v1/meexposes workspace-level product policy inproductGET /v1/sitesexposes site-level effective policy inproduct_configuration- profile-aware analytics reads expose an
availabilityobject and can return409when anExtended-onlyroute family is requested outside its compatible data envelope
Compatibility mirrors such as top-level plan_id or retention_days remain
derived from that canonical object, but they are now deprecated compatibility
fields. New integrations should read product.runtime_plan_id and
product.product_retention.api_retention_days instead. No removal will happen
before 2026-07-03T00:00:00Z.
Current route classes:
Strict-safe:/v1/reports/content, standard/v1/metrics/timeseries, standard/v1/metrics/breakdownMixed:/v1/reports/overview,/v1/reports/acquisition,/v1/reports/actionsAdvanced / gated:/v1/goals/conversions, tenant-scoped metrics and tenant breakdowns. These routes depend on the plan, tenant API access, and compatible configuration; do not read them as a single collection type.
For mixed routes, the response stays 200 in Strict for the strict-safe
slice, uses availability.readModel to declare that baseline explicitly, and
uses availability.sections to mark locked attribution or advanced sections.
Human reading rule: on Strict, the unflagged slice is the complete baseline
for that route. Treat flagged sections as optional Extended detail, not as
missing baseline analytics.
The same model applies in the dashboard: Audience remains useful in Strict
for technical audience dimensions, while campaign-style slices stay enriched.
Content report modes
Section titled “Content report modes”GET /v1/reports/content exposes two response shapes selected by include:
| Mode | Inclusive UTC range | Response |
|---|---|---|
summary | 1–365 days | Totals and one global daily pageview point; empty days are zero-filled |
full | 1–90 days | Totals, page details, per-page trend data, entry pages, and exit pages |
details (deprecated alias) | 1–90 days | Normalized to full; migrate new integrations to include=full |
When include is omitted, ranges through 90 days use full; ranges from 91
through 365 days use summary. Comparison is limited to 30 days in either
mode. limit has no effect on summary.
The summary timeseries is dense and ordered by UTC date: it contains exactly
one point for every requested day, and its pageview sum equals
totals.pageviews. It does not contain page paths, detailed page rows, or
top-level entry and exit lists.
Detailed synchronous Content responses and CSV exports remain limited to 90 days. A longer detailed export would require a future asynchronous workflow; none is exposed by the current API.
Cost model
Section titled “Cost model”Every successful metrics request (/v1/metrics/timeseries or
/v1/metrics/breakdown) consumes units. Non-metered endpoints (/v1/me,
/v1/sites, /v1/usage/*) are free.
Units are computed as:
units = base x interval x range x limit x dimension x metric| Factor | Value |
|---|---|
| base | 2 (timeseries) or 4 (breakdown) |
| interval | 1 (day) or 3 (hour) |
| range | ceil(days / 30) |
| limit | ceil(limit / 100) — breakdown only |
| dimension | 2 (page) or 1 (other) — breakdown only |
| metric | 2 (pageviews, sessions) or 1 (events) |
Content report metering keeps its base and duration factors in both modes.
summary does not apply a limit factor; full and the deprecated details
alias keep the existing limit factor. A final-cache hit is still billable.
Response budget
Section titled “Response budget”Every report response, including a final-cache hit, is checked against a hard
5 MiB serialized proxy-response budget. Responses are never truncated. If the
candidate response exceeds the budget, the API returns HTTP 422 with
REPORT_RESPONSE_TOO_LARGE, including include, range_days,
measured_bytes, and max_bytes in error.details. The rejected request
consumes zero metered units and is not written to the final response cache.
Examples
Section titled “Examples”| Request | Calculation | Units |
|---|---|---|
| Timeseries, pageviews, 7 days, daily | 2 x 1 x 1 x 1 x 1 x 2 | 4 |
| Timeseries, pageviews, 60 days, hourly | 2 x 3 x 2 x 1 x 1 x 2 | 24 |
| Breakdown by referrer, sessions, 30 days, limit 100 | 4 x 1 x 1 x 1 x 1 x 2 | 8 |
| Breakdown by page, pageviews, 90 days, limit 500 | 4 x 1 x 3 x 5 x 2 x 2 | 240 |
Soft overage
Section titled “Soft overage”When used_units > included_units, requests continue normally. The response
metadata indicates the overage:
{ "meta": { "units_charged": 4, "billable_overage": true, "usage": { "used_units": 104, "overage_units": 4, "included_units": 100, "hard_cap_units": 250 } }}These numbers are illustrative only. The actual included and hard-cap values
come from the active plan in the product kernel. Monitor the
billable_overage flag to alert before reaching the hard cap.
Hard cap
Section titled “Hard cap”When the hard cap is reached:
- HTTP
402with error codeHARD_CAP_REACHED - No additional usage is recorded
- Resets at the start of each billing period (1st of the month, UTC)
Rate limit
Section titled “Rate limit”Per-token rate limits are enforced in 60-second sliding windows:
- HTTP
429with error codeRATE_LIMITED - Headers:
X-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-Reset - Wait until
X-RateLimit-Resetbefore retrying
Reviewing your usage
Section titled “Reviewing your usage”- Dashboard users can inspect workspace consumption from Settings > Consumption.
- Site-specific detail and capture settings live in Settings > Sites > Collection.
GET /v1/usage/current— current billing period usageGET /v1/usage/history— monthly history (up to 24 months)
These endpoints are free and available to tokens with metrics:read or
usage:read scope.