Skip to main content
Technical11 min read2,005 words

How to Add Ads to Your AI Chatbot in 5 Minutes (Tutorial)

Step-by-step tutorial to add contextual ads to your AI chatbot using the Surfacedd SDK. Install, init, call, render — live in 5 minutes.

S
Surfacedd Team

To add ads to your AI chatbot, install the Surfacedd SDK, initialize it with your API key, pass user queries to the ad endpoint, and render the returned contextual ad inside your chatbot response. The entire integration takes four steps and under five minutes of development time. This tutorial walks through each step with production-ready code examples.

Prerequisites

Before you start, you need three things:

  1. A working AI chatbot — any framework (LangChain, custom, or hosted). The SDK is framework-agnostic.
  2. Node.js 18+ or a Python 3.9+ environment.
  3. A Surfacedd developer account — sign up at Surfacedd for Developers to get your API key.
According to Grand View Research's 2025 Chatbot Market Report, the global chatbot market reached $7.01 billion in 2024 and is projected to grow at a 23.3% CAGR through 2030. Most chatbot developers leave revenue on the table by not monetizing their user interactions. Contextual ads change that equation without degrading user experience.

Step 1: Install the SDK

Node.js / TypeScript

npm install @surfacedd/ads-sdk

Or with yarn:

yarn add @surfacedd/ads-sdk

Python

pip install surfacedd-ads

The SDK is lightweight — under 45KB gzipped for the Node package, with zero runtime dependencies. It will not bloat your chatbot's bundle or introduce dependency conflicts.

Verify the installation:

# Node.js
node -e "const s = require('@surfacedd/ads-sdk'); console.log(s.VERSION)"

# Python
python -c "import surfacedd_ads; print(surfacedd_ads.__version__)"

You should see the current SDK version printed. If you get an import error, confirm your package manager installed to the correct environment.

Step 2: Initialize the SDK

Node.js / TypeScript

import { SurfaceddAds } from '@surfacedd/ads-sdk'

const ads = new SurfaceddAds({
apiKey: process.env.SURFACEDD_API_KEY,
appId: 'your-chatbot-app-id',
environment: 'production', // use 'sandbox' for testing
})

Python

from surfacedd_ads import SurfaceddAds

ads = SurfaceddAds(
api_key=os.environ["SURFACEDD_API_KEY"],
app_id="your-chatbot-app-id",
environment="production", # use "sandbox" for testing
)

Configuration options:

ParameterRequiredDefaultDescription
apiKeyYesYour Surfacedd API key
appIdYesUnique identifier for your chatbot
environmentNoproductionproduction or sandbox
timeoutNo3000Request timeout in milliseconds
fallbackEnabledNotrueReturn empty response instead of throwing on error
cacheTTLNo300Cache duration for ad responses in seconds
Always store your API key in an environment variable. Never hardcode it in source files. According to GitGuardian's 2025 State of Secrets Report, 12.8 million new secrets were exposed in public GitHub repositories in 2024. Treat your Surfacedd API key with the same care as any other credential.

Step 3: Fetch a Contextual Ad

This is the core integration step. When your chatbot receives a user query, pass it to the Surfacedd endpoint to get a contextually relevant ad.

Node.js / TypeScript

async function getAdForQuery(userQuery: string, conversationContext?: string) {
  const adResponse = await ads.getAd({
    query: userQuery,
    context: conversationContext,
    format: 'inline', // 'inline', 'card', or 'footer'
    maxAds: 1, // number of ads to return
    categories: ['tech', 'saas'], // optional category filter
  })

if (adResponse.hasAd) {
return adResponse.ads[0]
}

return null
}

Python

async def get_ad_for_query(user_query: str, conversation_context: str = None):
    ad_response = await ads.get_ad(
        query=user_query,
        context=conversation_context,
        format="inline",       # "inline", "card", or "footer"
        max_ads=1,             # number of ads to return
        categories=["tech", "saas"],  # optional category filter
    )

if ad_response.has_ad:
return ad_response.ads[0]

return None

Key parameters explained:

    1. query: The user's message. The SDK uses this to match relevant brand campaigns.
    2. context: Optional. Pass the conversation history for better contextual matching. More context produces more relevant ads.
    3. format: Controls the ad response structure. inline returns text suitable for embedding within your chatbot response. card returns structured data for rich card rendering. footer returns a compact format for placement below the response.
    4. maxAds: Number of ad units to return per request. Start with 1 to keep the experience clean.
    5. categories: Optional filter to restrict ads to specific verticals. Useful if your chatbot serves a niche audience.
