Skip to content

Request an offer

Your agent requests an offer when a conversation reaches a moment. Offer Manager evaluates the moment's rules and returns zero or one offer, rendered for the channel. This document describes how to make the request with the Fetch API, handle the response, and report what happens to the offer. To set up the moment and its offers, see Create a moment.

The example on this page is the resort concierge agent from Moments, offers, and rules, which offers guests a spa booking after they check in.

Before you begin

  • Create a moment and an enabled rule with at least one offer.
  • Get an API key. In the console, open the account menu and click API Keys. The page lists your org's keys, and Create API Key creates a new one. Only admins and owners see this page.
  • Get the ID of the agent the moment belongs to. A key from API Keys belongs to the whole org, so each request names its agent in the application parameter. A fetch key bound to the agent makes the parameter unnecessary. See Authentication.
  • Keep the key on your server. Send requests from your agent's backend, not from a customer's device.

Choose the render format

The format parameter sets how the offer is rendered. Choose the format for the channel the conversation is on:

Channel format What you receive
RCS for Business, through Google rcs-google A rich card with suggested actions, ready to send.
RCS, through a GSMA Universal Profile provider rcs-gsma A rich card in the GSMA message format.
Facebook Messenger fbm A generic template, with the offer's replies as quick replies.
SMS sms Text followed by the offer's link.
Webchat direqt A card as JSON (title, subtitle, image, actions) for your webchat to draw. This is the default.

For every format, see Render formats. When a conversation moves from RCS to SMS, request the same moment with format=sms. The rules and offers stay the same.

Name the channel

Rules can be limited to channels, such as RCS only, and a rule limited to channels matches only requests whose channel is known. The sms, rcs-google, rcs-gsma, and fbm formats name their channel (fbm names messenger). For every other format, send the channel in the channel parameter: rcs, sms, webchat, messenger, or voice. A webchat request in the default format, for example, sends channel=webchat.

A request that names no channel still matches rules with no channel limit, but never a rule limited to channels. The console's Attributes page shows how many of each moment's requests named no channel. See Channels.

Request the offer

Send a POST to the Fetch API with the agent's ID in application and the moment's code in adUnit:

curl -X POST "https://ads.advertising.chat/v1/fetch/v2?key=YOUR_API_KEY&application=YOUR_AGENT_ID&adUnit=after-check-in&format=rcs-google" \
  -H "Content-Type: application/json" \
  -d '{
    "subscriber": "guest-8f2c1d",
    "attributes": { "tier": "gold", "checkInDate": "2026-11-02" },
    "context": "Guest just checked in and asked what time the pool opens."
  }'

The request body carries the following:

  • subscriber: an opaque identifier for the customer. It enforces frequency caps and the Show them in turn, in this order selection. Never use a phone number or email address.
  • attributes: the keys and values your rules' audiences and exclusions compare. See Rule conditions.
  • context: optional, a short summary of the conversation. It improves the fit of the offer and lets the appropriateness check withhold offers in sensitive moments. It is not stored.

Handle the response

A 200 response contains the offer:

{
  "messageId": "direqt-6a3f…",
  "format": "rcs-google",
  "payload": { "contentMessage": { "richCard": { "…": "…" } } },
  "properties": { "bookingType": "spa" },
  "isTest": false
}
  1. Send payload to the customer through your messaging platform without changing it. Its links are click-tracking URLs, so taps are recorded automatically.
  2. Keep messageId. You use it to report what happens to the offer.
  3. Read properties for the offer's custom properties.
  4. If isTest is true, the rule is in test mode. Don't send the offer to a customer.

A 204 response means no offer fits this moment. Continue the conversation without one. This is the most common response, and your agent must handle it.

Report what happens

Report events for the offer with the messageId from the response, passed as fetchEventId:

curl -X POST "https://ads.advertising.chat/v1/event?key=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"version": 2, "eventType": "deliver", "fetchEventId": "direqt-6a3f…"}'

Report send, deliver, and read as your messaging platform confirms them, and conversion when the customer completes the offer, such as booking the spa. For conversions that happen outside the conversation, such as on a booking page, see Conversion tracking.

Report reply taps

An offer's replies, such as "Book it" and "Not now", come back to your agent as the customer's next message, carrying the reply's postback data. Google's RCS platform returns it as suggestionResponse.postbackData, and Messenger as message.quick_reply.payload. Send it to the Interact API unchanged:

curl -X POST "https://ads.advertising.chat/v1/interact?key=YOUR_API_KEY&postbackData=direqt-6a3f…_Xk2a9-1"

With the Node SDK, call recordInteraction:

import { AdChat, isAdPostbackData } from '@advertising-chat/sdk';

const adchat = new AdChat({ apiKey: process.env.ADCHAT_API_KEY! });

// In your RCS webhook, for each message from the customer:
const postbackData = message.suggestionResponse?.postbackData;
if (isAdPostbackData(postbackData)) {
  const { recorded } = await adchat.recordInteraction(postbackData);
  // recorded is 'accepted' or 'declined' for a reply with a role.
}

For Messenger, messengerPostbackData(event) reads the postback data from a webhook messaging event. A reply with an accept or decline role records the customer's response, which rules can use, for example to stop offering the spa to a guest who said "Not now". Your agent's own replies carry their own payloads, so report only an offer's, which isAdPostbackData recognizes.

Check why an offer did or didn't appear

To see the reasoning for a request, add test=1. A test request isn't counted in reports, and its response lists why each rule was disqualified. To get the reason for an empty response without a test, add debug=1. See Request parameters.

What's next