Skip to content
<- Guides
/engineering

Choosing the Right AMC Attribution Data Source for Custom Models

Five rows. Six rules. The base table is the whole decision.

An operator asks for a custom attribution view in AMC. An agent grounded in Amazon Agent Atlas returns a five-row data-source matrix, six decision rules, and the footnotes that would have eaten the rest of the week.

Thomas Spicer
Maintained by Kuudo
TL;DR

AMC has four custom-attribution surfaces; the choice of base table is the entire decision. Use `conversions` for de-duped pixel volume. Use `conversions_with_relevance` for multi-touch credit (campaign columns + `engagement_scope` required). Use `conversions_with_relevance_for_audiences` for any query that needs `SELECT user_id` (the audience-table variant is the only one that permits it; `user_id` is Very-high threshold elsewhere). Use `amazon_attributed_events_*` when you need to reconcile with standard reporting numbers — never for modeling.

The Slack message came in mid-afternoon, from our paid-media lead: "Our attribution model defaults are leaving us blind. Can we build a custom attribution view in AMC, and which data source do we use?"

This is the kind of ask that sounds like one question and is really three. There is not "one" Amazon Marketing Cloud (AMC) attribution table. There are several, they are not interchangeable, and the obvious moves get you the wrong one. Ask ChatGPT for the AMC attribution table and you get back a single name with no context. Search Amazon's docs and the Custom Attribution Overview instructional query (IQ) surfaces, but the data-source comparison is buried in section 3.6 where most readers never scroll. Ping the agency and they default to amazon_attributed_events_by_conversion_time because that is the standard reporting source used by the Amazon DSP (demand-side platform) UI.

So I handed it to our agent, which has Amazon Agent Atlas behind it. Atlas indexes the AMC documentation, the instructional queries, the schema reference for every Amazon Standard Identification Number (ASIN) the catalog tracks, and the privacy framework that governs which columns you can put in a SELECT. Here is what came back.

What a model without Atlas gets wrong

I ran the same prompt through a frontier model with no retrieval. The output looked plausible. It was wrong in five specific, silent ways.

Five failure modes I saw on a single un-grounded prompt:

  • It treated amazon_attributed_events_by_conversion_time as a custom-attribution source. That table is the standard-reporting source: competition-aware, 14-day last-touch, de-duped across campaigns. You cannot build a custom model on it.
  • It wrote SELECT user_id from conversions_with_relevance for an audience-building query. user_id carries the aggregation threshold "Very high" and can never appear in the final SELECT of an analytics table. The only data source that permits audience-building semantics is conversions_with_relevance_for_audiences.
  • It filtered WHERE engagement_scope = 'PROMOTED' against conversions. engagement_scope lives on conversions_with_relevance; the plain conversions table excludes every campaign-dependent column.
  • It assumed conversions and conversions_with_relevance have the same row counts. They do not. In conversions_with_relevance, a single conversion can appear on multiple rows, one per relevant campaign. The IQ example splits conversion_id 123456 across campaign_a and campaign_b.
  • It quoted a 14-day pixel lookback to size pixel volume in custom attribution. That is the standard-reporting lookback. Inside custom attribution, the pixel lookback is bounded only by when the pixel was tracked to the campaign, or by the query time window.

None of these failures throw an error. The query runs. The numbers look like attribution numbers. They are the wrong ones, and you only find out when the downstream model contradicts a sanity check.

What Atlas retrieves

When the agent gets the question, it does a semantic search across the amazon_ads collection, which is the corpus that backs the Amazon Ads MCP. It pulls six chunks before it writes anything:

  • The Custom Attribution Overview (dataset conversions) defines the two custom-attribution data sources, the 28-day ASIN relevancy rules, and the section 3.6 comparison table that names all four AMC attribution sources.
  • The Amazon Ads Conversions with Relevance chunk (dataset conversions_with_relevance) names both physical variants: the Analytics table (conversions_with_relevance) and the Audience table (conversions_with_relevance_for_audiences).
  • The Amazon Attributed Events Overview (dataset amazon_attributed_events) is the schema reference for the standard-reporting attribution data, including the LOW-threshold dimension columns.
  • The Data Aggregation Thresholds in AMC chunk (dataset amazon_attributed_events_by_conversion_time) classifies every column as None, Low, Medium, High, or Very high, and explains why user_id cannot be SELECTed from a normal analytics table.
  • The Custom Attribution Linear Model IQ template shows how a chosen base table plugs into the standard-vs-custom comparison.
  • The Joining and Unioning Sponsored Ads Traffic with Conversions chunk (dataset sponsored_ads_traffic) demonstrates that sponsored_ads_traffic joins to conversions_with_relevance, not conversions, because campaign columns are required.

