Overview
The report endpoints, Get Brands Report, Get Domains Report, and Get URLs Report, all share three controls that shape what you get back:dimensionsdecide how the report is broken down.filtersdecide which underlying chats feed into the numbers (applied before aggregation).havingdecide which aggregated results are returned (applied after aggregation).
Dimensions
Every report always breaks down by its own entity: the Brands report returns one result per brand, the Domains report one per domain, the URLs report one per URL. A report with no dimensions returns a single aggregated result per entity. Adding dimensions splits each entity’s result into finer slices. You get one result for each combination of the entity and the requested dimension values. For example, on the Brands report, requesting["tag_id", "model_id"] returns one result per (brand × tag × model) combination, not one per (tag × model) pair. On the URLs report the same dimensions produce one result per (URL × tag × model), and so on.
Available dimensions include model_id, model_channel_id, country_code, prompt_id, tag_id, topic_id, chat_id, date, week, and month.
Always break down by engine (
model_channel_id) rather than only looking at the aggregate. An overall number can hide that you’re strong on one engine and invisible on another.filters vs having
Both narrow a report, but they act at different stages and have very different effects on ratio metrics (share_of_voice, visibility, retrieval_rate, retrieved_percentage, citation_rate).
filters, applied before aggregation
filters decide which chats are counted at all. Because they run before the numbers are computed, they shrink both the numerator and the denominator of every ratio metric.
Use filters when you want to genuinely restrict the scope of the analysis, for example, “only chats from ChatGPT” or “only chats in Germany.”
having, applied after aggregation
having decide which finished results come back. They run after every metric has already been computed, so they do not change any metric’s value. They only hide results you don’t want to see.
Use having when you want to keep the full-population metrics but only display a subset of results.
Population fields (
model_id, model_channel_id, country_code, prompt_id, tag_id, topic_id, chat_id) in having require the matching value in dimensions, otherwise the field isn’t part of the breakdown and the request is rejected.Pitfall: collapsing share of voice with filters
share_of_voice is a brand’s mentions divided by the mentions of all in-scope brands. If you scope to a single brand using filters, you remove every other brand from the calculation before it runs, so the denominator becomes just that one brand, and share of voice collapses to 1.0.
To look at one brand while keeping a meaningful share of voice, put brand_id in having instead:
filters shrink the denominators behind retrieval_rate and retrieved_percentage, while having selects results without touching them.
Pitfall: double-counting when you sum across tags yourself
A single prompt can carry multiple tags. (Topics are different: each prompt belongs to exactly one topic, so topics don’t overlap.) When you break a report down bytag_id, a chat whose prompt has three tags contributes to all three tag results. That’s exactly what you want when comparing tags against each other, since each tag’s number reflects everything labeled with it.
The trouble starts when you take those per-tag results and add them up yourself to get a total. Because overlapping chats were counted under every tag they belong to, your hand-rolled total counts them multiple times and overshoots the truth.
The fix is simple: let the report do the aggregation. Request the report without the tag_id dimension (or with no dimensions at all) and Peec aggregates over distinct chats, counting each one once:
Correct
Request once without
tag_id. Each chat is counted a single time.Incorrect
Request broken down by
tag_id, then add the results together. Multi-tagged chats are counted once per tag.When you do need to combine results across non-overlapping dimensions (such as
model_id or date), use the aggregation formulas documented on each report endpoint rather than naively averaging. Ratio metrics must be recombined from their underlying sums, not averaged.