The API responds in under 100ms on average. According to Surfacedd's 2026 Q1 performance report, P95 latency is 147ms, which means the ad fetch adds negligible delay to your chatbot's response time.

Handling the Response Object

The ad response contains everything you need to render and track the ad:

interface AdResponse {
  hasAd: boolean
  ads: Array<{
    id: string
    headline: string
    body: string
    brandName: string
    brandLogo: string
    ctaText: string
    ctaUrl: string
    disclosureText: string
    trackingPixel: string
  }>
  requestId: string
}

Always render the disclosureText alongside the ad. This typically reads "Sponsored" or "Ad" and ensures compliance with advertising transparency standards. The FTC's 2025 updated endorsement guides require clear and conspicuous disclosure of commercial content in AI-generated responses.

Step 4: Render the Ad in Your Chatbot Response

Now integrate the ad into your chatbot's response flow. Here is a complete example for a typical chatbot handler.

Node.js / TypeScript — Full Integration Example

import { SurfaceddAds } from '@surfacedd/ads-sdk'

const ads = new SurfaceddAds({
apiKey: process.env.SURFACEDD_API_KEY,
appId: 'my-chatbot',
})

async function handleUserMessage(userMessage: string, conversationHistory: string) {
// 1. Generate your chatbot's AI response (your existing logic)
const aiResponse = await generateAIResponse(userMessage, conversationHistory)

// 2. Fetch a contextual ad in parallel (non-blocking)
const adPromise = ads.getAd({
query: userMessage,
context: conversationHistory,
format: 'inline',
maxAds: 1,
})

// 3. Await the ad response
const adResponse = await adPromise

// 4. Combine AI response with ad
let finalResponse = aiResponse

if (adResponse.hasAd) {
const ad = adResponse.ads[0]
finalResponse += \n\n---\n
finalResponse += ${ad.disclosureText}: ${ad.headline}\n
finalResponse += ${ad.body}\n
finalResponse += ${ad.ctaText}

// 5. Fire the impression tracking pixel
await ads.trackImpression(ad.id, adResponse.requestId)
}

return finalResponse
}

Python — Full Integration Example

from surfacedd_ads import SurfaceddAds
import asyncio
import os

ads = SurfaceddAds(
api_key=os.environ["SURFACEDD_API_KEY"],
app_id="my-chatbot",
)

async def handle_user_message(user_message: str, conversation_history: str) -> str:
# 1. Generate your chatbot's AI response (your existing logic)
ai_response_task = generate_ai_response(user_message, conversation_history)

# 2. Fetch a contextual ad in parallel
ad_task = ads.get_ad(
query=user_message,
context=conversation_history,
format="inline",
max_ads=1,
)

# 3. Await both concurrently
ai_response, ad_response = await asyncio.gather(ai_response_task, ad_task)

# 4. Combine AI response with ad
final_response = ai_response

if ad_response.has_ad:
ad = ad_response.ads[0]
final_response += f"\n\n---\n"
final_response += f"{ad.disclosure_text}: {ad.headline}\n"
final_response += f"{ad.body}\n"
final_response += f"{ad.cta_text}"

# 5. Fire the impression tracking pixel
await ads.track_impression(ad.id, ad_response.request_id)

return final_response

Performance tip: Fetch the ad concurrently with your AI response generation. The ad API call runs in parallel, so it adds zero additional latency to your chatbot's total response time.

Step 5: Configure Ad Behavior

Fine-tune how ads appear in your chatbot using the configuration dashboard or SDK parameters.

Frequency Capping

Avoid showing ads on every response. Set frequency caps to maintain user experience quality:

const ads = new SurfaceddAds({
  apiKey: process.env.SURFACEDD_API_KEY,
  appId: 'my-chatbot',
  frequencyCap: {
    maxAdsPerSession: 3, // max ads per user session
    minMessagesBetween: 5, // minimum messages between ads
    cooldownSeconds: 120, // minimum seconds between ads
  },
})

According to a 2025 user experience study by the Nielsen Norman Group, chatbot users tolerate 1 ad per 5-7 messages without reported negative impact on satisfaction scores. Exceeding that ratio caused a measurable drop in session length.

Category Blocking

Block ad categories that conflict with your chatbot's purpose:

const ads = new SurfaceddAds({
  apiKey: process.env.SURFACEDD_API_KEY,
  appId: 'my-chatbot',
  blockedCategories: ['gambling', 'alcohol', 'political'],
})

Revenue Tracking

Monitor your earnings through the SDK:

