Skip to content

Events API

Every offer or ad that the Fetch API returns produces a stream of events: the fetch itself, message lifecycle notifications, taps on tracked links and replies, the customer's response to an offer, and conversions. Events drive the counts in the console's reports, and responses feed the subscriber history that rules read. This page describes the event types, how to report them, how conversions are tracked, and how responses are recorded.

How events are linked

Every event belongs to the org that owns the API key of the original fetch. An event is linked to the fetch that returned the offer or ad by the fetch identifier, the messageId in the fetch response. You pass that value as fetchEventId when you report an event, which ties deliveries, clicks, and conversions to a specific offer, rule, and moment.

An event can also carry the subscriber identifier from the fetch request, which counts unique reach and enforces frequency caps.

Event types

Event type Description How it is recorded
fetch An offer or ad was returned. Automatically, by the Fetch API.
send The message with the offer or ad was sent. Reported by your application.
deliver The message reached the customer's device. Reported by your application.
read The customer read the message. Reported by your application.
click The customer followed a tracked link. Automatically, by the click-tracking redirect, or reported by your application.
conversion The customer completed the tracked action, such as a booking or a purchase. Reported by your application, by a conversion pixel, or by an offline upload.
offer_accepted The customer accepted the offer. Reported by your application. See Responses to an offer.
offer_declined The customer turned the offer down. Reported by your application. See Responses to an offer.

Flow ads add six event types of their own.

Report an event

Send a POST with your API key, as the query parameter key or in the Authorization header:

POST https://ads.advertising.chat/v1/event
Content-Type: application/json

{
  "version": 2,
  "eventType": "deliver",
  "fetchEventId": "<messageId from the fetch response>",
  "timestamp": 1720000000000,
  "subscriber": "<opaque subscriber id>",
  "eventData": { }
}
Field Description
version Required. Must be 2.
eventType Required. One of send, deliver, read, click, conversion, offer_accepted, or offer_declined, or a flow event.
fetchEventId Required. The messageId from the fetch. An event that can't be linked to a fetch is rejected.
timestamp Optional. When the event happened, in Unix epoch milliseconds.
subscriber Optional. Used only if the fetch request had no subscriber.
eventData Optional. JSON to store with the event, available in the journal.

A 201 Created response confirms the event. An invalid eventType, eventData, or fetchEventId returns 422 Unprocessable Entity, as does an offer_accepted or offer_declined event that can't be resolved.

Click tracking

Links in returned offers and ads are click-tracking URLs, usually shortened on ads.chat. When the customer opens one, Advertising.chat records a click event and redirects to the original destination with a 302. Your application doesn't need to do anything to track these clicks.

Conversion tracking

Conversion pixel

To record conversions on a page that the customer reaches after a click, such as an order confirmation, embed this pixel:

GET https://ads.advertising.chat/v1/event?key=<your API key>&name=<activity>&value=<value>&cur=<currency>

The request returns a 1×1 transparent GIF. name identifies the activity, and value and cur optionally record its monetary value and currency. The pixel records a conversion on every load. When the customer reached the page through a tracked link in the past week, the conversion is attributed to that click.

Offline conversions

To upload a conversion that happened outside the conversation, such as at a front desk or in a call center, send:

POST https://ads.advertising.chat/v1/event/offlineConversion
Content-Type: application/json

{
  "messageId": "<messageId from the fetch response>",
  "eventData": { }
}

A 200 response confirms the upload.

A conversion attributed to a fetch also records converted in the customer's subscriber history. See Conversions.

Responses to an offer

A response is how a customer answered an offer: accepted, declined, or converted. Responses are recorded in the customer's subscriber history, where rules read them, for example to stop showing an offer to anyone who turned it down in the last 30 days. A response is recorded in one of three ways:

  • Your agent reports a tap on a reply that has a role, to /v1/interact.
  • Your application reports an offer_accepted or offer_declined event, to /v1/event.
  • A conversion is attributed to the fetch.

Each response names the fetch it answers by its fetch identifier. The fetch is looked up in your org's fetch journal, which keeps fetches for seven days, and resolves to the fetch's agent, subscriber, rule, and offer. A fetch that is older than seven days or that had no subscriber can't be resolved, and no response is recorded for it.

Silence is not a decline. A customer who doesn't answer an offer has no declined event, so a rule that excludes decliners keeps showing the offer to them.

Reply roles

A reply role says what tapping one of an offer's replies means. Each entry of a creative's actions can carry a role:

