Docs
Parcourir la documentation

API filters and date periods

One filter syntax for the dashboard, the API, MCP and exports. Learn the period, comparison and segment inputs and how to combine conditions with AND and OR.

Voir en Markdown

Every stats operation accepts the same inputs:

Parameter Description
period A preset from Periods. Default 7d
from, to Dates (YYYY-MM-DD, inclusive) in the site's timezone, with period=custom. Without from, the range starts 29 days before to. Without to, it ends today
compare none (default), previous_period, previous_year, custom (Comparisons)
compare_from, compare_to Dates (inclusive) with compare=custom. Both are needed, or there is no comparison
match_weekday true to align the comparison by day of the week. Default false
filters See Syntax
segment_id Apply a saved segment (seg_…). Its conditions are added to filters with AND. A segment you can't use (another member's private one) or an unknown id is ignored
include_imported true to add imported history (for example from Google Analytics) to the numbers. Default false. It only applies when there are no filters and no segment

Periods#

All periods are whole days in the site's timezone, except 24h.

period Range
today Today so far
yesterday Yesterday
24h The last 24 hours, up to now
7d, 14d, 28d, 30d, 90d That many days, ending with today
mtd, qtd, ytd From the start of this month, quarter or year to today
12mo The last 12 months, ending with today
last_month, last_quarter, last_year The previous calendar month, quarter or year
all From the site's first event (or first imported day) to today
custom from to to

Comparisons#

compare Compared with
none Nothing
previous_period The same length of time right before the period. With match_weekday, shifted back by whole weeks instead
previous_year The same dates one year earlier. With match_weekday, 52 weeks earlier
custom compare_from to compare_to

Syntax#

filters is a JSON array. Each item is a condition [dimension, operator, value]. Items are combined with AND. Wrap conditions in {"any": [...]} to combine them with OR.

json
[
  ["page", "starts_with", "/blog"],
  ["country", "any_of", ["DE", "FR", "NL"]],
  { "any": [["channel", "is", "email"], ["utm_medium", "is", "newsletter"]] }
]

In URLs, send it URL-encoded:

sh
curl -G "https://privatusanalytics.com/sites/pa_7Q2K9XH3AB/stats/aggregate.json" \
  --data-urlencode 'filters=[["page","starts_with","/blog"],["country","any_of",["DE","FR"]]]' \
  -H "Authorization: Bearer $PRIVATUS_TOKEN"

In JSON bodies and MCP tool calls, pass the array itself. Conditions can also be objects: {"dimension": "page", "operator": "is", "value": "/"}.

Limits: 20 conditions in total, regular expressions up to 200 characters. An any group needs at least one condition.

Operators#

Operator Value Meaning
is, is_not a string Equals / doesn't equal (case-sensitive)
any_of, none_of a list with at least one item Equals one of / none of (case-sensitive)
contains, not_contains a string Contains / doesn't contain the text, ignoring case
starts_with a string Starts with the text (case-sensitive)
wildcard, not_wildcard a string The whole value matches, with * standing for any characters, e.g. /blog/*/comments (case-sensitive)
regex, not_regex a string Matches / doesn't match a PostgreSQL regular expression (case-sensitive)
gt, lt a number Greater / less than
between [min, max], two numbers Inclusive range

For wildcard and not_wildcard, * is the only special character and the whole value must match, so ["page", "wildcard", "/blog/*"] matches every blog page. page values include a query parameter only when the site keeps it (Site settings, Privacy), stored in alphabetical order, e.g. /blog?page=3&sort=new.

gt, lt and between compare numbers, so they are meant for numeric properties (prop:<key>). A stored value that isn't a number never matches.

Dimensions#

The same keys are used for filters and for /sites/{site_id}/breakdown/{dimension}.

Dimension Label Scope
channel Channel Visit (first touch)
referrer Referrer Visit (first touch)
referrer_url Referrer URL Visit (first touch)
utm_source UTM source Visit (first touch)
utm_medium UTM medium Visit (first touch)
utm_campaign UTM campaign Visit (first touch)
utm_content UTM content Visit (first touch)
utm_term UTM term Visit (first touch)
ref Ref Visit (first touch)
hostname Hostname Visit (first touch)
country Country Visit (first touch)
language Language Visit (first touch)
device Device Visit (first touch)
browser Browser Visit (first touch)
browser_version Browser version Visit (first touch)
os Operating system Visit (first touch)
os_version OS version Visit (first touch)
screen Screen size Visit (first touch)
entry_page Entry page Visit only
exit_page Exit page Visit only
interaction Interaction Visit only
bot_score Bot score Visit only
page Page Event / page
event Event Event / page
goal Goal Goal
prop:<key> Custom property value, e.g. prop:plan Event
  • Visit (first touch) dimensions describe how a visit started. Events carry their visit's values, so "country is DE" works for events too.
  • Visit only: entry and exit pages, and interaction: whether the tracker saw a real input (a pointer, key, touch or wheel event) during the visit. Its values are seen, none and unknown (the visit can't tell, for example data from before 1 October 2026). And bot_score: how likely the visit came from a bot, as likely_human, unsure, likely_bot or not_scored (see Advanced Bot Detection).
  • Event / page: page filters visits that viewed a page, and event filters visits in which an event happened.
  • Goal: ["goal", "is", "goal_…"] filters visits that converted. The value is the goal's id. Use is or any_of for visits that converted, and is_not or none_of for visits that didn't. An unknown or archived goal id matches nothing.
  • Properties: prop:<key>, e.g. ["prop:plan", "is", "pro"], or ["prop:seats", "gt", 5]. The key is 1 to 64 lowercase letters, digits or underscores.

interaction and bot_score (Traffic quality) need the Pro plan or above. On Free a breakdown by one responds with 402 plan_limit, and a filter on one is left out of the query, so the result counts every visit.

Channel values are the keys listed in Channels (organic_search, ai_assistants…). Countries are ISO 3166-1 alpha-2 codes. There are no region or city dimensions.

Errors#

An unknown dimension or operator, a list operator without a list, a number operator without a number, an invalid regex, or filters that isn't a JSON array returns 422 validation_failed with the reason in message. An unknown period, compare or interval value returns 422 too.