HTTPS
Overview
Section titled “Overview”This document explains two ways to send chat messages to Growl:
- Frontend Recording (Recommended): Use
window.GrowlAds.recordMessage()directly from your frontend - simplest and most convenient - Backend-to-Backend: Forward messages from your backend to Growl’s
/v1/messages/endpoint - useful when you need more control or already have backend infrastructure
Both methods receive user conversation data, user agent information, request headers, and other relevant metadata for contextual ad targeting.
Backend-to-Backend Tracking
Section titled “Backend-to-Backend Tracking”If you prefer to track messages from your backend, use the /v1/messages/ endpoint.
Getting Visitor ID
Section titled “Getting Visitor ID”Step 1: Get Visitor ID on Client-Side
Section titled “Step 1: Get Visitor ID on Client-Side”On your frontend, call the async getVisitorId() method exposed by the Growl Ads script:
// Get the visitor ID (returns a Promise)const visitorId = await window.GrowlAds.getVisitorId();Step 2: Send Visitor ID to Your Backend
Section titled “Step 2: Send Visitor ID to Your Backend”Include the visitor_id in your chat request to your backend:
// Example: sending a chat message with visitor IDconst response = await fetch("/api/chat", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ chat_id: "chat_123", user_id: "<user_id>" message: "Hello!", visitor_id: visitorId, // Required - must be included so that it can be forwarded from your backend to Growl }),});Step 3: Forward Visitor ID to Growl
Section titled “Step 3: Forward Visitor ID to Growl”In your backend, include the visitor_id when calling the Growl messages API. See the API Reference and examples below.
API reference
Section titled “API reference”POST https://api.withgrowl.com/v1/messages/
Request Body
Section titled “Request Body”Send a JSON body with these fields:
{ publisher_id: string; // Contact Growl team for publisher-id visitor_id: string; // Required - visitor ID from GrowlAds.getVisitorId() chat_id?: string; // Optional - to track messages within a conversation user_id?: string; // Optional - user identifier user_email?: string; // Optional - user email request_headers: Record<string, string>; // HTTP headers from user's request user_message?: { // Optional text: string; }; ai_message?: { // Optional text: string; };};publisher_id: requiredvisitor_id: required - visitor ID obtained fromwindow.GrowlAds.getVisitorId()on client-side. Links chat messages to the same visitor who sees ads. See Getting Visitor ID above.request_headers: requiredchat_id: Optional - to track messages within a conversationuser_id: Optional - user identifieruser_email: Optional - user emailuser_message: Optionalai_message: Optional
Response
Section titled “Response”- Body: JSON
{ "message_ids": ["message_id_1", "message_id_2"], "status": "ok"}Example
Section titled “Example”// visitor_id is required - must be obtained from window.GrowlAds.getVisitorId() on client-sideconst response = await fetch("https://api.withgrowl.com/v1/messages/", { method: "POST", body: JSON.stringify({ publisher_id: "69100feb57219626dx5d87x1", visitor_id: "abc123xyz", // from client side - from await window.GrowlAds.getVisitorId() chat_id: "chat_456", user_id: "user_123", user_email: "user@example.com", request_headers: { "x-forwarded-for": "193.176.86.166", "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" }, user_message: { text: "Hi" }, ai_message: { text: "Hello" }, }),});// visitor_id is required - must be obtained from window.GrowlAds.getVisitorId() on client-sideexport const recordGrowlEvent = async ({ publisher_id, visitor_id, user_id, user_email, chat_id, headers, user_message, ai_message,}) => { await fetch("https://api.withgrowl.com/v1/messages/", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ publisher_id: publisher_id, visitor_id: visitor_id, user_id: user_id, user_email: user_email, chat_id: chat_id, request_headers: headers, user_message: user_message, ai_message: ai_message, }), });
console.log("Event sent to Growl");};TypeScript Support
Section titled “TypeScript Support”If you’re using TypeScript, you can add type definitions for the Growl Ads API. Create a file (e.g., growl-ads.d.ts) with the following:
export {};
interface RecordMessageOptions { /** * The chat ID to record the message in. */ chat_id: string;
/** * The message to record. */ message: string;
/** * The role of the message. */ role: "user" | "assistant";
/** * The user ID to record the message for. */ user_id: string;}
declare global { interface GrowlAds { init: () => void; getVisitorId: () => Promise<string>; recordMessage: (options: RecordMessageOptions) => Promise<void>; }
interface Window { GrowlAds: GrowlAds; }}This will provide autocomplete and type checking for window.GrowlAds.getVisitorId() and window.GrowlAds.recordMessage().
Request Headers and what to include
Section titled “Request Headers and what to include”For effective ad targeting, we recommend including the following in request_headers:
user-agent— Identifies the user’s browser or client for device detection.accept-language— Specifies the user’s preferred languages for language-based targeting.- IP address — Provide whichever of these you have:
cf-connecting-ip,x-forwarded-for, orx-real-ip.- If these headers are unavailable, check your
request_headersfor alternatives likex-forwarded-hostorx-forwarded-port.
- If these headers are unavailable, check your
- Geographic data (if using Cloudflare): Include
cf-ipcountryandcf-ipcityfor location-based targeting.
Only send headers that are accessible in your environment. If any are missing, Growl will still process your request—however, limited header data may reduce the accuracy of ad targeting.