role A tap records
accept accepted, for the offer and the rule that served it.
decline declined, for the offer and the rule that served it. Use it on a reply such as "Not now".
Absent Nothing in subscriber history. The tap is recorded as an interaction only.

Each action in a rendered offer has an action ID, <offer shortid>-<index>, where index is the action's position in the creative's actions, starting at 0. Its postback data is <messageId>_<actionId>: the fetch identifier, an underscore, and the action ID. In the RCS formats, the postback data is the suggestion's postback data, which the RCS platform returns to your agent when the customer taps it. In the fbm format, it is the quick reply's payload, which Messenger returns as message.quick_reply.payload. In the direqt format, each action carries it as context, with the action ID in actionId.

Report a reply tap

When the customer taps a reply, send its postback data unchanged:

POST https://ads.advertising.chat/v1/interact?key=YOUR_API_KEY&postbackData=<postback data>

postbackData is a query parameter, URL-encoded. The response is a 200 with this body:

{ "actionId": "Xk2a9-1", "role": "decline", "recorded": "declined" }
Field Description
actionId The action ID from the postback data.
role The tapped reply's role, when it has one.
recorded The response recorded in subscriber history, accepted or declined. Absent when the reply has no role, when the fetch can't be resolved, when that fetch didn't serve the offer, or when the same reply was already recorded for that fetch.

Postback data that isn't <messageId>_<actionId> returns 422.

A reply that opens a web page (actionType: "Navigate") links through the click redirect, https://ads.advertising.chat/v1/click, and the link carries the reply's postback data. When the customer follows the link, the reply's role is recorded as it is for a reported tap, so your agent doesn't need to report it on /v1/interact. A reply's role is recorded once per fetch, however often the link is followed or the tap reported. Link previews that messaging apps and crawlers fetch record nothing.

Report an accept or a decline

When your agent learns the customer's answer some other way, such as from a free-text reply, report it as an event against the fetch. The event takes either of two bodies. The version 2 body:

POST https://ads.advertising.chat/v1/event?key=YOUR_API_KEY
Content-Type: application/json

{
  "version": 2,
  "eventType": "offer_declined",
  "fetchEventId": "<messageId from the fetch response>",
  "eventData": { "offer": "<creative ID>" }
}

It returns 201 when the response is recorded, and 422 with no body when it isn't.

The event-name body:

POST https://ads.advertising.chat/v1/event?key=YOUR_API_KEY
Content-Type: application/json

{
  "messageId": "<messageId from the fetch response>",
  "eventName": "offer_declined",
  "eventData": { "offer": "<creative ID>" }
}

It returns 200 with { "eventId": "<id>", "recorded": "declined" } when the response is recorded. When it isn't, it returns 422 with a message and a reason:

reason Meaning
unknown-message The fetch identifier is invalid, isn't a fetch of your org, or is older than seven days.
no-subscriber The fetch had no subscriber.
no-offer The fetch served no offer, or eventData.offer isn't a valid ID.
unknown-offer eventData.offer isn't an offer that the fetch served.

In both bodies, eventData.offer is optional. It picks one of the offers the fetch served, and defaults to the first.

Conversions

A conversion attributed to a fetch records converted for the fetch's offer and rule. That covers each conversion event reported to /v1/event, and the first conversion that the conversion pixel or an offline upload attributes to a fetch. A conversion whose fetch can't be resolved is still recorded as an event.

Subscriber history

Subscriber history is the record of one customer's offer events, kept for each subscriber identifier within each agent. An agent's rules read only that agent's history. A request without a subscriber has no history.

Event Recorded for When
shown The moment, the rule, and the offer A fetch with a subscriber returns an offer. Test requests aren't recorded. For an exchange rule, only the moment and the rule.
accepted, declined The offer and the rule that served it A reply tap with a role, or an offer_accepted or offer_declined event.
converted The offer and the rule that served it A conversion attributed to the fetch.

For each moment, rule, or offer and each event type, history keeps the 20 most recent events, and none older than 95 days. A customer's history expires 95 days after its last event.

Three parts of serving read it:

  • Frequency caps on moments, rules, and offers count shown events. See Frequency.
  • History conditions in a rule's audience and exclusions count events of any type. See History conditions.
  • A rule that shows its offers in turn (Show them in turn, in this order) keeps each customer's place in its offers.

Because history keeps 20 events per type, a frequency cap allows at most 20 serves, and a history condition requires at most 20 events. Their windows are at most 90 days, inside the 95 days that history keeps.