Skip to content

HTTPS

This document explains two ways to send chat messages to Growl:

  1. Frontend Recording (Recommended): Use window.GrowlAds.recordMessage() directly from your frontend - simplest and most convenient
  2. 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.


If you prefer to track messages from your backend, use the /v1/messages/ endpoint.

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();

Include the visitor_id in your chat request to your backend:

// Example: sending a chat message with visitor ID
const 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
}),
});

In your backend, include the visitor_id when calling the Growl messages API. See the API Reference and examples below.

POST https://api.withgrowl.com/v1/messages/

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 : required
  • visitor_id : required - visitor ID obtained from window.GrowlAds.getVisitorId() on client-side. Links chat messages to the same visitor who sees ads. See Getting Visitor ID above.
  • request_headers : required
  • chat_id : Optional - to track messages within a conversation
  • user_id : Optional - user identifier
  • user_email : Optional - user email
  • user_message : Optional
  • ai_message : Optional
  • Body: JSON
{
"message_ids": ["message_id_1", "message_id_2"],
"status": "ok"
}
// visitor_id is required - must be obtained from window.GrowlAds.getVisitorId() on client-side
const 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" },
}),
});
growl.js
// visitor_id is required - must be obtained from window.GrowlAds.getVisitorId() on client-side
export 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");
};

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:

growl-ads.d.ts
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().

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, or x-real-ip.
    • If these headers are unavailable, check your request_headers for alternatives like x-forwarded-host or x-forwarded-port.
  • Geographic data (if using Cloudflare): Include cf-ipcountry and cf-ipcity for 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.