> For the complete documentation index, see [llms.txt](https://docs.chord.co/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.chord.co/activate/event-streaming/destinations/advertising/amazon-conversions-api.md).

# Amazon Conversions API

The **Amazon Conversions API** destination sends off-Amazon conversion events to [Amazon Ads](https://advertising.amazon.com/) using the server-side [Events API](https://advertising.amazon.com/API/docs/en-us/amazon-ads/1-0/betas#tag/Events/operation/CreateEvent), so purchases, sign-ups and other conversions that happen on your storefront can be attributed to — and optimized against — Amazon Ads campaigns.

This is a **server destination only**, which is how Amazon intends the Conversions API to be used: it exists for server-side and offline conversions, while browser-side measurement belongs to the Amazon Ad Tag (AAT) pixel on your storefront. Sending the same conversion through both surfaces without deduplication will double-count it.

This destination is built to match the Segment **Amazon Conversions Api** destination: the same conversion types, the same normalization and SHA-256 hashing of match keys, and `messageId` as the deduplication id. The Chord tracking-plan event names are mapped alongside Segment's, so a migration needs no per-event configuration.

## Getting started

Amazon Ads authenticates with **Login with Amazon (LWA)**. Chord cannot run an interactive OAuth flow inside a destination, so you supply the credentials of an LWA application that is already authorized for your advertiser account.

Before you connect, get these from Amazon:

* Your advertiser account ID. Use the Amazon DSP CFID, **not** the Entity ID.
* An LWA client ID and client secret, from the Amazon Ads API section of the [Amazon developer console](https://advertising.amazon.com/API/docs/en-us/guides/onboarding/create-lwa-app).
* An LWA refresh token, issued when your application was authorized for the advertiser account.
* The marketplace region of the advertiser account. Events sent to the wrong region are rejected.

Amazon supports **Self-Service accounts only** for this API. Managed Service and Manager accounts are not supported.

## Settings

* **Destination Name** (required): a name to tell this destination apart.
* **Region** (optional): `NA`, `EU` or `FE`, matching the marketplace region of your advertiser account. Defaults to North America (NA). The EU region needs a consent signal on every event.
* **Amazon Advertiser ID** (required): your numeric advertiser account ID, sent as the `Amazon-Ads-AccountId` header. Use the Amazon DSP CFID, not the Entity ID.
* **LWA Client ID** (required), **LWA Client Secret** (required) and **LWA Refresh Token** (required): the credentials of your Login with Amazon application, authorized for your advertiser account. Chord exchanges the refresh token for a one-hour access token and caches it until it expires. Chord never logs the refresh token.
* **Dataset Name** (optional): the dataset events are grouped into in Amazon Ads Data Manager. It must start with a letter, use only letters, numbers, underscores or hyphens, and be 5 to 100 characters. Defaults to `Default_Events`. Set it during setup, because changing it later creates new conversion definitions.
* **Event Action Source** (optional): where events come from: Website, Android, iOS, Fire TV or Offline. Defaults to Website. Treat it as fixed once events are flowing.
* **Default Country Code** (optional): the last-resort country for events with no locale or geo data. Defaults to `US`.
* **Send Page Events** (optional): send `page` events as the `PAGE_VIEW` conversion type. On by default.
* **Forward Unmapped Events as OTHER** (optional): send events with no mapping under their own name as `OTHER`. On by default. Turn it off to send only mapped events.
* **Limited Data Use** (optional): mark every event `LIMITED_DATA_USE`. Amazon does not use these events for measurement or optimization. Off by default.
* **Custom Event Mapping** (optional): sends a Chord event under a different Amazon conversion type, for example `Subscription Renewed` to `OFF_AMAZON_PURCHASES`.
* **Consent Requirements** (optional): the consent categories a visitor must accept before Chord sends data to this destination. See [Consent](/activate/event-streaming/consent.md).

## Connect

Add **Amazon Conversions API** from the destination catalog, using the settings above. See [Connect a destination](/activate/event-streaming/connect-a-destination.md) for the full steps.

## Datasets

Amazon Ads groups uploaded events into **datasets**, which is how they appear in Amazon Ads Data Manager. Leaving **Dataset Name** empty puts everything in Amazon's `Default_Events` dataset.

Set the dataset name during initial setup. A dataset name must start with a letter, contain only letters, numbers, underscores or hyphens, and be 5–100 characters long. **Changing it on a live destination creates new conversion definitions in Amazon**, splitting your reporting history — treat it as immutable once events are flowing.

## Event mapping

Amazon has a closed set of twelve conversion types. Chord maps its canonical event names onto them, using the same event names as the Segment destination plus the Chord tracking-plan aliases for the same actions:

| Chord event                                                                         | Amazon event             | Notes |
| ----------------------------------------------------------------------------------- | ------------------------ | ----- |
| [`Product Added`](/collect-data/tracking-plan/product-added.md)                     | `ADD_TO_SHOPPING_CART`   |       |
| `Application Submitted`                                                             | `APPLICATION`            |       |
| [`Checkout Started`](/collect-data/tracking-plan/checkout-started.md)               | `CHECKOUT`               |       |
| `Callback Started`                                                                  | `CONTACT`                |       |
| `Lead Generated`                                                                    | `LEAD`                   |       |
| [`Order Completed`](/collect-data/tracking-plan/order-completed.md), `Order Placed` | `OFF_AMAZON_PURCHASES`   |       |
| `Application Opened`                                                                | `MOBILE_APP_FIRST_START` |       |
| `page` events, `Page Viewed`                                                        | `PAGE_VIEW`              |       |
| [`Products Searched`](/collect-data/tracking-plan/products-searched.md)             | `SEARCH`                 |       |
| [`Signed Up`](/collect-data/tracking-plan/signed-up.md), `Account Created`          | `SIGN_UP`                |       |
| [`Subscription Created`](/collect-data/tracking-plan/subscription-created.md)       | `SUBSCRIBE`              |       |
| Any other track event                                                               | `OTHER`                  |       |

`identify`, `group` and other event types are skipped with an explicit log line.

### Custom events

`OTHER` is a conversion type Amazon defines for "customer actions that don't fit the definition of the standard event types", so this destination is **passthrough-capable**: an event with no mapping is forwarded under its own name as `OTHER` rather than dropped. Turn **Forward Unmapped Events as OTHER** off to send only the mapped conversion events — skipped events are logged explicitly either way. See [Custom events](/collect-data/everyone-else/sdk-reference/custom-events.md).

### Overriding the mapping

Use **Custom Event Mapping** to send a specific event under a different conversion type, e.g. `Subscription Renewed` → `OFF_AMAZON_PURCHASES`. Only the twelve types above are valid; an event mapped to anything else is skipped with a log line rather than guessed at.

{% hint style="warning" %}
**A conversion definition in Amazon Ads is identified by the event name, conversion type and event source together.** Renaming events, changing **Event Action Source**, or remapping conversion types all create new definitions in Amazon. Settle these before you start sending production traffic.
{% endhint %}

## Identity (match keys)

Amazon requires **at least one match key** per event, and every PII match key must be normalized and SHA-256 hashed. Chord does both before the request leaves the platform — plaintext PII is never sent. A value that already looks like a SHA-256 digest is passed through rather than hashed twice.

| Chord source (priority order)                                                                     | Amazon field | Notes                                                                                            |
| ------------------------------------------------------------------------------------------------- | ------------ | ------------------------------------------------------------------------------------------------ |
| `properties.email` > `context.traits.email`                                                       | `EMAIL`      | Normalization before hashing: Lowercase; keep alphanumerics plus `.`, `@`, `+`, `-`              |
| `properties.phone` / `phone_number` > traits                                                      | `PHONE`      | Normalization before hashing: Digits only                                                        |
| `properties.firstName` / `first_name` > traits                                                    | `FIRST_NAME` | Normalization before hashing: Lowercase alphanumerics only                                       |
| `properties.lastName` / `last_name` > traits                                                      | `LAST_NAME`  | Normalization before hashing: Lowercase alphanumerics only                                       |
| `traits.address.street` / `address1` > `properties.street` / `address1`                           | `ADDRESS`    | Normalization before hashing: Lowercase alphanumerics only                                       |
| `traits.address.city` > `properties.city` > `properties.shipping_city`                            | `CITY`       | Normalization before hashing: Lowercase alphanumerics only                                       |
| `traits.address.state` / `region` > `properties.state` > `properties.shipping_state`              | `STATE`      | Normalization before hashing: Lowercase alphanumerics only                                       |
| `traits.address.postalCode` / `zipcode` > `properties.postalCode` > `properties.shipping_zipcode` | `POSTAL`     | Normalization before hashing: Lowercase, whitespace removed (punctuation kept for UK/CA formats) |
| `context.device.advertisingId` / `idfa` / `adid`                                                  | `MAID`       | Normalization before hashing: Sent in the clear                                                  |
| `properties.rampId` > traits > `context.clientIds.rampId`                                         | `RAMP_ID`    | Normalization before hashing: Sent in the clear                                                  |
| `properties.matchId` / `match_id` > traits > `context.clientIds.matchId`                          | `MATCH_ID`   | Normalization before hashing: Sent in the clear                                                  |

"Lowercase alphanumerics only" means ASCII: `José` is hashed as `jos`. This matches the Segment destination; we have not been able to confirm it against Amazon's own guideline, which requires an Amazon Ads login to read. The same applies to email: the guideline as Segment quotes it keeps only `.`, `@` and `-`, but Segment's code — and ours — also keeps `+`.

Identifiers sent as numbers (a zip of `94107`, a phone of `14155550132`) are treated as their string form. Values that carry no matching signal are **dropped rather than hashed**: placeholders like `n/a`, `unknown` or `test`, an email without an `@`, and phone numbers with fewer than 7 digits or all one digit. A hash of `n/a` is the same for every brand that sends it, so it would match unrelated customers.

An event that carries **no** usable identifier cannot be attributed, so it fails with a non-retryable error rather than being sent and silently discarded by Amazon.

**Match ID** deserves a note: it is an opaque identifier of your own (a loyalty ID, an order reference) that Amazon correlates to users via the Amazon Ad Tag. If your storefront passes `match_id` to AAT, sending the same value here links offline and server-side conversions to the same customer journey without sharing hashed PII.

## Event fields

| Chord source (priority order)                                                                                                | Amazon field                            | Notes                                                                                                   |
| ---------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| `event` (page: `name` > `context.page.title` > `Page View`)                                                                  | `eventDescription.name`                 | Sent verbatim                                                                                           |
| See [Event mapping](#event-mapping)                                                                                          | `eventDescription.conversionType`       |                                                                                                         |
| **Event Action Source** setting, else `context.device.type`                                                                  | `eventDescription.eventSource`          | Uppercased. Device types Amazon does not accept (`mobile`, `desktop`) fall back to `WEBSITE`            |
| *(hardcoded)* `SERVER_TO_SERVER`                                                                                             | `eventDescription.eventIngestionMethod` | Required by Amazon for Conversions API events                                                           |
| `properties.country` > `properties.shipping_country` > `context.locale` > `context.geo` > address > **Default Country Code** | `countryCode`                           | Locale forms (`en-US`, `pt_BR`) are reduced to the region subtag                                        |
| `timestamp`, else `receivedAt`                                                                                               | `eventTime`                             | ISO 8601                                                                                                |
| `messageId`                                                                                                                  | `eventId`                               | Amazon's `clientDedupeId` — see [Deduplication](#deduplication)                                         |
| `properties.value` > `revenue` > `total` > `price`                                                                           | `value`                                 | Sent for every conversion type                                                                          |
| `properties.currency` > `properties.meta.i18n.currency`                                                                      | `currencyCode`                          | `OFF_AMAZON_PURCHASES` only. Currencies outside Amazon's accepted list are omitted rather than rejected |
| `properties.quantity`, else the sum of `products[].quantity`                                                                 | `unitsSold`                             | `OFF_AMAZON_PURCHASES` only. Omitted when unknown — Amazon then defaults it to 1                        |
| `brand`, `category`, `productId` + custom-mapped properties                                                                  | `customData`                            | See [Custom attributes](#custom-attributes)                                                             |
| See [Consent](#consent)                                                                                                      | `consent`                               |                                                                                                         |
| **Limited Data Use** setting or `properties.dataProcessingOptions`                                                           | `dataProcessingOptions`                 |                                                                                                         |

### Country code

Amazon requires an ISO 3166-1 alpha-2 country code on **every** event. Browser events usually carry `context.locale` or geo data; back-end events (Shopify webhooks, server-to-server ingest) often carry neither, which is what the **Default Country Code** setting is for — it defaults to `US`. Clear it if you would rather such events fail loudly than be attributed to the wrong country.

### Custom attributes

Amazon's `customData` is a list of name/value pairs. Names accept letters, numbers and underscores; values are strings capped at 256 characters. Chord sends:

* `brand`, `category` and `productId`, resolved from the event's top-level properties and falling back to the first entry of `products[]`. These are the attributes Amazon uses for reporting, alongside `attr1`–`attr10`.
* Any property you have configured as a `properties.*` destination mapping in Chord, promoted into `customData` automatically. Names are sanitized (`gift-note` → `gift_note`) and nested values are JSON-stringified rather than dropped.

PII fields (email, phone, first/last name) are **never** promoted as plain custom attributes — they only ever leave as hashed match keys.

### Consent

| Chord source (priority order)                                                                                  | Amazon field                                           | Notes |
| -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | ----- |
| `context.ip`                                                                                                   | `consent.geo.ipAddress`                                |       |
| `properties.amznUserData` / `amznAdStorage`, or `context.consent.*` — `GRANTED` / `DENIED` (booleans accepted) | `consent.amazonConsent.amznUserData` / `amznAdStorage` |       |
| `properties.tcf` > `context.consent.tcf`                                                                       | `consent.tcf`                                          |       |
| `properties.gpp` > `context.consent.gpp`                                                                       | `consent.gpp`                                          |       |

**In the EU region, Amazon requires at least one of these signals on every event.** An EU-region event carrying none fails with a non-retryable error instead of being sent and rejected. In practice `context.ip` satisfies this for browser-originated events; back-end events need an explicit consent property.

### Limited data use

Enabling **Limited Data Use** stamps every event with Amazon's `LIMITED_DATA_USE` data-processing option. Amazon does **not** process events marked this way for measurement or optimization, so enable it only where a privacy regime requires it. Individual events can opt in on their own by sending a `dataProcessingOptions` property containing `LIMITED_DATA_USE`.

## Deduplication

`messageId` is sent as Amazon's `clientDedupeId`. For events sharing a dedupe id Amazon processes only the most recent one, which makes pipeline retries and replays safe.

Note that Amazon deduplicates **across all event types**, not per event type — two different conversions must not share a `messageId`.

## Error handling

| Condition                                                            | Behavior                                                                                              |
| -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| 5xx or 429 from Amazon                                               | Retried                                                                                               |
| 401                                                                  | The cached access token is discarded and the event retried with a freshly minted one                  |
| 403                                                                  | Not retried — the LWA application is not authorized for this advertiser, which a new token cannot fix |
| Other 4xx                                                            | Not retried — a malformed event will not become valid on a resend                                     |
| `207` with a per-event `error` entry                                 | Treated as a failure, with Amazon's own error message. A 207 whose events all succeeded passes        |
| Missing match key, missing country code, missing EU consent          | Not retried; the log line names the missing piece                                                     |
| LWA credentials rejected (`400`/`401` at the token endpoint)         | Not retried — the Client ID, Secret or Refresh Token needs fixing                                     |
| Non-numeric Advertiser ID, or a Dataset Name outside Amazon's format | Not retried, and no request is made. The console form flags both when the destination is saved        |

The access-token request is deliberately excluded from Live Events logging: it carries the client secret and refresh token in its body and returns the access token in its response.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.chord.co/activate/event-streaming/destinations/advertising/amazon-conversions-api.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
