AMS Query DSL Reference
The AMS Query API uses a SQL-like Domain Specific Language (DSL) for requesting OOH measurement metrics. This document describes the query syntax and provides examples, as well as a mapping back to the structured JSON queries.
Query Structure
A query follows this general structure:
SELECT <metrics>
FROM <layer>
FOR AUDIENCE <universe> [TARGET <segment>]
WHERE <filters>
DURING <time_range>
[GROUP BY <dimensions>]
[ORDER BY <field> ASC|DESC]
[LIMIT <n>]
[VERSION <model_version_id>]
JSON Mapping
| DSL Clause | JSON Field | Required |
|---|---|---|
SELECT | select | Yes |
FROM | layer | No (default: audience) |
FOR AUDIENCE | audience.universe_id | Yes |
TARGET | audience.target | No |
WHERE | filters | Yes |
DURING | time | Yes |
GROUP BY | groupby | No |
ORDER BY | order_by | No |
LIMIT | limit | No |
VERSION | model_version_id | No |
SELECT Clause
Specifies which metrics to calculate. Each metric can have an aggregation method and optional period basis.
Available Metrics
| Metric | Description |
|---|---|
imps | Raw impression count (noticed exposures) |
reach | Unique individuals reached |
reach_pct | Reach as percentage of universe |
target_reach_pct | Reach as percentage of target segment |
freq | Average frequency (impressions per reached person) |
grps | Gross Rating Points = (impressions / universe) x 100 |
trps | Target Rating Points = (target impressions / target universe) x 100 |
Aggregation Methods
| Aggregation | Description |
|---|---|
total | Sum all values (default) |
avg | Average across the period |
Period Basis
| Period | Description |
|---|---|
daily | Metrics on a per-day basis |
weekly | Metrics on a per-week basis |
quad_weekly | Metrics on a 4-week basis (standard OOH buying period) |
Syntax
SELECT total(imps), total(reach), avg(freq)
SELECT avg(imps) PER weeklyJSON
{
"select": [
{"metric": "imps", "agg": "total"},
{"metric": "reach", "agg": "total"},
{"metric": "freq", "agg": "avg"}
]
}With period basis:
{
"select": [
{"metric": "imps", "agg": "avg", "period": "weekly"}
]
}FROM Clause (Exposure Layer)
Specifies which exposure measurement layer to use. Layers represent different stages of the visibility funnel per Geopath/MRC standards.
Available Layers
| Layer | Description |
|---|---|
ots | Opportunity To See - Circulation-based count of people passing the unit who have a reasonable opportunity to notice the ad |
lts | Likelihood To See (VAC) - Visibility-adjusted based on unit characteristics, environment, and viewing conditions |
audience | Full Audience Model - Demographic and behavioral adjustments applied (default) |
Syntax
SELECT total(imps) FROM audience
SELECT total(imps) FROM lts
SELECT total(imps) FROM otsJSON
{
"layer": "audience"
}FOR AUDIENCE Clause
Defines the population universe used as the denominator for GRP calculations. Optionally includes a target segment for TRP calculations.
Syntax
FOR AUDIENCE universe_id=1
FOR AUDIENCE universe_id=1 TARGET age_range=[18,49] AND sex=['M','F']JSON
Basic universe:
{
"audience": {
"universe_id": 1
}
}With target demographic:
{
"audience": {
"universe_id": 1,
"target": {
"age_range": [18, 49],
"sex": ["M", "F"],
"combine": "and"
}
}
}Target Segment Fields
| Field | Type | Description |
|---|---|---|
age_range | [min, max] | Age range inclusive (e.g., [18, 34]) |
sex | ["M"], ["F"], or ["M", "F"] | Biological sex filter |
ethnicity | string[] | Ethnicity codes per census classifications |
income_range | [min, max] | Annual household income in USD |
segment_ids | string[] | Pre-defined segment IDs for custom targeting |
combine | "and" or "or" | How to combine criteria (default: "and") |
WHERE Clause (Filters)
Filters constrain which inventory and data are included in the query. Multiple filter objects in the array are combined with OR logic. Within a single filter object, fields are combined with AND logic.
Filter Types
Geographic Filters
WHERE dma_id IN (501, 803, 602)
WHERE state IN ('NY', 'CA', 'TX')
WHERE zipcode IN ('10001', '90210'){
"filters": [
{
"geo": {
"dma_ids": [501, 803, 602],
"states": ["NY", "CA"],
"zipcodes": ["10001", "90210"],
"geo_mode": "asset_location"
}
}
]
}| Field | Description |
|---|---|
dma_ids | Nielsen DMA IDs |
states | US state codes |
zipcodes | 5-digit ZIP codes |
geo_mode | "asset_location" (where units are) or "audience_residence" (where viewers live) |
Operator Filters
WHERE operator_id IN (1, 2, 3)
WHERE plant_id IN (100, 101){
"filters": [
{
"operator": {
"operator_ids": [1, 2, 3],
"plant_ids": [100, 101]
}
}
]
}Inventory Filters
WHERE asset_id IN ('asset_001', 'asset_002')
WHERE format IN ('billboard', 'transit')
WHERE environment IN ('roadside', 'retail'){
"filters": [
{
"inventory": {
"asset_ids": ["asset_001", "asset_002"],
"frame_ids": ["frame_001"],
"format": ["billboard", "transit"],
"environment": ["roadside", "retail"]
}
}
]
}Campaign Filters
WHERE campaign_id IN ('camp_12345')
WHERE placement_id IN ('plc_001', 'plc_002'){
"filters": [
{
"campaign": {
"campaign_ids": ["camp_12345"],
"placement_ids": ["plc_001", "plc_002"]
}
}
]
}Combining Filters
AND within a filter object:
{
"filters": [
{
"geo": {"dma_ids": [501]},
"inventory": {"format": ["billboard"]}
}
]
}This returns billboards in DMA 501.
OR across filter objects:
{
"filters": [
{"geo": {"dma_ids": [501]}},
{"geo": {"dma_ids": [803]}}
]
}This returns results from DMA 501 OR DMA 803.
DURING Clause (Time Range)
Specifies the date range for the query.
Syntax
DURING '2025-01-01' TO '2025-01-28'
DURING '2025-01-01' TO '2025-01-28' TIMEZONE 'America/New_York'
DURING '2025-01-01' TO '2025-01-28' AS OF '2025-02-01'JSON
{
"time": {
"start_date": "2025-01-01",
"end_date": "2025-01-28",
"timezone": "America/New_York",
"as_of_date": "2025-02-01"
}
}| Field | Description |
|---|---|
start_date | Start date (YYYY-MM-DD, inclusive) |
end_date | End date (YYYY-MM-DD, inclusive) |
timezone | IANA timezone for time-based groupings (default: UTC) |
as_of_date | Point-in-time for historical queries (audit/reproducibility) |
GROUP BY Clause
Specifies dimensions to aggregate results by. Returns one row per unique combination of grouping values.
Available Dimensions
OOH Metadata
| Dimension | Description |
|---|---|
asset_id | Unique identifier for an OOH asset (physical location) |
frame_id | Unique identifier for a frame (ad face) within an asset |
operator_id | Media owner/operator identifier |
operator | Operator name (for display) |
format | Inventory format (billboard, transit, street_furniture) |
environment | Placement environment (roadside, retail, airport) |
Time
| Dimension | Description |
|---|---|
date | Calendar date (YYYY-MM-DD) |
day_of_week | Day of week (0=Monday, 6=Sunday) |
hour | Hour of day (0-23) |
hour_of_week | Hour index within the week (0-167) |
week | ISO week start date (Monday) |
Geography
| Dimension | Description |
|---|---|
dma | Nielsen Designated Market Area ID |
state | US state code |
zipcode | 5-digit ZIP code |
Syntax
GROUP BY operator, dma
GROUP BY week, format
GROUP BY hourJSON
{
"groupby": ["operator", "dma"]
}ORDER BY Clause
Specifies sort order for results. Fields must be in select or groupby.
Syntax
ORDER BY grps DESC
ORDER BY week ASC, imps DESCJSON
{
"order_by": [
{"field": "grps", "direction": "desc"}
]
}LIMIT Clause
Limits the number of rows returned.
Syntax
LIMIT 20JSON
{
"limit": 20
}VERSION Clause
Pins the query to a specific model version for reproducibility.
Syntax
VERSION 42JSON
{
"model_version_id": 42
}Complete Examples
Example 1: Simple Impressions Query
DSL:
SELECT total(imps)
FROM audience
FOR AUDIENCE universe_id=1
WHERE dma_id IN (501)
DURING '2025-01-01' TO '2025-01-28'JSON:
{
"select": [{"metric": "imps", "agg": "total"}],
"filters": [{"geo": {"dma_ids": [501]}}],
"audience": {"universe_id": 1},
"time": {"start_date": "2025-01-01", "end_date": "2025-01-28"},
"layer": "audience"
}Example 2: Reach and Frequency by Operator
DSL:
SELECT total(reach), avg(freq), total(grps)
FROM audience
FOR AUDIENCE universe_id=1
WHERE dma_id IN (501)
DURING '2025-01-01' TO '2025-01-28'
GROUP BY operator
ORDER BY grps DESC
LIMIT 20JSON:
{
"select": [
{"metric": "reach", "agg": "total"},
{"metric": "freq", "agg": "avg"},
{"metric": "grps", "agg": "total"}
],
"filters": [{"geo": {"dma_ids": [501]}}],
"audience": {"universe_id": 1},
"time": {"start_date": "2025-01-01", "end_date": "2025-01-28"},
"layer": "audience",
"groupby": ["operator"],
"order_by": [{"field": "grps", "direction": "desc"}],
"limit": 20
}Example 3: Target Demographics (TRPs)
DSL:
SELECT total(imps), total(trps), total(target_reach_pct)
FROM audience
FOR AUDIENCE universe_id=1 TARGET age_range=[18,49] AND sex=['M','F']
WHERE dma_id IN (501, 803, 602)
DURING '2025-01-01' TO '2025-01-28'
GROUP BY dmaJSON:
{
"select": [
{"metric": "imps", "agg": "total"},
{"metric": "trps", "agg": "total"},
{"metric": "target_reach_pct", "agg": "total"}
],
"filters": [{"geo": {"dma_ids": [501, 803, 602]}}],
"audience": {
"universe_id": 1,
"target": {
"age_range": [18, 49],
"sex": ["M", "F"],
"combine": "and"
}
},
"time": {"start_date": "2025-01-01", "end_date": "2025-01-28"},
"layer": "audience",
"groupby": ["dma"]
}Example 4: Weekly Campaign Performance
DSL:
SELECT total(imps)
FROM audience
FOR AUDIENCE universe_id=1
WHERE campaign_id IN ('camp_12345')
DURING '2025-01-01' TO '2025-02-28'
GROUP BY week, format
ORDER BY week ASCJSON:
{
"select": [{"metric": "imps", "agg": "total"}],
"filters": [{"campaign": {"campaign_ids": ["camp_12345"]}}],
"audience": {"universe_id": 1},
"time": {"start_date": "2025-01-01", "end_date": "2025-02-28"},
"layer": "audience",
"groupby": ["week", "format"],
"order_by": [{"field": "week", "direction": "asc"}]
}Example 5: Hourly Daypart Analysis
DSL:
SELECT avg(imps) PER daily
FROM audience
FOR AUDIENCE universe_id=1
WHERE dma_id IN (501) AND format IN ('billboard') AND environment IN ('roadside')
DURING '2025-01-01' TO '2025-01-28' TIMEZONE 'America/New_York'
GROUP BY hour
ORDER BY hour ASCJSON:
{
"select": [{"metric": "imps", "agg": "avg", "period": "daily"}],
"filters": [
{
"geo": {"dma_ids": [501]},
"inventory": {"format": ["billboard"], "environment": ["roadside"]}
}
],
"audience": {"universe_id": 1},
"time": {
"start_date": "2025-01-01",
"end_date": "2025-01-28",
"timezone": "America/New_York"
},
"layer": "audience",
"groupby": ["hour"],
"order_by": [{"field": "hour", "direction": "asc"}]
}Example 6: Pinned Version for Reproducibility
DSL:
SELECT avg(imps), avg(reach), avg(freq)
FROM lts
FOR AUDIENCE universe_id=1
WHERE asset_id IN ('asset_001', 'asset_002', 'asset_003') AND format IN ('billboard')
DURING '2025-01-01' TO '2025-06-30'
GROUP BY asset_id
VERSION 42JSON:
{
"select": [
{"metric": "imps", "agg": "avg"},
{"metric": "reach", "agg": "avg"},
{"metric": "freq", "agg": "avg"}
],
"filters": [
{
"inventory": {
"asset_ids": ["asset_001", "asset_002", "asset_003"],
"format": ["billboard"]
}
}
],
"audience": {"universe_id": 1},
"time": {"start_date": "2025-01-01", "end_date": "2025-06-30"},
"layer": "lts",
"groupby": ["asset_id"],
"model_version_id": 42
}Response Format
Query responses include metadata for audit trails and the result data in a columnar format.
{
"meta": {
"request_id": "req_abc123",
"query_id": "qry_xyz789",
"generated_at_utc": "2025-01-15T10:30:00Z",
"dataset_version": "2025.01",
"methodology_version": "1.2.0",
"model_version_id": 42,
"warnings": ["Data for operator_id=3 is preliminary"]
},
"columns": [
{"name": "operator", "type": "string"},
{"name": "reach", "type": "integer"},
{"name": "freq", "type": "float"},
{"name": "grps", "type": "float"}
],
"rows": [
["Lamar Advertising", 2345678, 4.2, 125.6],
["Clear Channel Outdoor", 1987654, 3.8, 98.4],
["Outfront Media", 1654321, 3.5, 76.2]
],
"next_page_token": null
}Pagination
For large result sets, use the next_page_token to fetch subsequent pages:
{
"page_token": "eyJvZmZzZXQiOjEwMH0="
}Updated about 2 months ago
