> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aiderx.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Ad Event and Log Integration

> Use the ad tracking identifier from an ad response to record impressions, clicks, and conversions and measure performance.

This page covers recording impressions, clicks, and conversions with the ad tracking identifier (`ext.ad_log`) from an ad response, without an SDK. These ad events let you measure ad performance. For requesting and rendering ads, see [Ad Serving Integration](https://docs.aiderx.io/development/en/serving-ad.md).

User activity logs, such as product views and purchases, are used for recommendations that reflect user activity. These logs are sent separately from ad events; see [Product and Content Data Integration](https://docs.aiderx.io/development/en/catalog.md) for how to connect them.

## Understand ad events

Ad events connect an ad response to user interactions and target actions.

| Event | Meaning |
| - | - |
| Impression | The number of times an ad is recorded as shown according to the configured impression tracking mode |
| Click | The number of times a user clicks an ad |
| Conversion | The number of completed target actions, such as a purchase or signup, that are recorded as conversions |

## Store the ad tracking identifier

When an ad request returns an ad, the response includes an ad tracking identifier in the top-level `ext.ad_log`. For the complete response specification, see the [ad request API](https://docs.aiderx.io/en/0.5.0/decision/ad-serving/serving-an-ad.md).

```json Response (excerpt) theme={null}
{
  "ad": {
    "id": "7c4f2b18-e9a6-4d3f-b821-56a09c73e4fd"
  },
  "ext": {
    "message": "success",
    "ad_log": "<ad tracking identifier returned by A2>"
  }
}
```

`ad_log` is an identifier issued for each ad response that connects events to that response. Store `ad` and `ext.ad_log` together when processing the response. If a server requested the ad, pass both values to the client.

For a click, use the `ad_log` from the selected ad's response. If a conversion occurs later, store the same value with the user session or order and use it when the conversion is confirmed.

## Send events

### Impression

Depending on the mode configured for the assignment, an impression is recorded when A2 returns the ad or when the client calls the impression tracking URL.

| Impression Tracking Mode | When it counts as an impression | Client implementation |
| - | - | - |
| **On Ad Response** (default) | When A2 returns the ad | No additional implementation |
| **On Impression Event** | When the ad appears on screen and the client calls the tracking URL | Call the impression tracking URL from the response |

Choose the tracking mode in the assignment's **Delivery Settings**. In Ad Manager, select a line item under **AdOps > Line Items**, then add or edit an assignment from the **Inventory Assignment** tab.

If you select **On Impression Event**, A2 adds an impression tracking URL to the ad response. Where the URL appears depends on the creative type.

| Creative type | Impression tracking URL location |
| - | - |
| Image banner | `url` in `ad.display.event[]` |
| Native | `url` of the entries in `ad.display.native.eventtrackers[]` whose `event` is `1` and `method` is `1` |

```json Image banner theme={null}
{
  "ad": {
    "display": {
      "banner": {
        "img": "https://cdn.example.com/banner.jpg"
      },
      "event": [
        { "url": "<impression tracking URL>" }
      ]
    }
  }
}
```

```json Native theme={null}
{
  "ad": {
    "display": {
      "native": {
        "eventtrackers": [
          { "event": 1, "method": 1, "url": "<impression tracking URL>" }
        ]
      }
    }
  }
}
```

A native `eventtrackers` array can also include other tracking URLs registered with the creative. Call every URL that matches the condition.

Run the following code once after the ad has been displayed.

```javascript theme={null}
function getImpressionUrls(ad) {
  const native = ad?.display?.native;
  if (native) {
    return (native.eventtrackers ?? [])
      .filter((tracker) => tracker.event === 1 && tracker.method === 1 && tracker.url)
      .map((tracker) => tracker.url);
  }
  return (ad?.display?.event ?? []).map((event) => event.url).filter(Boolean);
}

getImpressionUrls(response.ad).forEach((url) => {
  new Image(1, 1).src = url;
});
```

A successful call returns `200` with a 1×1 image.

> [accordion] When the response has no impression tracking URL
>
> Video creatives and some external ad network ads do not include an impression tracking URL. Use **On Ad Response** when you assign these ads. If you select **On Impression Event**, their impressions aren't counted.

> [accordion] When you receive native ads as HTML
>
> Even when you receive a native ad as HTML markup (`ad.display.adm`), the impression tracking URLs are included in `ad.display.native.eventtrackers`. Check whether the HTML of the native style applied to the ad unit calls the impression tracking URLs itself. If it doesn't, call them with the code above. Calling them from both places counts the impression twice.

> [accordion] Do I need to send vimp separately?
>
> For the basic ad integration, do not send `vimp` separately. Ad impressions are recorded as `imp` according to the Impression Tracking Mode selected above. The Log API accepts `vimp`, but current ad performance aggregation does not use it as the standard impression count. For recommendation view events, see the recommendation integration documentation.

### Click

When a user clicks an ad, send `action` as `clk` to the [Record User Log API](https://docs.aiderx.io/en/0.5.0/decision/ad-log/record-user-log.md). Set `ad_log` to the `ext.ad_log` from the clicked ad's response.

```bash theme={null}
curl -X POST "https://your_a2_service/dmp/v0/log" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "ad_log",
    "action": "clk",
    "ad_log": "<ext.ad_log of the clicked ad>"
  }'
```

On the web, start sending the click event before opening the landing page. You can use the Fetch API's `keepalive` option to let the request continue while the page navigates away.

> [accordion] When you render HTML creatives in an iframe
>
> Clicks inside an iframe do not reach the parent document's click handler. Rendering the HTML creative and opening its landing page alone does not automatically record an A2 `clk` event.
>
> With direct API integration, the parent document needs to receive a click notification from the creative or ad provider and call the click API above with that ad response's `ext.ad_log`. If you use `postMessage` notifications, verify the sending iframe and origin before handling the message. If the creative does not provide click notifications, confirm a way to connect them with the provider.
>
> When the Web SDK renders a native HTML creative, the native style HTML must also send `parent.postMessage({ type: "ad-clicked", id: iframeId }, "*")` on click for the SDK to send `clk`. `iframeId` must match the ID of the iframe connected by the SDK. This message is the SDK's click connection mechanism; without the SDK, you must implement the parent document's message listener and click API call yourself. Sending a click separately when the SDK already sends it can count the click twice.

### Conversion

When a conversion defined by the service, such as a purchase or signup, is confirmed, send `action` as `conv` to the same API. Set `ad_log` to the value stored with the user session or order.

```bash theme={null}
curl -X POST "https://your_a2_service/dmp/v0/log" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "ad_log",
    "action": "conv",
    "ad_log": "<stored ext.ad_log>"
  }'
```

## Important delivery notes

* Modifying or creating `ad_log` can prevent the event from being linked to its original ad response, causing it to be omitted or attributed incorrectly. The impression tracking URL is signed, so use the URL exactly as returned.
* Sending the same impression tracking URL or the same click or conversion event more than once can count it as a separate event.

For checking whether events appear in reports, see [Integration Verification and Troubleshooting](https://docs.aiderx.io/development/en/integration-verification-and-troubleshooting.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.