const stats = await ads.getStats({
  period: '30d',
  metrics: ['impressions', 'clicks', 'revenue', 'ecpm'],
})

console.log(Revenue (30 days): $${stats.revenue})
console.log(Effective CPM: $${stats.ecpm})

Troubleshooting Common Issues

"No ad returned" for most queries

This usually means your query context is too vague. Pass the full conversation history in the context parameter. More context allows better matching. If you are in sandbox mode, switch to production — sandbox has limited ad inventory.

High latency responses

Check your timeout setting. The default is 3000ms, which is generous. If latency exceeds 200ms consistently, verify your server's geographic location. The Surfacedd API has edge nodes in US-East, US-West, EU-West, and AP-Southeast. Use the closest region.

Tracking pixels not firing

Ensure trackImpression() is called after the ad is rendered to the user, not before. The function is async — await it or fire-and-forget with .catch() to prevent unhandled promise rejections.

SDK version conflicts

If you see TypeScript type errors after updating, clear your node_modules and reinstall. The SDK follows semantic versioning. Major version bumps may include breaking changes. Pin your version in package.json for stability.

Going Live: Pre-Launch Checklist

Before deploying ads to your production chatbot, verify these items:

    1. [ ] API key is stored as an environment variable, not hardcoded
    2. [ ] Sandbox testing completed with at least 100 test queries
    3. [ ] Frequency capping is configured (recommended: max 3 ads per session)
    4. [ ] Disclosure text ("Sponsored" / "Ad") renders visibly with every ad
    5. [ ] Impression tracking fires correctly (verify in the Surfacedd dashboard)
    6. [ ] Category blocking is set for any restricted verticals
    7. [ ] Error handling returns graceful fallback (no ad) when the API is unreachable
    8. [ ] Response latency tested under load — ad fetch should not increase total response time

Revenue Expectations

What can you expect to earn from chatbot ads? Revenue depends on your chatbot's traffic volume, audience demographics, and query topics.

According to Surfacedd's 2026 publisher benchmark data, chatbots in the following categories see these average effective CPMs:

Chatbot CategoryAverage eCPMRevenue per 100K Queries
Technology / SaaS$8.50$850
Finance / Insurance$12.00$1,200
Travel / Hospitality$7.20$720
Health / Wellness$6.80$680
General Purpose$4.50$450
Education$3.80$380
A chatbot handling 500,000 queries per month in the technology vertical could generate roughly $4,250/month in ad revenue. Scale that to 2 million queries and you are looking at $17,000/month — meaningful revenue from a 5-minute integration.

For complete API documentation, endpoint references, and advanced configuration guides, visit the Surfacedd Developer Documentation.

Sign up for a developer account at Surfacedd for Developers and start monetizing your chatbot today.

FAQ

Does adding ads slow down my chatbot?

No, when implemented correctly. The Surfacedd SDK fetches ads concurrently with your AI response generation, adding zero additional latency to the user-facing response time. The API's P95 latency is 147ms. If the ad request exceeds your configured timeout, the SDK returns an empty response and your chatbot serves its answer without an ad. Users never wait for ads.

How much can I earn from chatbot ads?

Revenue depends on traffic volume, audience vertical, and ad engagement. Technology-focused chatbots with 500,000 monthly queries typically earn $4,000-$5,000/month at current eCPM rates. Finance and insurance verticals earn more. The SDK requires minimal maintenance after initial setup, making the revenue essentially passive once your chatbot is live.

Will ads hurt my chatbot's user experience?

Not if you configure frequency capping correctly. Research from the Nielsen Norman Group shows that users tolerate 1 ad per 5-7 messages without negative impact on satisfaction. The Surfacedd SDK supports configurable frequency caps, category blocking, and disclosure text to keep ads transparent and non-intrusive. Start conservative and adjust based on user feedback.

What frameworks does the Surfacedd SDK support?

The SDK is framework-agnostic. It works with any Node.js or Python chatbot — LangChain, LlamaIndex, custom implementations, Rasa, Botpress, or hosted platforms that allow custom code. The SDK makes a simple API call and returns structured data. If your chatbot can make HTTP requests, it can integrate Surfacedd ads. See the developer documentation for framework-specific examples.

Start monetizing your AI app today

Get the SDK →Calculate Revenue →
chatbot ads SDKAI ad integrationdeveloper tutorialchatbot monetizationad SDK

Related Posts

Technical

MCP Advertising, Explained

8 min read
Developer Monetization

MCP Server Monetization: How to Add Ads to MCP

5 min read
Developer Monetization

AI Agent Monetization: The Developer's Complete Guide

16 min read