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.
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:
- A working AI chatbot — any framework (LangChain, custom, or hosted). The SDK is framework-agnostic.
- Node.js 18+ or a Python 3.9+ environment.
- A Surfacedd developer account — sign up at Surfacedd for Developers to get your API key.
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:
| Parameter | Required | Default | Description |
|---|---|---|---|
apiKey | Yes | — | Your Surfacedd API key |
appId | Yes | — | Unique identifier for your chatbot |
environment | No | production | production or sandbox |
timeout | No | 3000 | Request timeout in milliseconds |
fallbackEnabled | No | true | Return empty response instead of throwing on error |
cacheTTL | No | 300 | Cache duration for ad responses in seconds |
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:
query: The user's message. The SDK uses this to match relevant brand campaigns.context: Optional. Pass the conversation history for better contextual matching. More context produces more relevant ads.format: Controls the ad response structure.inlinereturns text suitable for embedding within your chatbot response.cardreturns structured data for rich card rendering.footerreturns a compact format for placement below the response.maxAds: Number of ad units to return per request. Start with 1 to keep the experience clean.categories: Optional filter to restrict ads to specific verticals. Useful if your chatbot serves a niche audience.
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:
- [ ] API key is stored as an environment variable, not hardcoded
- [ ] Sandbox testing completed with at least 100 test queries
- [ ] Frequency capping is configured (recommended: max 3 ads per session)
- [ ] Disclosure text ("Sponsored" / "Ad") renders visibly with every ad
- [ ] Impression tracking fires correctly (verify in the Surfacedd dashboard)
- [ ] Category blocking is set for any restricted verticals
- [ ] Error handling returns graceful fallback (no ad) when the API is unreachable
- [ ] 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 Category | Average eCPM | Revenue 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 |
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.