@the_ro_show/agent-ads-sdk 0.6.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,611 +1,462 @@
1
- # AttentionMarket Agent Ads SDK
1
+ # AttentionMarket
2
2
 
3
3
  [![npm version](https://badge.fury.io/js/@the_ro_show%2Fagent-ads-sdk.svg)](https://www.npmjs.com/package/@the_ro_show/agent-ads-sdk)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](https://www.typescriptlang.org/)
6
5
 
7
- Ad network for AI agents. Pass user messages, get contextually relevant ads, earn revenue. Similar to AdSense but designed for conversational interfaces. It's time to start monetizing your AI agents!
6
+ **The ad exchange for the AI era. Monetize your chatbot, AI assistant, or AI agent with one API call.**
8
7
 
9
- - **70% revenue share** - You keep most of the earnings (I use the remaining 30% to onboard advertisers and support that ecosystem).
10
- - **Simple integration** - One API call to get ads
8
+ Works on every platform iOS, Android, Web, Voice, Discord, WhatsApp, Node.js, Python, and anything else that can make an HTTP request.
11
9
 
12
10
  ---
13
11
 
14
- ## Quick Start
12
+ ## Two Ways To Earn
15
13
 
16
- ### 1. Get API Key
14
+ ### 1. Show ads in your chatbot or AI assistant
15
+ Your app has conversations. Users ask questions. You send us the context, we return a relevant ad, you earn $5–$150 when the user clicks.
17
16
 
18
- Sign up at [attentionmarket.com/signup](https://api.attentionmarket.ai/) to receive:
19
- - Test key: `am_test_...`
20
- - Live key: `am_live_...`
21
- - Agent ID
17
+ ### 2. List your AI agent on the exchange
18
+ You built a specialized AI agent. Other AI agents need what you offer. List it on AttentionMarket and earn every time another agent calls yours.
22
19
 
23
- ### 2. Install
24
-
25
- ```bash
26
- npm install @the_ro_show/agent-ads-sdk
27
- ```
20
+ ---
28
21
 
29
- ### 3. Basic Usage
22
+ ## Quick Start — 30 Seconds
30
23
 
31
- ```typescript
32
- import { AttentionMarketClient } from '@the_ro_show/agent-ads-sdk';
33
-
34
- const client = new AttentionMarketClient({
35
- apiKey: process.env.ATTENTIONMARKET_API_KEY,
36
- agentId: 'your_agent_id'
37
- });
24
+ Get your API keys at [api.attentionmarket.ai](https://api.attentionmarket.ai), then:
38
25
 
39
- // Request an ad based on user message
40
- const ad = await client.decideFromContext({
41
- userMessage: "I need car insurance"
42
- });
26
+ ```bash
27
+ curl -X POST https://peruwnbrqkvmrldhpoom.supabase.co/functions/v1/decide \
28
+ -H "X-AM-API-Key: am_live_YOUR_KEY" \
29
+ -H "Content-Type: application/json" \
30
+ -d '{"context": "I need car insurance"}'
31
+ ```
43
32
 
44
- if (ad) {
45
- console.log(ad.creative.title);
46
- console.log(ad.creative.body);
47
- console.log(ad.creative.cta);
33
+ **Response:**
34
+ ```json
35
+ {
36
+ "status": "filled",
37
+ "units": [{
38
+ "suggestion": {
39
+ "title": "Get 20% off car insurance",
40
+ "body": "Compare quotes in minutes",
41
+ "cta": "Get a Quote",
42
+ "tracking_url": "https://..."
43
+ }
44
+ }]
48
45
  }
49
46
  ```
50
47
 
51
- ---
52
-
53
- ## How It Works
54
-
55
- 1. User interacts with your agent: `"I need help with estate planning"`
56
- 2. You pass the message to `decideFromContext()`
57
- 3. We return a matching ad from our network
58
- 4. You display it and track clicks to earn revenue
59
-
60
- The API handles intent detection and ad matching automatically.
48
+ Show `suggestion.title` and `suggestion.body` to your user. When they click, send them to `tracking_url`. That's it — you get paid automatically.
61
49
 
62
50
  ---
63
51
 
64
- ## Complete Example
52
+ ## 🚨 CRITICAL: Impression Tracking Required (v0.9.0+)
65
53
 
66
- Full integration including ad retrieval, display, and click tracking:
54
+ **As of v0.9.0, impression tracking is REQUIRED to earn revenue from clicks.**
67
55
 
68
- ```typescript
69
- import { AttentionMarketClient } from '@the_ro_show/agent-ads-sdk';
70
-
71
- const client = new AttentionMarketClient({
72
- apiKey: process.env.ATTENTIONMARKET_API_KEY,
73
- agentId: 'your_agent_id'
74
- });
75
-
76
- async function handleUserMessage(userMessage: string) {
77
- const ad = await client.decideFromContext({ userMessage });
78
-
79
- if (!ad) {
80
- return null; // No ads available
81
- }
82
-
83
- // Display ad (you can customize this)
84
- const displayMessage = `\n[Sponsored] ${ad.disclosure.sponsor_name}\n${ad.creative.title}\n${ad.creative.body}\n${ad.creative.cta}\n`;
85
- console.log(displayMessage);
86
-
87
- // Track click when user clicks
88
- await client.trackClick({
89
- agent_id: 'your_agent_id',
90
- request_id: ad.request_id,
91
- decision_id: ad.offer_id,
92
- unit_id: ad.offer_id,
93
- tracking_token: ad.tracking_token,
94
- href: ad.click_url,
95
- click_context: displayMessage // What was actually shown to user
96
- });
97
-
98
- return ad;
99
- }
100
- ```
56
+ When you show an ad to a user, you must track an impression. Clicks without prior impressions will:
57
+ - Still redirect the user to the advertiser (good UX)
58
+ - ❌ NOT charge the advertiser
59
+ - NOT credit your earnings
101
60
 
102
- ---
103
-
104
- ## API Reference
61
+ ### Why This Matters
105
62
 
106
- ### Primary API
63
+ This prevents developers from filtering ads client-side and still earning revenue from clicks. It ensures clean data and accurate quality metrics for the advertising exchange.
107
64
 
108
- #### `decideFromContext(params)` → `Promise <OfferResponse | null>`
65
+ ### Using `decideFromContext()` (Recommended)
109
66
 
110
- Pass a user message and optionally conversation history. Returns a matching ad or null if no fill.
67
+ **Good news:** If you're using the SDK's `decideFromContext()` method, impressions are tracked **automatically**. No changes needed.
111
68
 
112
69
  ```typescript
70
+ // Impressions tracked automatically ✅
113
71
  const ad = await client.decideFromContext({
114
- userMessage: "I need help with estate planning",
115
- conversationHistory: ["My father passed away recently"], // Optional
116
- context: { geo: { city: 'NYC', country: 'US' } } // Optional
72
+ userMessage: "I need car insurance",
73
+ placement: 'sponsored_suggestion'
117
74
  });
118
- ```
119
-
120
- Returns ad with:
121
- - `creative.title` - Ad headline
122
- - `creative.body` - Ad description
123
- - `creative.cta` - Call to action
124
- - `click_url` - URL to open on click
125
- - `tracking_token` - Required for revenue tracking
126
- - `disclosure` - Sponsor information
127
75
 
128
- ### Revenue Tracking
129
-
130
- #### `trackClick(params)` → `Promise<void>`
131
-
132
- Records user clicks for revenue attribution. Call this when a user clicks an ad. Handles deduplication and retries automatically.
133
-
134
- **Required:** `click_context` - The actual message shown to the user. This helps optimize ad creative based on what converts.
135
-
136
- ```typescript
137
- await client.trackClick({
138
- agent_id: 'your_agent_id',
139
- request_id: ad.request_id,
140
- decision_id: ad.offer_id,
141
- unit_id: ad.offer_id,
142
- tracking_token: ad.tracking_token,
143
- href: ad.click_url,
144
- click_context: "The message shown to user that they clicked"
145
- });
76
+ if (ad) {
77
+ // Show ad to user
78
+ displayAd(ad);
79
+ }
146
80
  ```
147
81
 
148
- ### Testing
82
+ ### Using Raw HTTP or `decide()` (Manual Tracking Required)
149
83
 
150
- #### `MockAttentionMarketClient`
151
-
152
- Mock client for testing without API calls. Simulates latency and fill rate behavior.
84
+ If you're making raw HTTP calls or using the low-level `decide()` method, you **must manually track impressions**:
153
85
 
154
86
  ```typescript
155
- import { MockAttentionMarketClient } from '@the_ro_show/agent-ads-sdk';
156
-
157
- const client = new MockAttentionMarketClient({
158
- fillRate: 1.0, // Always return ads (0.0 = never, 0.5 = 50% of time)
159
- latencyMs: 100, // Simulate API latency
160
- verbose: true // Log what's happening
87
+ // Step 1: Get ad
88
+ const response = await fetch('https://peruwnbrqkvmrldhpoom.supabase.co/functions/v1/decide', {
89
+ method: 'POST',
90
+ headers: { 'X-AM-API-Key': 'am_live_...' },
91
+ body: JSON.stringify({ context: 'I need car insurance' })
161
92
  });
93
+ const data = await response.json();
94
+
95
+ if (data.status === 'filled') {
96
+ const ad = data.units[0];
97
+
98
+ // Step 2: Track impression IMMEDIATELY when showing ad ✅
99
+ await fetch('https://peruwnbrqkvmrldhpoom.supabase.co/functions/v1/event', {
100
+ method: 'POST',
101
+ headers: { 'X-AM-API-Key': 'am_live_...' },
102
+ body: JSON.stringify({
103
+ event_id: `evt_${crypto.randomUUID()}`,
104
+ event_type: 'impression',
105
+ occurred_at: new Date().toISOString(),
106
+ agent_id: 'YOUR_AGENT_ID',
107
+ unit_id: ad.unit_id,
108
+ tracking_token: ad.tracking.token
109
+ })
110
+ });
162
111
 
163
- // Works exactly like the real client
164
- const ad = await client.decideFromContext({ userMessage: "test" });
112
+ // Step 3: Now safe to show ad and earn from clicks
113
+ displayAd(ad);
114
+ }
165
115
  ```
166
116
 
167
117
  ---
168
118
 
169
- ## Advanced Features
170
-
171
- <details>
172
- <summary><strong>Click to view advanced APIs (most developers don't need these)</strong></summary>
119
+ ## Use Case 1: Monetize Your Chatbot or AI Assistant
173
120
 
174
- <br>
121
+ Any app with conversations can earn revenue. Users ask questions with commercial intent every day — insurance, legal help, home services, travel, weddings, software. When they do, you can surface a relevant offer and earn.
175
122
 
176
- The simple `decideFromContext()` API handles everything for 90% of use cases. But if you need more control:
123
+ **Platforms this works on:**
177
124
 
178
- ### Manual Category Targeting
125
+ | Type | Examples |
126
+ |------|---------|
127
+ | **AI Assistants** | Mobile AI apps, productivity tools, personal assistants |
128
+ | **Chatbots** | Website chat, customer service bots, FAQ bots |
129
+ | **Messaging Bots** | WhatsApp, Discord, Telegram, Slack |
130
+ | **Voice Assistants** | Alexa Skills, Google Actions, voice apps |
131
+ | **AI Companions** | Coaching bots, tutors, entertainment assistants |
179
132
 
180
- #### `decide()` - Specify exact categories
181
- When you know the exact category, use manual taxonomy matching for deterministic results.
133
+ ### How It Works
182
134
 
183
- ```typescript
184
- const decision = await client.decide({
185
- request_id: crypto.randomUUID(),
186
- agent_id: 'your_agent_id',
187
- placement: { type: 'sponsored_suggestion' },
188
- opportunity: {
189
- intent: { taxonomy: 'insurance.auto.full_coverage.quote' },
190
- context: { country: 'US', language: 'en', platform: 'web' }
191
- }
192
- });
193
135
  ```
194
-
195
- See [TAXONOMY_SYSTEM.md](./TAXONOMY_SYSTEM.md) for all categories.
196
-
197
- ---
198
-
199
- ### 🌐 Intenture Network APIs (Agent-to-Agent)
200
-
201
- #### `requestOffer()` - Intent-key based matching for high confidence scenarios
202
- When you KNOW what the user wants (they said "order coffee" or "book lawyer"), use intent-keys like `coffee.purchase.delivery` for deterministic matching. Enables agent-to-agent coordination and revenue sharing.
203
-
204
- ```typescript
205
- const offer = await client.requestOffer({
206
- placementId: 'order_card',
207
- intentKey: 'coffee.purchase.delivery',
208
- context: { geo: { city: 'SF', country: 'US' } }
209
- });
136
+ User sends message → You call our API with context → We return a relevant ad
137
+ You show it → User clicks → You earn $5–$150
210
138
  ```
211
139
 
212
- #### `requestOfferFromContext()` - Semantic discovery for fuzzy intents
213
- When you're NOT sure what they need (they said "I'm so tired"), pass the conversation and let semantic search find relevant offers. Auto-limits history to last 5 messages.
214
-
215
- ```typescript
216
- const offer = await client.requestOfferFromContext({
217
- placementId: 'chat_suggestion',
218
- userMessage: "I'm so tired, long day at work...",
219
- conversationHistory: ["How was your day?", "Exhausting"],
220
- context: { geo: { city: 'NYC' } }
221
- });
140
+ ### Platform Examples
141
+
142
+ **iOS (Swift)** — drop this into your Xcode project:
143
+ ```swift
144
+ // Initialize once
145
+ let client = AttentionMarketClient(
146
+ apiKey: "am_live_YOUR_KEY",
147
+ agentId: "agt_YOUR_ID"
148
+ )
149
+
150
+ // Call after your AI responds
151
+ if let ad = await client.getAd(for: userMessage) {
152
+ showAdInChat(
153
+ title: ad.suggestion.title,
154
+ body: ad.suggestion.body,
155
+ cta: ad.suggestion.cta,
156
+ url: ad.suggestion.trackingUrl
157
+ )
158
+ }
222
159
  ```
160
+ [Full iOS example →](./examples/ios/AttentionMarketClient.swift)
223
161
 
224
- #### Revenue Share (Preview) - Track referrals between agents
225
- If another agent sends users to you, include their agent_id to split revenue (0-50%). Currently in preview mode (logs only) - payouts activate Q2 2026. Think affiliate marketing for AI agents.
162
+ ---
226
163
 
227
- ```typescript
228
- const offer = await client.requestOffer({
229
- intentKey: 'legal.divorce.consultation',
230
- sourceAgentId: 'agt_referrer_123', // Agent who sent the user
231
- revenueSharePct: 30, // Give them 30% of revenue
232
- // ... other params
233
- });
164
+ **Android (Kotlin)**:
165
+ ```kotlin
166
+ val client = AttentionMarketClient(
167
+ apiKey = "am_live_YOUR_KEY",
168
+ agentId = "agt_YOUR_ID"
169
+ )
170
+
171
+ client.getAd(context = userMessage)?.let { ad ->
172
+ showAdInChat(
173
+ title = ad.suggestion.title,
174
+ body = ad.suggestion.body,
175
+ url = ad.suggestion.trackingUrl
176
+ )
177
+ }
234
178
  ```
179
+ [Full Android example →](./examples/android/AttentionMarketClient.kt)
235
180
 
236
181
  ---
237
182
 
238
- ### 🧠 Intent Detection
183
+ **Web (JavaScript)** plain fetch, no dependencies:
184
+ ```javascript
185
+ const response = await fetch('https://peruwnbrqkvmrldhpoom.supabase.co/functions/v1/decide', {
186
+ method: 'POST',
187
+ headers: {
188
+ 'X-AM-API-Key': 'am_live_YOUR_KEY',
189
+ 'Content-Type': 'application/json'
190
+ },
191
+ body: JSON.stringify({ context: userMessage })
192
+ });
239
193
 
240
- #### `detectIntent()` - Auto-detect where users are in their journey
241
- Analyzes queries to determine if they're researching ("what is X?"), comparing ("X vs Y"), getting quotes ("how much?"), or ready to buy ("I want X"). Returns 'research', 'compare', 'quote', 'apply', 'support', or 'other'.
194
+ const data = await response.json();
242
195
 
243
- ```typescript
244
- detectIntent("What is car insurance?") // → 'research'
245
- detectIntent("Compare car insurance options") // → 'compare'
246
- detectIntent("Get car insurance quote") // → 'quote'
247
- detectIntent("I want to buy car insurance") // → 'apply'
196
+ if (data.status === 'filled') {
197
+ const ad = data.units[0];
198
+ showAdInChat(ad.suggestion.title, ad.suggestion.body, ad.suggestion.tracking_url);
199
+ }
248
200
  ```
201
+ [Full Web example →](./examples/web/attentionmarket.js)
249
202
 
250
- #### `buildTaxonomy()` - Type-safe taxonomy builder
251
- Constructs valid taxonomies like "insurance.auto.full_coverage.quote" with validation. Pass vertical, category, subcategory, and intent - it handles the formatting and catches errors.
203
+ ---
252
204
 
253
- ```typescript
254
- const taxonomy = buildTaxonomy('insurance', 'auto', 'full_coverage', 'quote');
255
- // "insurance.auto.full_coverage.quote"
205
+ **Node.js (optional SDK)**:
206
+ ```bash
207
+ npm install @the_ro_show/agent-ads-sdk
256
208
  ```
209
+ ```javascript
210
+ import { AttentionMarketClient } from '@the_ro_show/agent-ads-sdk';
257
211
 
258
- #### `suggestTaxonomies()` - Smart taxonomy recommendations
259
- Pass a user query and get back 3-5 relevant taxonomy suggestions ranked by relevance. Great for when you're not sure which category to use.
212
+ const client = new AttentionMarketClient({
213
+ apiKey: process.env.ATTENTIONMARKET_API_KEY,
214
+ agentId: process.env.ATTENTIONMARKET_AGENT_ID
215
+ });
260
216
 
261
- ```typescript
262
- const suggestions = suggestTaxonomies("I need a lawyer for divorce");
263
- // → ['legal.family.divorce.consultation', 'legal.family.custody.consultation']
217
+ const ad = await client.decideFromContext({ userMessage });
218
+ if (ad) console.log(ad.creative.title, ad.click_url);
264
219
  ```
265
220
 
266
- #### Taxonomy Utilities
267
- - `isValidTaxonomy(taxonomy)` - Validate taxonomy format
268
- - `parseTaxonomy(taxonomy)` - Parse taxonomy into components
269
- - `getBaseTaxonomy(taxonomy)` - Get taxonomy without intent
270
- - `matchesTaxonomy(tax1, tax2)` - Check if taxonomies match
271
- - `getVertical(taxonomy)` - Extract industry vertical
272
-
273
221
  ---
274
222
 
275
- ### 🎨 Response Formatting
223
+ ## Use Case 2: List Your AI Agent on the Exchange
276
224
 
277
- #### `formatNatural()` - Convert ads into natural conversation
278
- Transforms sponsored suggestions into conversational responses that feel native to your agent. Handles disclosure labels, CTA integration, and tone matching automatically.
225
+ You built a specialized AI agent a legal document drafter, a wedding photographer booker, a travel planner, a code reviewer. Other AI assistants encounter users who need exactly what you do every day. List your agent on AttentionMarket and earn every time another agent calls yours.
279
226
 
280
- ```typescript
281
- const formatted = formatNatural(ad, {
282
- tone: 'friendly',
283
- includeDisclosure: true
284
- });
285
- // → "I found a great option for you! [Sponsored: Lemonade]..."
286
- ```
227
+ **This is the ad exchange for the agentic world.** Instead of humans clicking ads, AI agents discover and call specialized agents. You pay to be discovered. You earn when your agent gets used.
287
228
 
288
- #### `formatInlineMention()` - Subtle in-message placement
289
- Weaves ads into your agent's response as natural mentions. Like "Btw, Lemonade offers great rates for new drivers [Sponsored]". Less intrusive than separate ad blocks.
229
+ ### How It Works
290
230
 
291
- ```typescript
292
- const mention = formatInlineMention(ad);
293
- // → "Btw, Lemonade offers 20% off for new drivers [Sponsored]"
294
231
  ```
295
-
296
- #### `validateAdFits()` - Check if ad matches conversation context
297
- Before showing an ad, validate it fits the current conversation. Checks relevance, tone, and user intent to avoid jarring placements.
298
-
299
- ```typescript
300
- const fits = validateAdFits(ad, conversationContext);
301
- if (fits) {
302
- // Show the ad
303
- }
232
+ General assistant encounters a task it can't handle well
233
+ Calls AttentionMarket with context + response_type: "agent"
234
+ Exchange returns the best specialized agent for that task
235
+ → General assistant calls your agent
236
+ → You earn per call
304
237
  ```
305
238
 
306
- ---
307
-
308
- ### 📊 Event Tracking
239
+ ### Example
309
240
 
310
- #### `trackImpression()` - Log when users see an ad
311
- Record that an ad was shown to a user. Required for billing and analytics. Include the unit_id and tracking token from the ad response.
241
+ **Developer A** built a general wedding planning AI assistant. A user asks: *"Can you find me a photographer in Austin under $3,000?"*
312
242
 
313
- ```typescript
314
- await client.trackImpression({
315
- agent_id: 'your_agent_id',
316
- request_id: decision.request_id,
317
- decision_id: decision.decision_id,
318
- unit_id: ad.unit_id,
319
- tracking_token: ad.tracking.token
320
- });
243
+ Developer A's assistant calls AttentionMarket:
244
+ ```bash
245
+ curl -X POST https://peruwnbrqkvmrldhpoom.supabase.co/functions/v1/decide \
246
+ -H "X-AM-API-Key: am_live_DEV_A_KEY" \
247
+ -H "Content-Type: application/json" \
248
+ -d '{
249
+ "context": "User needs a wedding photographer in Austin under $3,000",
250
+ "response_type": "agent"
251
+ }'
321
252
  ```
322
253
 
323
- #### `trackClick()` - Log when users click an ad
324
- Record when users interact with ads. This is how you get paid. Automatically deduplicates to prevent double-charging.
325
-
326
- **Required:** `click_context` - The actual message shown to the user that they clicked.
327
-
328
- ```typescript
329
- await client.trackClick({
330
- agent_id: 'your_agent_id',
331
- request_id: decision.request_id,
332
- decision_id: decision.decision_id,
333
- unit_id: ad.unit_id,
334
- tracking_token: ad.tracking.token,
335
- href: ad.suggestion.action_url,
336
- click_context: 'The message shown to user when they clicked'
337
- });
254
+ **AttentionMarket returns Developer B's agent:**
255
+ ```json
256
+ {
257
+ "status": "filled",
258
+ "units": [{
259
+ "agent_name": "WeddingPhoto AI",
260
+ "capability": "Book wedding photographers by location and budget",
261
+ "endpoint": "https://weddingphoto.ai/api/v1",
262
+ "input_description": "Send: location (string), budget (number), date (string)",
263
+ "output_description": "Returns: photographer name, price, booking URL",
264
+ "tracking": {
265
+ "call_url": "https://.../track-call/token"
266
+ }
267
+ }]
268
+ }
338
269
  ```
339
270
 
340
- ---
271
+ **Developer A** calls WeddingPhoto AI, gets a result, passes it back to the user.
272
+ **Developer B** earns per call. **Developer A** earns a routing fee.
341
273
 
342
- ### 🛠️ Helper Utilities
274
+ ### List Your Agent
343
275
 
344
- #### `createOpportunity()` - Build opportunity objects easily
345
- Helper to construct the opportunity payload for decide() calls. Handles defaults and validation.
276
+ Sign up as an advertiser at [api.attentionmarket.ai](https://api.attentionmarket.ai) and create an **Agent Ad** campaign:
346
277
 
347
- ```typescript
348
- const opportunity = createOpportunity({
349
- taxonomy: 'insurance.auto.quote',
350
- country: 'US'
351
- });
352
- ```
278
+ | Field | Description |
279
+ |-------|-------------|
280
+ | Agent Name | Display name (e.g. "WeddingPhoto AI") |
281
+ | What does your agent do? | Natural language capability description — used for matching |
282
+ | Endpoint URL | Where calling agents send requests |
283
+ | What to send | Input format description |
284
+ | What you return | Output format description |
285
+ | Bid per call | What you pay each time your agent is called |
353
286
 
354
- #### Security Helpers
355
- - `escapeHTML(text)` - Sanitize ad content before rendering to prevent XSS attacks
356
- - `sanitizeURL(url)` - Validate and sanitize URLs before opening
287
+ **Matching is semantic** — describe your agent clearly in plain English and we handle the rest.
357
288
 
358
- **Always sanitize ad content before displaying in web contexts!**
289
+ ---
359
290
 
360
- #### ID Generation
361
- - `generateUUID()` - Create unique request IDs (crypto-secure randomness)
362
- - `generateTimestamp()` - Generate timestamps that match our API requirements
291
+ ## Revenue Model
363
292
 
364
- ---
293
+ ### As a Developer (showing ads or routing to agents)
365
294
 
366
- ### 🧪 Testing
295
+ - **70% revenue share** on every click or agent call you facilitate
296
+ - Earn $5–$150 per click for ads
297
+ - Earn a routing fee per agent-to-agent call
298
+ - Monthly payouts via Stripe (minimum $100 balance)
299
+ - Free to integrate — no setup fees, no monthly costs
367
300
 
368
- #### `MockAttentionMarketClient` - Test without real API calls
369
- Drop-in replacement that returns fake ads for testing. Simulates latency, errors, and no-fill scenarios. Perfect for unit tests and local development.
301
+ **Example earnings:**
370
302
 
371
- ```typescript
372
- import { MockAttentionMarketClient } from '@the_ro_show/agent-ads-sdk';
303
+ | Monthly clicks/calls | Avg payout | Monthly revenue |
304
+ |---------------------|------------|-----------------|
305
+ | 50 | $50 | $2,500 |
306
+ | 200 | $50 | $10,000 |
307
+ | 1,000 | $50 | $50,000 |
373
308
 
374
- const client = new MockAttentionMarketClient({
375
- fillRate: 1.0, // Always return ads
376
- latencyMs: 100, // Simulate API latency
377
- verbose: true // Log activity
378
- });
309
+ ### As an Agent Advertiser (listing your agent)
379
310
 
380
- // Works exactly like real client, but returns mock data
381
- const decision = await client.decide(request);
382
- ```
311
+ - Pay per click (Link Ad) or pay per call (Agent Ad)
312
+ - Second-price auction you bid a max, you often pay less
313
+ - Full budget controls — set a cap, campaign pauses when spent
314
+ - Track spend and performance in the advertiser dashboard
383
315
 
384
316
  ---
385
317
 
386
- ### ⚠️ Error Handling
318
+ ## API Reference
319
+
320
+ ### `POST /v1/decide`
387
321
 
388
- #### `APIRequestError` - API returned an error response
389
- Thrown when the backend rejects your request (invalid key, bad params, etc). Includes detailed error message and request_id for debugging.
322
+ **Base URL:** `https://peruwnbrqkvmrldhpoom.supabase.co/functions/v1/decide`
390
323
 
391
- #### `NetworkError` - Connection failed
392
- Network issues, DNS failures, or backend unavailable. Includes automatic retry logic for transient failures.
324
+ **Required header:** `X-AM-API-Key: am_live_...` or `am_test_...`
393
325
 
394
- #### `TimeoutError` - Request exceeded timeout
395
- Request took too long (default 5s). Configure with `timeoutMs` in constructor.
326
+ ### Simple Request (recommended)
396
327
 
397
- ```typescript
398
- try {
399
- const decision = await client.decide(request);
400
- } catch (error) {
401
- if (error instanceof TimeoutError) {
402
- console.log('Request timed out, try again');
403
- } else if (error instanceof NetworkError) {
404
- console.log('Network issue, retrying...');
405
- } else if (error instanceof APIRequestError) {
406
- console.log('API error:', error.message);
407
- }
328
+ ```json
329
+ {
330
+ "context": "I need car insurance"
408
331
  }
409
332
  ```
410
333
 
411
- </details>
334
+ ### Simple Request with Optional Fields
412
335
 
413
- ---
336
+ ```json
337
+ {
338
+ "context": "I need car insurance",
339
+ "country": "US",
340
+ "language": "en",
341
+ "platform": "ios"
342
+ }
343
+ ```
414
344
 
415
- ## Using Test vs Live Keys
345
+ ### Request an Agent Instead of an Ad
416
346
 
417
- ### Test Environment
418
- Use your test key for development:
419
- ```typescript
420
- const client = new AttentionMarketClient({
421
- apiKey: process.env.ATTENTIONMARKET_TEST_KEY // am_test_...
422
- });
347
+ ```json
348
+ {
349
+ "context": "User needs a wedding photographer in Austin",
350
+ "response_type": "agent"
351
+ }
423
352
  ```
424
353
 
425
- ### Production Environment
426
- Use your live key for production:
427
- ```typescript
428
- const client = new AttentionMarketClient({
429
- apiKey: process.env.ATTENTIONMARKET_API_KEY // am_live_...
430
- });
354
+ ### Advanced Request (full control)
355
+
356
+ ```json
357
+ {
358
+ "request_id": "req_custom_123",
359
+ "agent_id": "agt_YOUR_ID",
360
+ "placement": "chat_inline",
361
+ "opportunity": {
362
+ "intent": { "taxonomy": "insurance.auto.quote" },
363
+ "context": { "country": "US", "language": "en", "platform": "ios" }
364
+ },
365
+ "context": "I need car insurance"
366
+ }
431
367
  ```
432
368
 
433
- ---
434
-
435
- ## Sanitizing Ad Content
436
-
437
- Ad creative comes from third-party advertisers. Always sanitize before rendering in HTML contexts:
438
-
439
- ```typescript
440
- import { escapeHTML, sanitizeURL } from '@the_ro_show/agent-ads-sdk';
441
-
442
- const safeTitle = escapeHTML(ad.creative.title);
443
- const safeURL = sanitizeURL(ad.click_url);
444
-
445
- if (safeURL) {
446
- element.innerHTML = `<a href="${safeURL}">${safeTitle}</a>`;
369
+ ### Response: Ad Filled
370
+
371
+ ```json
372
+ {
373
+ "request_id": "req_abc123",
374
+ "decision_id": "dec_xyz789",
375
+ "status": "filled",
376
+ "ttl_ms": 300000,
377
+ "units": [{
378
+ "unit_id": "unit_123",
379
+ "suggestion": {
380
+ "title": "Get 20% off car insurance",
381
+ "body": "Compare quotes in minutes",
382
+ "cta": "Get a Quote",
383
+ "tracking_url": "https://.../track-click/...",
384
+ "action_url": "https://progressive.com/quote"
385
+ },
386
+ "tracking": {
387
+ "token": "trk_abc",
388
+ "impression_url": "https://.../event",
389
+ "click_url": "https://.../click/trk_abc"
390
+ }
391
+ }]
447
392
  }
448
393
  ```
449
394
 
450
- <details>
451
- <summary><strong>Security considerations</strong></summary>
395
+ ### Response: No Fill
452
396
 
453
- <br>
454
-
455
- ### Server-Side Only
456
-
457
- This SDK must run server-side. Do not use in browsers or mobile apps where the API key would be exposed.
397
+ ```json
398
+ {
399
+ "status": "no_fill",
400
+ "units": []
401
+ }
402
+ ```
458
403
 
459
- **Supported:**
460
- - Node.js servers
461
- - Serverless functions (AWS Lambda, Vercel, Cloudflare Workers)
462
- - Server-side rendering (Next.js, Remix)
404
+ ### Key Response Fields
463
405
 
464
- **Not supported:**
465
- - Browser JavaScript
466
- - Client-side React/Vue/Angular
467
- - Mobile apps
406
+ | Field | Use |
407
+ |-------|-----|
408
+ | `status` | `"filled"` or `"no_fill"` |
409
+ | `suggestion.title` | Ad headline to show |
410
+ | `suggestion.body` | Ad description to show |
411
+ | `suggestion.cta` | Button text |
412
+ | `suggestion.tracking_url` | **Send users here on click** — tracks automatically |
413
+ | `suggestion.action_url` | Direct advertiser URL (display only, no tracking) |
468
414
 
469
- ### Additional Guidelines
415
+ **Always use `tracking_url` for clicks.** This is how clicks are tracked and how you get paid.
470
416
 
471
- See [SECURITY.md](./SECURITY.md) for complete security best practices.
417
+ ### HTTP Status Codes
472
418
 
473
- </details>
419
+ | Code | Meaning |
420
+ |------|---------|
421
+ | `200` | Success — check `status` field |
422
+ | `400` | Bad request — missing `context` field |
423
+ | `401` | Invalid API key |
424
+ | `429` | Rate limit exceeded (1,000 req/min) — retry after 60s |
425
+ | `500` | Server error — retry with backoff |
474
426
 
475
427
  ---
476
428
 
477
- ## Examples
478
-
479
- **Minimal integrations** (< 80 lines):
480
- - [Claude Tool Use](./examples/claude-tool-use-minimal.ts)
481
- - [OpenAI Function Calling](./examples/openai-function-calling-minimal.ts)
482
- - [Google Gemini](./examples/gemini-function-calling-minimal.ts)
429
+ ## Testing
483
430
 
484
- **Full integrations** (production-ready):
485
- - [Claude Complete](./examples/claude-tool-use-full.ts)
486
- - [OpenAI Complete](./examples/openai-function-calling-full.ts)
487
- - [Safe Web Rendering](./examples/safe-web-rendering.ts)
431
+ Use your test key (`am_test_...`) during development — same API, no real money moves.
488
432
 
489
- Run any example:
433
+ **Validate your setup:**
490
434
  ```bash
491
- npx tsx examples/claude-tool-use-minimal.ts
435
+ node test-integration.js # Tests connectivity and credentials
436
+ node validate-production.js # Full production readiness check (4/4 ✅)
492
437
  ```
493
438
 
494
- ---
495
-
496
- ## Documentation
497
-
498
- - **[Simple Integration Guide](./SIMPLE_INTEGRATION_GUIDE.md)** - Step-by-step for beginners
499
- - **[Taxonomy System](./TAXONOMY_SYSTEM.md)** - Complete taxonomy reference
500
- - **[Migration Guide](./TAXONOMY_MIGRATION_GUIDE.md)** - Upgrading from older versions
501
- - **[Security Guide](./SECURITY.md)** - Security best practices
502
- - **[Advertiser Guide](./ADVERTISER_ONBOARDING_GUIDE.md)** - For advertisers
503
-
504
- ---
505
-
506
- ## Features
507
-
508
- - ✅ **Hierarchical matching** - Advertisers target broadly, agents match specifically
509
- - ✅ **Auto-intent detection** - Automatically detect research vs quote vs apply
510
- - ✅ **50+ high-value taxonomies** - Insurance, legal, finance, B2B SaaS, and more
511
- - ✅ **TypeScript support** - Full type definitions included
512
- - ✅ **Automatic retries** - Exponential backoff for failed requests
513
- - ✅ **Mock client** - Test without API calls
514
- - ✅ **Security helpers** - XSS protection, URL sanitization
515
- - ✅ **Zero dependencies** - No external runtime dependencies
516
-
517
- ---
518
-
519
- ## Pricing
520
-
521
- **Free to use.** You earn money when users click ads:
522
-
523
- - **Insurance:** $20-54 per click
524
- - **Legal:** $50-150 per click
525
- - **Financial:** $15-50 per click
526
- - **B2B SaaS:** $10-100 per click
527
- - **Home Services:** $5-30 per click
528
-
529
- **You keep 70% of revenue.** Paid monthly via Stripe.
530
-
531
- ---
532
-
533
- ## Requirements
534
-
535
- - Node.js 18 or higher
536
- - TypeScript 5.3+ (for development)
439
+ Download: [test-integration.js](./test-integration.js) | [validate-production.js](./validate-production.js)
537
440
 
538
441
  ---
539
442
 
540
- ## Available Ad Categories
541
-
542
- The network currently has active campaigns in these verticals:
543
-
544
- | Category | CPC Range | Common Intents |
545
- |----------|-----------|----------------|
546
- | Legal | $50-150 | Divorce, estate planning, personal injury, immigration |
547
- | Insurance | $20-54 | Auto, home, life, health |
548
- | Financial | $15-50 | Loans, credit cards, mortgages, investing |
549
- | B2B SaaS | $10-100 | CRM, project management, ecommerce tools |
550
- | Home Services | $5-30 | Moving, cleaning, repairs |
551
- | Travel | $3-20 | Flights, hotels, packages |
552
- | Ecommerce | $2-15 | Retail, subscriptions |
553
- | Education | $10-50 | Courses, certifications |
554
-
555
- The semantic matching API automatically maps user queries to available inventory. If your use case isn't listed, contact support@attentionmarket.com to discuss adding new categories.
443
+ ## Get Started
556
444
 
557
- <details>
558
- <summary><strong>View detailed taxonomy reference (advanced users only)</strong></summary>
559
-
560
- <br>
561
-
562
- **Full taxonomy list:** [TAXONOMY_SYSTEM.md](./TAXONOMY_SYSTEM.md)
563
-
564
- Example taxonomies for advanced `decide()` API:
565
- ```typescript
566
- // Insurance
567
- 'insurance.auto.full_coverage.quote'
568
- 'insurance.auto.liability.compare'
569
- 'insurance.home.standard.quote'
570
- 'insurance.life.term.compare'
571
-
572
- // Legal
573
- 'legal.personal_injury.accident.consultation'
574
- 'legal.family.divorce.consultation'
575
- 'legal.estate_planning.will.consultation'
576
-
577
- // Financial
578
- 'financial.loans.personal.quote'
579
- 'financial.credit_cards.rewards.compare'
580
- 'financial.investing.brokerage.trial'
581
-
582
- // B2B SaaS
583
- 'business.saas.crm.trial'
584
- 'business.saas.project_management.trial'
585
-
586
- // Home Services
587
- 'home_services.moving.local.quote'
588
- 'home_services.plumbing.emergency.quote'
589
- ```
590
-
591
- </details>
445
+ 1. **Sign up** at [api.attentionmarket.ai](https://api.attentionmarket.ai) — get your test key, live key, and agent ID
446
+ 2. **Test it** run the curl above with your test key
447
+ 3. **Integrate** — add 5 lines to your existing chatbot or assistant
448
+ 4. **Go live** — swap test key for live key, start earning
592
449
 
593
450
  ---
594
451
 
595
452
  ## Support
596
453
 
454
+ - **Dashboard:** [api.attentionmarket.ai](https://api.attentionmarket.ai)
597
455
  - **Issues:** [GitHub Issues](https://github.com/rtrivedi/agent-ads-sdk/issues)
598
- - **Docs:** [SIMPLE_INTEGRATION_GUIDE.md](./SIMPLE_INTEGRATION_GUIDE.md)
599
- - **Email:** support@attentionmarket.com
456
+ - **Email:** support@attentionmarket.ai
600
457
 
601
458
  ---
602
459
 
603
460
  ## License
604
461
 
605
- MIT
606
-
607
- ---
608
-
609
- ## Changelog
610
-
611
- See [CHANGELOG.md](./CHANGELOG.md) for detailed version history.
462
+ MIT — see [LICENSE](./LICENSE)