Overview
The Query API provides aggregated access to Scrunch’s core AI visibility metrics. It is the same data that powers the Scrunch dashboard, exposed in a flexible, queryable format for analytics and reporting workflows. This API is optimized for scale and performance, making it ideal for BI tools, reporting pipelines, scheduled exports, and automation where response-level detail is not required. Each request returns pre-aggregated metrics based on the dimensions you select.What the Query API includes
The Query API returns aggregated metrics such as:- Brand presence percentage
- Brand position score
- Brand sentiment score
- Competitor presence percentage
- Sub-brand presence, position, and sentiment
- Citation rate, share of voice, and citation volume
- Response counts
- Date (day, week, month, quarter, year)
- Prompt or prompt metadata
- Persona
- Tag
- Platform
- Competitor
- Sub-brand
- Source URL
- Branded vs non-branded
When to use the Query API
Use the Query API when you need:- Weekly or monthly reporting
- Trend analysis over time
- Brand and competitor visibility metrics
- Aggregation by date, persona, tag, platform, or prompt
- Data for dashboards (Looker, Power BI, Tableau)
- Large batch metric pulls for automation or reporting
“How do we compare to competitors by topic or platform?”
When not to use the Query API
The Query API is not appropriate if you need:- Raw AI response text
- Citation URLs or snippets
- Per-response competitor sentiment or position
- Full message-level audits or research
Example query
filters (pre-aggregation, on dimensions) and having (post-aggregation, on metrics):
Two ways to query
The Query API exposes two endpoints that share the same dimensions and metrics:GET /v1/{brand_id}/query— URL-parameter form. Use it for simple pulls and BI integrations that prefer query strings.POST /v2/query/{brand_id}— JSON-body form. Use it when you need post-aggregation thresholds (HAVING), negated filters, or period-over-period comparison in a single request. See the Structured Query Endpoint reference.
POST /v2 endpoint additionally requires the Query scope on the key.
Fields reference
Specify fields in thefields= array to control what is returned. Dimensions determine how metrics are grouped — querying a dimension alone returns its unique values. Metrics are numeric measures — querying a metric alone returns its overall aggregate across all data.
Dimensions
Metrics
Citation metrics are computed on the staging source path. To break citations down by source, pair them with the
domain, source_url, owner, cited_competitor_name, citation_segment, or source_topic dimensions — these activate the source-grain breakdown. You can also break citation metrics down by prompt (on its own or combined with a source-grain dimension) to see per-prompt citation rates. Mixing citation fields with high-cardinality dimensions can be slower than mention-only queries; keep date windows and field lists tight.Pooled “All (brands & competitors)” metrics. The
market_* metrics roll mention, position, sentiment, and rank up across your brand and every active competitor in a single volume-weighted average. Use them to track the overall AI conversation about your category — not the sum of per-entity rates. They run as their own query path, so they cannot be mixed with brand, competitor, or sub-brand metrics in the same request; pull them on their own and combine the series downstream.Active-entity scope. Sub-brand metrics, the
sub_brand_id breakdown, competitor citation metrics, and the cited_competitor_name filter and breakdown only count rows tied to currently active sub-brands and competitors. Archived sub-brands (including those whose parent competitor is no longer active) and deactivated competitors are excluded from numerators, share-of-voice denominators, and breakdown values. Re-activate the entity in your Scrunch brand configuration to bring its history back into results.Share of Voice supported breakdowns and filters
Mention Share of Voice (brand_share_of_voice, competitor_share_of_voice) divides an entity’s present-response count by the full brand-plus-active-competitors set. Adding a breakdown re-buckets both sides of that ratio, so each row divides by its own slice’s present-set — never a global total. Only the dimensions listed below produce a valid partition; anything else returns HTTP 400.
Supported breakdowns. date, date_week, date_month, date_quarter, date_year, ai_platform, stage, persona_name, country, prompt, competitor_id, competitor_name.
The prompt breakdown partitions the denominator per prompt, so each row is that prompt’s share of voice against the full competitive set on the same prompt.
Supported filters. All of the supported breakdowns are also filterable, plus prompt_id, tag, prompt_topic, and ai_platform_search_enabled. tag and prompt_topic are filter-only for Share of Voice — as breakdowns they would fan a multi-tag response across array elements in the numerator while it counts once in the whole-set denominator, inflating the share.
Not supported. The conditional dimensions position_bucket, sentiment_band, and rank are rejected as both breakdowns and filters — they describe one entity’s row within a response, so they cannot narrow the whole-set denominator. Source-grain fields (domain, source_url, owner, cited_competitor_name, citation_segment, source_topic, source_type, source_domain) are citation-path only and cannot combine with mention Share of Voice.
Sub-brand Share of Voice. sub_brand_share_of_voice runs on the sub-brand query path. It accepts tag and prompt_topic as filters (parity with sub_brand_citation_share_of_voice) but still rejects them as breakdowns. The prompt (text) dimension is not available on this path at all — for a per-prompt sub-brand slice, break down by prompt_id instead.
Example: citation metrics
Example: Influence Score for outreach prioritization
Rank cited domains by Influence Score alongside the share of pages that already mention your brand — a shortlist of high-influence sources you don’t yet appear on:Example: citations broken down by domain topic
Break down citation volume by the topic tags configured for each cited source’s domain. Untagged sources appear in an explicitUntagged bucket:
Example: pooled market metrics
Example: sub-brand citation rate by platform
Break down how often each AI platform cites a specific sub-brand’s owned domains:Cross-grain pooled presence
cross_grain_presence_percentage pools presence across the brand grain (your brand plus selected competitors) and the sub-brand grain (selected sub-brands) into one presence rate. A response counts as present if any selected entity on either grain appeared, so a response that mentions both a brand-grain entity and a sub-brand-grain entity is counted once — not twice.
Use it when you want to chart brand + sub-brand visibility as a single combined series (for example, “Own brand + all sub-brands” or “Own brand + one sub-brand + one competitor”) without the double-counting you’d get from summing the per-grain rates.
Selecting which entities join the pool
By default the pool includes your own brand plus every active competitor and every active sub-brand. Narrow either grain with a positive filter on that grain’s identity field:filters=competitor_name:<name>— narrows the competitor branch of the brand grain. Your own brand always stays in the pool.filters=sub_brand_id:<id>— narrows the sub-brand grain to the named sub-brand(s).filters=ownership:competitor— signals “include the competitor branch” when you want all active competitors in the pool but have no specific names to list. Without either this filter or acompetitor_namelist, the pool drops the competitor branch entirely and uses your own brand alone on the brand grain.
IN (...) — the pool is the union of the named entities, matching what an Explorer multi-select produces. Negated identity filters (competitor_name:!<name>, sub_brand_id:!<id>) are rejected with HTTP 400.
Supported breakdowns
Cross-grain pooling is presence-only, so it accepts only the non-conditional lens dimensions:date, date_week, date_month, date_quarter, date_year, ai_platform, stage, persona_name, persona_id, country, branded, prompt_id.
Entity-identity breakdowns (competitor_id, competitor_name, sub_brand_id) and source-grain dimensions (domain, source_url, owner, source_domain) are not supported — the pooled series has no per-entity split. Position, sentiment, rank, and share-of-voice have no cross-grain analogue and are not available either.
Example
Weekly combined presence for your brand, a chosen competitor, and one sub-brand on ChatGPT:Only active competitors and sub-brands contribute to the pool. Archived competitors and sub-brands (including those whose parent competitor is no longer active) are excluded from the numerator, so re-activate them in your brand configuration to bring their history back in.
Filtering results
The Query API supports two filter parameters that narrow what is returned. Both can be combined in the same request and both can be repeated to apply multiple filters (combined with AND).Dimension filters (filters)
Use filters to narrow rows before aggregation runs. Each filter takes the form field:value. Combine multiple values with | for an IN match, and prefix the value with ! to negate.
prompt_id, persona_id, persona_name, ai_platform, ai_platform_search_enabled, tag, competitor_id, competitor_name, sub_brand_id, branded, stage, prompt_topic, country, position_bucket, sentiment_band, rank, date, date_week, date_month, date_quarter, date_year, owner.
rank values must be positive integers (1, 2, …); non-numeric values return HTTP 400.
owner accepts a closed vocabulary — brand, competitor, other. Any other value returns HTTP 400; see Filtering by citation source owner.
source_url, domain, source_domain, source_topic, prompt, and query_fanouts are not filterable.
Filter for prompts with no tag or topic
Pass the reserved token__none__ as a filter value on tag or prompt_topic to match prompts that carry no tag or no topic. Use it to isolate the untagged tail of your prompt set.
__none__ with real values using | — the filter matches the untagged prompts or the named tags:
! to invert the whole filter — for example, prompts that carry at least one tag:
tag and prompt_topic accept __none__. Sending it on any other dimension returns HTTP 400. A tag literally named __none__ becomes unreachable by equality — the token always resolves to the absence match. Rename such a tag if you need to filter for it directly.
Filtering by citation source owner
owner scopes results to citations owned by the brand, a configured competitor, or a third party. Values are a closed vocabulary: brand, competitor, other. Any other value returns HTTP 400.
The filter behaves at two grains depending on what else is in fields:
- Response grain (default). Without a source-grain breakdown, the filter keeps whole responses that cite at least one source of that owner. Every metric in the request is scoped to those responses.
- Source grain (with
domain,source_url,citation_segment, orsource_topicinfields). The filter narrows the source-grain rows to the matching sources only, so a citation-domain breakdown returns just the domains owned by the selected class.
owner filter creates citation context, so it must be paired with a citation metric (for example citation_count, brand_citation_rate, citation_unique_responses). Pairing owner with only response-level metrics such as responses returns HTTP 400 — use the owner breakdown for that shape instead.
Metric filters (having)
Use having to filter on aggregated metric values after GROUP BY runs. Each entry takes the form metric:operator:value.
having must also appear in fields.
Breaking mentions down by a conditional dimension
position_bucket, sentiment_band, and rank are conditional dimensions — they describe how an entity appeared in a response, so they only exist on responses where that entity is actually mentioned (and, for rank, ranked):
position_bucket:top,middle,bottomsentiment_band:positive,mixed,negative,nonerank: positive integers (1,2, …), where1is the first mention
rank, not ranked) are excluded from the breakdown — there is no “not mentioned” or “rank 0” row. Alongside a presence metric, each row reports that bucket’s share of mentions: the buckets within a group sum to 1.0 (100% of mentioned responses), not to the overall mention rate. To relate the shares back to overall visibility, run a second query without the conditional dimension or multiply each share by the overall presence metric.
The conditional dimension follows the entity scope of the metric it is paired with:
- Pair with
brand_*mention metrics to break out your brand’s position, sentiment, or rank distribution. - Pair with
competitor_*mention metrics (plus acompetitor_id/competitor_namefilter) to break out a competitor’s distribution. - Pair with
market_*mention metrics to break out the pooled distribution across every tracked entity.
Position breakdown
Rank distribution
rank with a competitor_* mention metric (and a competitor_id filter) to chart the same distribution for a competitor, or with a market_* mention metric to chart the pooled distribution across every tracked entity.
Crossing with non-conditional dimensions
The same decomposition holds per group when you cross a conditional dimension with a non-conditional one — shares sum to 1.0 within eachai_platform below:
Filtering on a conditional dimension
You can also use either dimension purely as a filter — for example, to restrict every other metric in a query to responses where the brand appears in the top of the answer, or only to positive mentions:This behavior only applies when
position_bucket or sentiment_band is in fields. For queries that do not group by either, brand_presence_percentage keeps its usual meaning — the share of all responses that mention the brand.Date range and validation
Use thestart_date and end_date query parameters to scope a request to a specific window. Both are optional and accept the YYYY-MM-DD format.
Example: valid request
Example: invalid date returns 400
Cardinality and result size
Because the Query API performs grouping dynamically, combining highly granular dimensions can significantly increase the number of rows returned. Examples of high-cardinality dimensions include:- ai_platform
- tag
- prompt_topic
- competitor_id
- competitor_name
- source_url
- source_domain
- domain
- source_type
- query_fanouts
Limits and performance considerations
- The Query API supports large batch pulls (up to tens of thousands of rows per request)
- Results are pre-aggregated and optimized for analytics and BI ingestion
- Query performance degrades as result cardinality increases
Best practices
- Prefer date_week or date_month over daily granularity when possible
- Run separate queries for different reporting needs and join downstream
- Keep field lists small to control result size
- Use brand-scoped API keys when embedding in client-facing dashboards
- Treat Query API outputs as metrics tables, not raw data logs
Relationship to the Responses API
The Query API and Responses API are complementary:- Query API: fast, aggregated metrics for reporting and dashboards
- Responses API: full-fidelity response text and citation data for deep analysis
Run your first query
Go to the Query API Quickstart →