Skip to main content
upstack query-attribution shows which UTM source, campaign, ad set, or ad gets credit for your orders, with revenue, new customers, spend, and ROAS on every row. It wraps Run an attribution query, which has the full request and response reference. How attribution works explains how credit is assigned.

Usage

Breakdown dimensions

--dimension decides what each row is. The CLI rejects any other value before sending the request. Names come from your connected ad platform when the click’s IDs match its data, otherwise from the UTM value on the click. A campaign without matching platform data shows its raw ID as the name. Rows with no value show (not set).

Required flags

Optional flags

-i, --output, --file, and --from-file work as described in upstack query shared flags. --output table and csv print one line per row with every measure column.

Filters

--filter takes the same canonical tree as every query command. Two families of fields work here. To filter by campaign ID, put the ID in attribution.utm_campaign. Fields like channel.campaign_id belong to query-ads and query-channel-details, and this endpoint rejects them:
A value matches every row whose name or ID equals it, in any source. Add an attribution.utm_source condition when the same campaign name shows up under more than one channel.
attribution.* fields only do exact matches today. Use equals, or in for a list. upstack filters lists other operators for them, but those run as exact matches too: not_equals "Meta Ads" returns only Meta Ads. attribution.utm_medium conditions are ignored, and so are attribution.* conditions inside a not group. Keep conditions at the top level of an and, or in one or group under it. Details are in Filtering results.
orders.* conditions support every operator upstack filters lists for them, but only with --value-source orders. With events they’re ignored.

From-file schema

--from-file takes a JSON file of parameter-style keys, the same names as the flags, not the API request body. Flags override file values.

Response shape

results has one entry with dateRange, dimension, the filter you sent, data.primary, and measureDetails. The sample below is a real campaign-grain response, trimmed to a few of the measure columns.
  • Rows are sorted by orders.count (or core.conversions with --value-source events), highest first.
  • With orders, rows carry orders.* measures. With events, they carry core.conversions, core.unique_converters, core.conversion_value, core.average_conversion_value, core.cpa, and core.roas. Both add channel.* ad platform measures and tracked.* visitor counts. measureDetails lists every measure id on the rows, with its total.
  • Values are numeric strings, and zero comes back as null.
  • utm_adset and utm_ad appear on every row but only hold the row’s own ad set or ad at those two grains.

Examples

Errors

See Errors and edge cases for the full list.

See also