Atlas does not pick the table for you. It surfaces the rules and lets the agent make the call.

The agent's output

The artifact for this kind of question is not SQL. It is a decision plan: a matrix of every AMC attribution data source side by side, then a rule set keyed off the operator's actual use case. Here is the machine-readable form the agent returned, before the prose write-up:

{
  "artifact": "decision_plan",
  "topic": "amc-custom-attribution-base-table",
  "rules": [
    {"use_case": "align with Amazon DSP / Sponsored Ads UI numbers", "pick": "amazon_attributed_events_by_conversion_time", "why": "standard-reporting source; custom attribution will not reconcile by design"},
    {"use_case": "Prime Day delivered-impression effect on conversions", "pick": "amazon_attributed_events_by_traffic_time", "why": "anchors on traffic time, matching the campaign window"},
    {"use_case": "de-duped pixel volume across all campaigns, exposed and un-exposed users", "pick": "conversions", "why": "excludes campaign columns; one row per conversion"},
    {"use_case": "linear / position-based / first-touch / last-touch multi-touch model with per-campaign credit", "pick": "conversions_with_relevance", "why": "campaign columns + engagement_scope required to split credit; one row per (conversion x relevant campaign)"},
    {"use_case": "build an audience from users satisfying a custom-attribution rule", "pick": "conversions_with_relevance_for_audiences", "why": "only data source permitting SELECT user_id for audience materialization"},
    {"use_case": "measure halo lift specifically", "pick": "conversions_with_relevance", "why": "filter engagement_scope = 'BRAND_HALO' vs 'PROMOTED' on the relevance table"}
  ]
}

Comparison matrix: the AMC attribution data sources

Data source What it is ASIN coverage Pixel coverage engagement_scope? SELECT user_id? Lookback Dedup behavior Use it for
amazon_attributed_events_by_conversion_time Standard-reporting attribution, by conversion time Ad-attributed only Ad-attributed only N/A No (user_id is Very high) 14-day last-touch (pixel) De-duped across campaigns Aligning with the standard Amazon DSP and Sponsored Ads reports
amazon_attributed_events_by_traffic_time Standard-reporting attribution, by traffic time Ad-attributed only Ad-attributed only N/A No 14-day last-touch (pixel) De-duped across campaigns Campaign-window analyses, like Prime Day delivered impressions
conversions Custom-attribution base; relevant conversions only, no campaign columns Promoted plus brand halo All pixel conversions tracked to the campaign, exposed and un-exposed users No No 28-day ASIN relevancy; pixel lookback bounded by tracking start De-duped Volume questions and de-duped pixel performance across campaigns
conversions_with_relevance (Analytics table) Custom-attribution base plus campaign and advertiser columns Same conversions as conversions, one row per relevant campaign Same conversions as conversions, one row per relevant campaign Yes (PROMOTED, BRAND_HALO, null) No Same as conversions Duplicated across relevant campaigns Multi-touch and split-credit custom models (linear, position-based, first-touch, last-touch)
conversions_with_relevance_for_audiences (Audience table) Audience-table variant of conversions_with_relevance Same as conversions_with_relevance Same as conversions_with_relevance Yes Yes, the only data source that permits SELECT user_id for audience-building Same as conversions_with_relevance Same Materializing custom-attribution audiences for activation

A note on framing: Atlas's section 3.6 comparison lists four AMC attribution data sources by splitting amazon_attributed_events into the _by_conversion_time and _by_traffic_time variants. Other framings collapse those two into one and treat conversions_with_relevance_for_audiences as the fourth distinct surface. The matrix above shows all five rows so both views are visible; the decision rules below collapse to the four-way operator choice.

Decision rules

  • If the use case is "align my custom model output with the numbers in the Amazon DSP or Sponsored Ads UI," pick amazon_attributed_events_by_conversion_time, because it is the standard-reporting source and custom attribution will not reconcile by design.
  • If the use case is "Prime Day delivered-impression effect on conversions," pick amazon_attributed_events_by_traffic_time, because it anchors on traffic time and matches the campaign window.
  • If the use case is "de-duped pixel volume across all campaigns the pixel is tracked to, exposed and un-exposed users," pick conversions, because it excludes campaign columns and emits one row per conversion.
  • If the use case is "linear, position-based, first-touch, or last-touch custom model with per-campaign credit," pick conversions_with_relevance, because campaign columns and engagement_scope are required to split credit; expect one row per (conversion x relevant campaign).
  • If the use case is "build an audience from the users who satisfy a custom attribution rule," pick conversions_with_relevance_for_audiences, because it is the only data source that permits SELECT user_id for audience materialization.
  • If the use case is "measure halo lift specifically," pick conversions_with_relevance and filter on engagement_scope = 'BRAND_HALO' versus 'PROMOTED'.

