Skip to content

Quickstart: Node SDK path

Serve ads from your own Node code with the typed SDK — you control exactly where ads appear. Time to first ad: about 5 minutes.

1. Get your fetch key

Advertising.chat is in private beta — request access if you don't have an account yet. Sign in to the Advertising.chat Console and copy your fetch key — new accounts get one automatically, shown on Get Started (also under API Keys, /admin). That is the only credential you need.

2. Install

npm install @advertising-chat/sdk

Node 18+ (native fetch), TypeScript types included, zero runtime dependencies.

3. Fetch an ad

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

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

const ad = await adchat.fetchAd<UniversalAdPayload>({
  subscriber: sessionId,        // anonymous id — enables frequency capping
  context: [                    // conversation context → relevant ads
    { role: 'user', text: 'What is a good gift for a coffee lover?' },
    { role: 'assistant', text: 'A quality burr grinder is a great pick.' },
  ],
});

if (!ad) {
  // No ad for this moment (204 no-fill). Continue without one.
  return;
}

console.log(ad.messageId);       // fetch id — use for event reporting
console.log(ad.payload.title);   // "Acme Coffee Grinder"
console.log(ad.payload.actions); // [{ text: 'Shop now', navigate: { url: 'https://...' } }]

context may be a string summary or an array of { role, text } turns. It is used to select this ad and is not retained as user history.

4. Render for your channel

The default (direqt) format is a universal card. Render helpers map it to common surfaces — always with the sponsorship disclosure:

import { renderWebchat, renderWhatsApp } from '@advertising-chat/sdk';

const web = renderWebchat(ad.payload);
// { text, imageUrl, buttons: [{ label, url, id }], disclosure: 'Sponsored' }

const wa = renderWhatsApp(ad.payload);
// WhatsApp Cloud API message object (interactive cta_url or image/text),
// footer "Sponsored" — send with your recipient: { ...wa, to }

Prefer channel-native payloads straight from the server? Pass format: 'sms' | 'fbm' | 'rcs-google' | 'rcs-gsma' | 'slack' | 'html' to fetchAd and forward ad.payload to your gateway.

5. Clicks and conversions

Action URLs in the payload are already click-tracking URLs — present them verbatim. When a user opens one, the click is recorded and they are 302-redirected to the advertiser. That's your first served ad and click, end to end.

Record other engagement explicitly:

// user acted on the ad outside a tracked link:
await adchat.recordEvent({ messageId: ad.messageId, type: 'click' });

// user completed the advertised action:
await adchat.recordConversion({
  messageId: ad.messageId,
  name: 'purchase',
  value: 19.99,
  currency: 'USD',
});

Both throw an AdChatApiError on failure; success is silent (HTTP 201).

Next