Amazon Ads
Send conversions to Amazon Ads (DSP, Sponsored Display and Streaming TV attribution) through the Amazon Ads Events API.
Why route Amazon Ads through Datafly Signal
- Conversions survive ad blockers and tracking prevention. Signal sends the event from your own infrastructure, so the conversions Amazon Ads optimises against are not filtered by the browser.
- Identifiers are hashed before they leave your infrastructure. Signal normalises and applies SHA-256 inside your own deployment, so Amazon Ads receives match keys, not raw personal data.
- One consent decision governs every destination. Amazon Ads is gated by the same consent state as the rest of your stack, so a withdrawal applies everywhere at once.
- Presets for Retail, Insurance and B2B / SaaS. The mapping starts from a working configuration for your vertical, and every field can be changed afterwards.
Prerequisites
- An Amazon Ads API application (Login with Amazon). Copy its Client ID and Client Secret.
- Authorise the application for a user with the
event_manager_editpermission and keep the refresh token. - Copy the Advertiser Account ID from Amazon Ads > Administration > Account access and settings, and pick the API host for its region.
- Optional: choose a Dataset Name to group the conversion definitions Amazon creates from your events.
Configuration
| Field | Type | Required | Description |
|---|---|---|---|
client_id | string | Yes | Your Amazon Ads API (Login with Amazon) client ID. Sent as the Amazon-Ads-ClientId header. |
client_secret | secret | Yes | Your Login with Amazon client secret, used to exchange the refresh token for an access token. |
refresh_token | secret | Yes | A long-lived Login with Amazon refresh token for a user with the event_manager_edit permission on the advertiser account. |
advertiser_id | string | Yes | The Amazon Ads advertiser account the events belong to (Amazon Ads > Administration > Account access and settings). Sent as the Amazon-Ads-AccountId header. |
region_host | select | Yes | The regional Amazon Ads API host for the marketplace your account belongs to. |
data_set_name | string | No | Optional. The Events Manager dataset the conversion definitions are grouped under; Amazon uses default_events when empty. Starts with a letter, then letters, digits, _ or -. |
default_country_code | string | No | ISO 3166-1 alpha-2 country sent when the event has no geo country. Amazon rejects an event without a country code, and for UK and EEA events requires a consent signal. |
profile_id | string | No | Not read by the Events API, which is addressed by advertiser account. Retained for existing integrations. |
region | string | No | Superseded by the API Host field. Retained for existing integrations. |
Configure in Signal
- In the Management UI, go to Integrations > Integration Library and select Amazon Ads.
- Choose a preset, fill in the fields above and choose the pipelines and consent categories (advertising destinations default to marketing).
- Click Install Integration.
Or with the Management API:
curl -X POST http://localhost:8084/v1/admin/integration-catalog/amazon_ads/install \
-H "Authorization: Bearer YOUR_TOKEN" -H "Content-Type: application/json" \
-d '{"name": "Amazon Ads", "variant": "default", "config": {"client_id": "amzn1.application-oa2-client...", "client_secret": "...", "refresh_token": "Atzr|...", "advertiser_id": "amzn1.ads-account.g.abc123", "region_host": "advertising-api.amazon.com"}, "delivery_mode": "server_side"}'API endpoint
POST https://{{region_host}}/adsApi/v1/create/eventsAuthentication: Login with Amazon Bearer token (refreshed from the refresh token), Amazon-Ads-ClientId and Amazon-Ads-AccountId headers. Allow egress to your region's Amazon Ads API host from the network your delivery workers run on.
Presets and event mapping
Every preset sends only the fields it maps (the strict output contract is on). Events not listed are not sent.
Retail (ecommerce)
Retail funnel for the Amazon Ads Events API: page and product views, search, add to cart, checkout and off-Amazon purchases with value, currency and the order ID as eventId for deduplication.
| Signal event | Amazon Ads event |
|---|---|
page | PAGE_VIEW |
search | SEARCH |
view_search_results | SEARCH |
view_item | PAGE_VIEW |
add_to_cart | ADD_TO_SHOPPING_CART |
begin_checkout | CHECKOUT |
purchase | OFF_AMAZON_PURCHASES |
sign_up | SIGN_UP |
generate_lead | LEAD |
Default (default)
Amazon Ads Events API core conversions (page views, search, add to cart, checkout, leads, sign-ups and purchases) with hashed email, phone and name match keys, the country code and Amazon consent signals.
| Signal event | Amazon Ads event |
|---|---|
page | PAGE_VIEW |
search | SEARCH |
add_to_cart | ADD_TO_SHOPPING_CART |
begin_checkout | CHECKOUT |
generate_lead | LEAD |
sign_up | SIGN_UP |
purchase | OFF_AMAZON_PURCHASES |
Insurance (insurance)
Insurance funnel: quote requests and leads as LEAD, contact requests as CONTACT, applications as APPLICATION and policy purchases as OFF_AMAZON_PURCHASES with premium value and the policy number as eventId.
| Signal event | Amazon Ads event |
|---|---|
page | PAGE_VIEW |
get_quote | LEAD |
quote_requested | LEAD |
generate_lead | LEAD |
lead_submitted | LEAD |
contact_requested | CONTACT |
begin_checkout | APPLICATION |
purchase | OFF_AMAZON_PURCHASES |
policy_purchased | OFF_AMAZON_PURCHASES |
sign_up | SIGN_UP |
B2B / SaaS (saas)
Lead and subscription funnel: leads and demo requests as LEAD, sign-ups and trials as SIGN_UP, paid subscriptions as SUBSCRIBE.
| Signal event | Amazon Ads event |
|---|---|
page | PAGE_VIEW |
generate_lead | LEAD |
demo_requested | LEAD |
sign_up | SIGN_UP |
trial_started | SIGN_UP |
subscription_started | SUBSCRIBE |
Identity and hashing
| Amazon Ads field | Signal source | Treatment |
|---|---|---|
matchKeys[] EMAIL | $traits.email | trim, lowercase, SHA-256 |
matchKeys[] PHONE | $traits.phone | digits with country code, SHA-256 |
matchKeys[] FIRST_NAME, LAST_NAME | $traits.first_name, last_name | trim, lowercase, SHA-256 |
matchKeys[] MAID | device advertising ID (apps) | lowercase, not hashed |
Email, phone and names come from datafly.identify() traits (a legacy properties.email / properties.phone is read when no trait is set). Raw personal data is never sent.
The Events API needs at least one match key per event, so an event with no email, phone, name or device advertising ID (an anonymous visitor) is not sent.
Deduplication and consent
eventId carries the Signal event ID, or the order ID on purchases. countryCode is required (the event’s geo country, else the Default Country Code) and UK and EEA events need a consent signal: Signal sends consent.amazonConsent from the visitor’s marketing consent. Events must be no more than seven days old.
Example: purchase (Default preset)
datafly.identify('crm-user-7', { email: 'jane.doe@example.com', phone: '07700 900123', first_name: 'Jane', last_name: 'Doe' });
datafly.track('purchase', {
transaction_id: 'T_1001', value: 139.99, currency: 'GBP',
items: [
{ item_id: 'SKU_1', item_name: 'Running Shoes', item_category: 'Footwear', item_brand: 'Acme', price: 120.00, quantity: 2 },
{ item_id: 'SKU_2', item_name: 'Gloves', price: 19.99, quantity: 1 }
]
});Request Signal sends (rendered from the preset):
{
"events": [
{
"consent": {
"amazonConsent": {
"amznAdStorage": "GRANTED",
"amznUserData": "GRANTED"
}
},
"countryCode": "GB",
"currencyCode": "GBP",
"eventDescription": {
"conversionType": "OFF_AMAZON_PURCHASES",
"dataSetName": "SignalEvents",
"eventIngestionMethod": "SERVER_TO_SERVER",
"eventSource": "WEBSITE",
"name": "purchase"
},
"eventId": "T_1001",
"eventTime": "2025-09-22T00:13:20.123Z",
"matchKeys": [
{
"type": "EMAIL",
"values": [
"86e0b9e56c17cc4d12387e1949b85053fbe73bc3ce5a1188713a9d300cc6133d"
]
},
{
"type": "PHONE",
"values": [
"033134b911b137918338415ee3d20a064b24773d36a3b02e8b99fdd3fcd6b4cd"
]
},
{
"type": "FIRST_NAME",
"values": [
"81f8f6dde88365f3928796ec7aa53f72820b06db8664f5fe76a7eb13e24546a2"
]
},
{
"type": "LAST_NAME",
"values": [
"799ef92a11af918e3fb741df42934f3b568ed2d93ac1df74f1b8d41a27932a6f"
]
}
],
"value": 139.99
}
]
}Known limitations
unitsSoldis not set (Amazon defaults it to 1) until a SUM expression exists (#1389).- Name hashing does not strip non-letters as Amazon’s tag does (#1390).
Troubleshooting
| Symptom | Cause | Resolution |
|---|---|---|
401 / 403 | Invalid, expired or under-privileged credential | Re-issue the credential described under Prerequisites and update the integration. |
400 | A field the vendor rejects | Open the event in the Delivery Log; the vendor’s message names the field. |
| Event dead-lettered with a required-field error | A value the vendor requires is missing (for example currency and value on a purchase) | Send the property in the track() call, or map it in the integration. |
| Low match rate | Few identifiers | Call datafly.identify() with email and phone when you know them, and keep click-ID capture enabled. |
Vendor reference: https://github.com/amzn/ads-events-api-gtm-tag.