Installation
Copy
npm install @chat-ads/chatads-sdk
Quick Start
Copy
import { ChatAdsClient } from '@chat-ads/chatads-sdk';
const client = new ChatAdsClient({
apiKey: process.env.CHATADS_API_KEY!,
baseUrl: 'https://api.getchatads.com'
});
// Using analyzeMessage (string + options)
const response = await client.analyzeMessage(
"What are the best noise-cancelling headphones?",
{ country: "US" }
);
if (response.error === null && response.data?.returned > 0) {
// Access first offer
const offer = response.data.offers[0];
console.log(`link_text: ${offer.link_text}`);
console.log(`url: ${offer.url}`);
// Or iterate all offers
response.data.offers.forEach((offer, i) => {
console.log(`Offer ${i + 1}: ${offer.link_text} - ${offer.url}`);
});
}
Configuration Options
Copy
import { ChatAdsClient } from '@chat-ads/chatads-sdk';
const client = new ChatAdsClient({
apiKey: 'cak_your_api_key', // Required
baseUrl: 'https://api.getchatads.com', // Required: API base URL
timeoutMs: 10000, // Optional: request timeout (default: 10000)
maxRetries: 2, // Optional: retry attempts (default: 0)
retryBackoffFactorMs: 500, // Optional: backoff between retries
raiseOnFailure: true, // Optional: throw on API errors
fetchImplementation: customFetch, // Optional: custom fetch for Node 16
logger: console, // Optional: debug logging
});
Methods
analyze
Analyze a message using a payload object.Copy
const response = await client.analyze({
message: "Looking for a good yoga mat",
country: "US",
quality: "standard" // fast | standard | best
});
analyzeMessage
Convenience method that takes a message string directly.Copy
// Simple usage
const response = await client.analyzeMessage("Looking for a good yoga mat");
// With options
const response = await client.analyzeMessage(
"Looking for a good yoga mat",
{
country: "US",
quality: "standard"
}
);
Response Types
The SDK exports the following types from@chat-ads/chatads-sdk:
Copy
import type {
ChatAdsResponseEnvelope,
AnalyzeData,
Offer,
Product,
ChatAdsError,
ChatAdsMeta,
UsageInfo
} from '@chat-ads/chatads-sdk';
// Response envelope returned by analyze() and analyzeMessage()
interface ChatAdsResponseEnvelope {
data?: AnalyzeData | null;
error?: ChatAdsError | null;
meta: ChatAdsMeta;
}
interface AnalyzeData {
status: "filled" | "partial_fill" | "no_offers_found" | "internal_error"; // Response status
offers: Offer[]; // Array of affiliate offers (only contains filled offers)
requested: number; // Number of offers requested
returned: number; // Number of offers returned
}
interface Offer {
link_text: string; // Text to use for the affiliate link
url: string; // Affiliate URL (always populated)
confidence_level: string; // Confidence classification (low, medium, high)
product?: Product; // Product metadata
}
interface Product {
title?: string; // Product title from search
description?: string; // Product description
stars?: number; // Product rating (e.g., 4.5)
reviews?: number; // Number of reviews
}
interface ChatAdsError {
code: string;
message: string;
details?: Record<string, unknown>;
}
interface ChatAdsMeta {
request_id: string;
timestamp?: string;
version?: string;
country?: string | null;
timing_ms?: Record<string, number> | null;
usage?: UsageInfo | null;
}
interface UsageInfo {
monthly_requests: number;
is_free_tier: boolean;
free_tier_limit?: number | null;
free_tier_remaining?: number | null;
daily_requests?: number | null;
daily_limit?: number | null;
}
Error Handling
The SDK exports two error classes for typed error handling:Copy
import {
ChatAdsClient,
ChatAdsAPIError,
ChatAdsSDKError
} from '@chat-ads/chatads-sdk';
try {
const response = await client.analyzeMessage("Looking for headphones");
// Check response-level errors (when raiseOnFailure is false)
if (response.error !== null) {
switch (response.error?.code) {
case 'DAILY_LIMIT_EXCEEDED':
case 'MONTHLY_LIMIT_EXCEEDED':
// Rate limit hit - wait for reset
break;
case 'UNAUTHORIZED':
// Check API key
break;
default:
console.error(response.error?.message);
}
}
} catch (error) {
// ChatAdsAPIError: HTTP errors (4xx, 5xx) or logical failures (when raiseOnFailure is true)
if (error instanceof ChatAdsAPIError) {
console.error('API Error:', error.statusCode, error.response?.error);
}
// ChatAdsSDKError: Configuration, validation, or transport errors
else if (error instanceof ChatAdsSDKError) {
console.error('SDK Error:', error.message);
}
else {
console.error('Unexpected error:', error);
}
}
Framework Examples
Next.js API Route
Copy
// app/api/affiliate/route.ts
import { ChatAdsClient } from '@chat-ads/chatads-sdk';
import { NextResponse } from 'next/server';
const client = new ChatAdsClient({
apiKey: process.env.CHATADS_API_KEY!,
baseUrl: process.env.CHATADS_BASE_URL!
});
export async function POST(request: Request) {
const { message } = await request.json();
const response = await client.analyzeMessage(message, { country: "US" });
return NextResponse.json(response);
}
Express.js
Copy
import express from 'express';
import { ChatAdsClient } from '@chat-ads/chatads-sdk';
const app = express();
app.use(express.json());
const client = new ChatAdsClient({
apiKey: process.env.CHATADS_API_KEY!,
baseUrl: process.env.CHATADS_BASE_URL!
});
app.post('/analyze', async (req, res) => {
const response = await client.analyzeMessage(req.body.message);
res.json(response);
});