A few things to notice about how the agent broke this apart.

The amazon_attributed_events_* family is not a custom-attribution base table. It is competition-aware, de-duped across campaigns, and follows fixed last-touch logic. Use it when you need to align with standard reporting numbers. Never use it when you are modeling, because the model logic is already baked in and you cannot unbake it.

The split between conversions and conversions_with_relevance is a row-shape difference, not a coverage difference. Both tables cover the same set of relevant conversions. conversions_with_relevance adds campaign and advertiser dimensions, and as a consequence it emits one row per relevant campaign per conversion. A dedup-aware question like "how many users converted in the window, period" uses conversions. A multi-touch model that splits credit across campaigns uses conversions_with_relevance because the per-campaign rows are exactly what gets weighted.

The audience-table variant exists because of aggregation thresholds, not because someone wanted three tables instead of two. user_id is classified Very high, which means a normal analytics table cannot put it in a final SELECT, cannot filter it against a literal value, and cannot use it as a join or group-by key against literals. The _for_audiences companion is the data source that allows audience-building semantics, and it is the only one. Anything materializing user-level audiences from custom attribution flows through it.

The engagement_scope column on conversions_with_relevance is the lever for halo measurement. Values are PROMOTED for the promoted ASIN, BRAND_HALO for halo conversions to other ASINs from the same brand, and null for pixel conversions. Any custom model that wants to isolate halo lift filters on this column. Any custom model that ignores it is silently treating halo and promoted as the same thing.

The footnotes the agent surfaced unprompted

This is the part where retrieval grounding earns its keep. None of these were asked for. All of them mattered.

Six things the agent surfaced that the operator did not ask about:

  • The 28-day ASIN relevancy window for custom attribution is double the brand-based 14-day window in amazon_attributed_events_by_conversion_time and _by_traffic_time. Higher per-ASIN conversion counts in custom attribution are expected, not a bug.
  • The custom-attribution data sources are not competition-aware and include both viewable and non-viewable impressions. Two more reasons custom-attribution conversion counts run higher than the attributed-events numbers.
  • Pixel conversions in conversions and conversions_with_relevance do not require an ad impression or click to be relevant. If a pixel was tracked to a DSP campaign, all pixel conversions appear, including from users who were never exposed.
  • Pixel lookback inside custom attribution is bounded by when the pixel was tracked to the campaign, or by the query time window. It is not the 14-day last-touch lookback that amazon_attributed_events_* uses. Sizing pixel volume with the wrong lookback is a common silent error.
  • engagement_scope is always PROMOTED for pixel conversions (when event_category = 'pixel'), and halo_code is null for pixels. Both columns are LOW-threshold dimensions and both live only on conversions_with_relevance.
  • user_id (aggregation threshold Very high) can never appear in the final SELECT, cannot be filtered with literal values, and cannot be used as a join or group-by key against literals. It can, however, be COUNT or COUNT DISTINCTed, which is how reach, optimal-frequency, and customer-journey queries get written. The _for_audiences audience table exists as a separate physical surface precisely because the analytics tables cannot do the audience-shaped thing.

Most of these would have cost an hour each to discover the hard way. Compounded across a quarter, they are the difference between a custom attribution program that ships and one that gets quietly abandoned.

What happens next

The decision plan is the input, not the output. Once you have picked the base table, the operational moves diverge.

If you picked conversions_with_relevance for a multi-touch model, the next step is to schedule the linear or position-based IQ as a recurring AMC workflow. Package it as a verified Skill and export the campaign-weighted credit to a dashboard. If you picked conversions_with_relevance_for_audiences, the next step is to activate the resulting user set as an AMC audience, following the same pattern documented in the cart-abandoner audience guide. If you picked conversions for de-duped pixel volume across campaigns, feed it into the same pipeline pattern used in the Subscribe & Save lift workflow, substituting your custom-attribution filters.

If you picked amazon_attributed_events_by_conversion_time or _by_traffic_time, stop. You are doing standard reporting alignment, not custom modeling. Route the work to the standard-reports surface and save AMC for the questions standard reports cannot answer.

Why this matters

Pick the wrong base table and every downstream model inherits the wrong numbers, silently, for as long as the workflow runs.


Next in the series: building a path-to-conversion view in AMC that stitches DSP, Sponsored Products, Sponsored Brands, and Sponsored Display into a single touch-ordered timeline. Custom attribution sets the base table; path analysis is what you do with it.

Quick answers

What's the difference between conversions and conversions_with_relevance in AMC?

Both data sources cover the same set of relevant conversions. conversions_with_relevance adds advertiser and campaign columns, which means a single conversion can appear on multiple rows — one row per relevant campaign. Use conversions for de-duped volume questions. Use conversions_with_relevance for multi-touch credit splitting.

Why does my AMC custom-attribution query return more conversions than the standard reports?

Three reasons. Custom attribution uses a 28-day ASIN relevancy window versus the standard 14-day last-touch. Custom attribution is not competition-aware. Custom attribution includes both viewable and non-viewable impressions. Higher counts are expected, not a bug.

Can I SELECT user_id from conversions_with_relevance?

No. user_id carries the "Very high" aggregation threshold and cannot appear in the final SELECT on any analytics table in AMC. Use the conversions_with_relevance_for_audiences audience-table variant for any query that needs user-level output. It is the only AMC data source that permits SELECT user_id for audience materialization.

What does engagement_scope actually mean and where does it live?

engagement_scope distinguishes PROMOTED conversions (the actual ASIN tied to the campaign) from BRAND_HALO conversions (other ASINs from the same brand picked up by the ad's halo effect). It is null for pixel conversions. The column only exists on conversions_with_relevance — not on the plain conversions table.

Can I build a custom attribution model on amazon_attributed_events_by_conversion_time?

No. The amazon_attributed_events_* family is the standard-reporting source: competition-aware, 14-day last-touch, de-duped across campaigns. The attribution logic is baked in and cannot be unbaked. Use it when you need to reconcile with the numbers in the Amazon DSP or Sponsored Ads UI; never for custom modeling.

Why does my JOIN of sponsored_ads_traffic to conversions return zero rows?

Because conversions doesn't carry campaign columns. The JOIN needs conversions_with_relevance — the _with_relevance variant is the only custom-attribution surface that includes campaign and advertiser dimensions. The "Joining and Unioning Sponsored Ads Traffic with Conversions" IQ template demonstrates the correct pattern.

FAQ

What's the difference between `conversions` and `conversions_with_relevance`?

Both cover the same set of relevant conversions. `conversions_with_relevance` adds advertiser and campaign columns, which means a single conversion can appear on multiple rows — one per relevant campaign. Use `conversions` for de-duped volume questions. Use `conversions_with_relevance` for multi-touch credit splitting.

Why does my AMC custom-attribution query return more conversions than standard reports?

Three reasons. Custom attribution uses a 28-day ASIN relevancy window vs the standard 14-day last-touch. Custom attribution is not competition-aware. Custom attribution includes both viewable and non-viewable impressions. Higher counts are expected, not a bug.

Can I `SELECT user_id` from `conversions_with_relevance`?

No. `user_id` carries the 'Very high' aggregation threshold and cannot appear in the final SELECT on any analytics table. Use the `conversions_with_relevance_for_audiences` audience-table variant for any query that needs user-level output.

What does `engagement_scope` actually mean?

It distinguishes PROMOTED conversions (the actual ASIN tied to the campaign) from BRAND_HALO conversions (other ASINs from the same brand picked up by the ad's halo effect). It's null for pixel conversions. The column only exists on `conversions_with_relevance` — not on `conversions`.

Can I build a custom attribution model on `amazon_attributed_events_by_conversion_time`?

No. The `amazon_attributed_events_*` family is the standard-reporting source — competition-aware, 14-day last-touch, de-duped across campaigns. The attribution logic is baked in and you cannot unbake it. Use it when you need to reconcile with the numbers in the Amazon DSP or Sponsored Ads UI; never for custom modeling.

Why does my JOIN of `sponsored_ads_traffic` to `conversions` return zero rows?

Because `conversions` doesn't carry campaign columns. The JOIN needs `conversions_with_relevance` — the `_with_relevance` variant is the only custom-attribution surface that includes campaign and advertiser dimensions. The 'Joining and Unioning Sponsored Ads Traffic with Conversions' IQ demonstrates the correct pattern.

Sources