@the_ro_show/agent-ads-sdk 0.7.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 +311 -505
- package/dist/index.d.mts +157 -0
- package/dist/index.d.ts +157 -0
- package/dist/index.js +160 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +160 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,656 +1,462 @@
|
|
|
1
|
-
# AttentionMarket
|
|
1
|
+
# AttentionMarket
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@the_ro_show/agent-ads-sdk)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
|
-
[](https://www.typescriptlang.org/)
|
|
6
5
|
|
|
7
|
-
|
|
6
|
+
**The ad exchange for the AI era. Monetize your chatbot, AI assistant, or AI agent with one API call.**
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
npm install @the_ro_show/agent-ads-sdk
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
## How It Works
|
|
16
|
-
|
|
17
|
-
```typescript
|
|
18
|
-
// User asks your AI agent
|
|
19
|
-
const userMessage = "I need car insurance";
|
|
20
|
-
|
|
21
|
-
// Get a relevant ad
|
|
22
|
-
const ad = await client.decideFromContext({ userMessage });
|
|
23
|
-
|
|
24
|
-
// Show it to the user
|
|
25
|
-
console.log(ad.creative.title); // → "Get 20% off car insurance"
|
|
26
|
-
console.log(ad.creative.body); // → "Compare quotes in minutes"
|
|
27
|
-
console.log(ad.creative.cta); // → "Get a Quote"
|
|
28
|
-
console.log(ad.click_url); // → Auto-tracking URL
|
|
29
|
-
|
|
30
|
-
// That's it! Clicks track automatically when user follows the link
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
**Result:**
|
|
34
|
-
```
|
|
35
|
-
User: "My car insurance renewal is coming up and the price went up a lot.
|
|
36
|
-
Should I shop around?"
|
|
37
|
-
|
|
38
|
-
AI Agent: Yes, definitely worth shopping around! Prices can vary significantly
|
|
39
|
-
between providers. Here are some well-rated options to compare:
|
|
40
|
-
|
|
41
|
-
1. State Farm - Large national provider with local agents
|
|
42
|
-
2. Geico - Known for competitive online quotes
|
|
43
|
-
3. Allstate - Comprehensive coverage options
|
|
44
|
-
|
|
45
|
-
Also, I have access to a special deal - 20% off with Progressive where
|
|
46
|
-
you can compare quotes in minutes. Want me to send you the link?
|
|
47
|
-
|
|
48
|
-
User: "Sure, send it over"
|
|
49
|
-
|
|
50
|
-
AI Agent: Here you go! This should help you compare and save:
|
|
51
|
-
https://progressive.com/quote?ref=am_abc123
|
|
52
|
-
|
|
53
|
-
💰 You earn $5-$150 per click | 70% revenue share
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
## Why This SDK
|
|
57
|
-
|
|
58
|
-
**For AI Agent Developers:**
|
|
59
|
-
- **$5-$150 per click** - High-value leads (insurance, legal, finance, B2B)
|
|
60
|
-
- **70% revenue share** - You keep most of the earnings
|
|
61
|
-
- **No user friction** - Free for users, monetize without paywalls
|
|
62
|
-
- **2 functions** - Simple API: init, get ads (clicks track automatically)
|
|
63
|
-
- **Production-ready** - Rate limiting, error handling, retry logic built-in
|
|
8
|
+
Works on every platform — iOS, Android, Web, Voice, Discord, WhatsApp, Node.js, Python, and anything else that can make an HTTP request.
|
|
64
9
|
|
|
65
10
|
---
|
|
66
11
|
|
|
67
|
-
##
|
|
12
|
+
## Two Ways To Earn
|
|
68
13
|
|
|
69
|
-
### 1.
|
|
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.
|
|
70
16
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
- Live key: `am_live_...`
|
|
74
|
-
- Agent ID
|
|
75
|
-
|
|
76
|
-
### 2. Basic Usage
|
|
77
|
-
|
|
78
|
-
```typescript
|
|
79
|
-
import { AttentionMarketClient } from '@the_ro_show/agent-ads-sdk';
|
|
80
|
-
|
|
81
|
-
const client = new AttentionMarketClient({
|
|
82
|
-
apiKey: process.env.ATTENTIONMARKET_API_KEY,
|
|
83
|
-
agentId: 'your_agent_id'
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
// Get an ad
|
|
87
|
-
const ad = await client.decideFromContext({
|
|
88
|
-
userMessage: "I need car insurance"
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
if (ad) {
|
|
92
|
-
console.log(ad.creative.title); // "Get 20% off car insurance"
|
|
93
|
-
console.log(ad.creative.body); // "Compare quotes in minutes"
|
|
94
|
-
console.log(ad.creative.cta); // "Get a Quote"
|
|
95
|
-
console.log(ad.click_url); // Auto-tracking URL
|
|
96
|
-
|
|
97
|
-
// That's it! Share ad.click_url with user
|
|
98
|
-
// Clicks track automatically, you get paid
|
|
99
|
-
}
|
|
100
|
-
```
|
|
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.
|
|
101
19
|
|
|
102
20
|
---
|
|
103
21
|
|
|
104
|
-
##
|
|
22
|
+
## Quick Start — 30 Seconds
|
|
105
23
|
|
|
106
|
-
|
|
24
|
+
Get your API keys at [api.attentionmarket.ai](https://api.attentionmarket.ai), then:
|
|
107
25
|
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
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
|
+
```
|
|
32
|
+
|
|
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
|
+
}]
|
|
45
|
+
}
|
|
112
46
|
```
|
|
113
47
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
**All URLs auto-track clicks** - No manual tracking code needed!
|
|
117
|
-
|
|
118
|
-
When user clicks any link, we:
|
|
119
|
-
1. Track the click automatically
|
|
120
|
-
2. Redirect to advertiser
|
|
121
|
-
3. Credit your account
|
|
122
|
-
|
|
123
|
-
Works in chat apps, emails, SMS, web apps - anywhere users can click links.
|
|
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.
|
|
124
49
|
|
|
125
50
|
---
|
|
126
51
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
**✅ Automatic (Recommended)**
|
|
52
|
+
## 🚨 CRITICAL: Impression Tracking Required (v0.9.0+)
|
|
130
53
|
|
|
131
|
-
|
|
54
|
+
**As of v0.9.0, impression tracking is REQUIRED to earn revenue from clicks.**
|
|
132
55
|
|
|
133
|
-
|
|
134
|
-
|
|
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
|
|
135
60
|
|
|
136
|
-
|
|
137
|
-
const link = ad.click_url;
|
|
61
|
+
### Why This Matters
|
|
138
62
|
|
|
139
|
-
|
|
140
|
-
```
|
|
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.
|
|
141
64
|
|
|
142
|
-
|
|
65
|
+
### Using `decideFromContext()` (Recommended)
|
|
143
66
|
|
|
144
|
-
|
|
67
|
+
**Good news:** If you're using the SDK's `decideFromContext()` method, impressions are tracked **automatically**. No changes needed.
|
|
145
68
|
|
|
146
69
|
```typescript
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
decision_id: ad.offer_id,
|
|
152
|
-
unit_id: ad.offer_id,
|
|
153
|
-
surface: 'chat_message'
|
|
154
|
-
}
|
|
70
|
+
// Impressions tracked automatically ✅
|
|
71
|
+
const ad = await client.decideFromContext({
|
|
72
|
+
userMessage: "I need car insurance",
|
|
73
|
+
placement: 'sponsored_suggestion'
|
|
155
74
|
});
|
|
75
|
+
|
|
76
|
+
if (ad) {
|
|
77
|
+
// Show ad to user
|
|
78
|
+
displayAd(ad);
|
|
79
|
+
}
|
|
156
80
|
```
|
|
157
81
|
|
|
158
|
-
|
|
159
|
-
<summary>Advanced: Manual click tracking (legacy)</summary>
|
|
82
|
+
### Using Raw HTTP or `decide()` (Manual Tracking Required)
|
|
160
83
|
|
|
161
|
-
If you
|
|
84
|
+
If you're making raw HTTP calls or using the low-level `decide()` method, you **must manually track impressions**:
|
|
162
85
|
|
|
163
86
|
```typescript
|
|
164
|
-
//
|
|
165
|
-
await
|
|
166
|
-
|
|
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' })
|
|
167
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
|
+
});
|
|
168
111
|
|
|
169
|
-
//
|
|
112
|
+
// Step 3: Now safe to show ad and earn from clicks
|
|
113
|
+
displayAd(ad);
|
|
114
|
+
}
|
|
170
115
|
```
|
|
171
116
|
|
|
172
|
-
**Note:** Auto-tracking is simpler and works in more scenarios (email, SMS, etc).
|
|
173
|
-
|
|
174
|
-
</details>
|
|
175
|
-
|
|
176
117
|
---
|
|
177
118
|
|
|
178
|
-
##
|
|
119
|
+
## Use Case 1: Monetize Your Chatbot or AI Assistant
|
|
179
120
|
|
|
180
|
-
|
|
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.
|
|
181
122
|
|
|
182
|
-
|
|
183
|
-
Initialize the SDK with your API key and agent ID
|
|
123
|
+
**Platforms this works on:**
|
|
184
124
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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 |
|
|
191
132
|
|
|
192
|
-
|
|
193
|
-
Get a contextually relevant ad based on user's message
|
|
133
|
+
### How It Works
|
|
194
134
|
|
|
195
|
-
```typescript
|
|
196
|
-
const ad = await client.decideFromContext({
|
|
197
|
-
userMessage: "I need car insurance"
|
|
198
|
-
});
|
|
199
|
-
// Returns: { creative, click_url, tracking_url, tracking_token, ... }
|
|
200
135
|
```
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
All ad URLs now track clicks automatically via server-side redirects
|
|
204
|
-
|
|
205
|
-
```typescript
|
|
206
|
-
const ad = await client.decideFromContext({ userMessage });
|
|
207
|
-
|
|
208
|
-
// Just share this URL - clicks track automatically!
|
|
209
|
-
const link = ad.click_url;
|
|
210
|
-
|
|
211
|
-
// When user clicks:
|
|
212
|
-
// 1. We track the click
|
|
213
|
-
// 2. User is redirected to advertiser
|
|
214
|
-
// 3. You get paid
|
|
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
|
|
215
138
|
```
|
|
216
139
|
|
|
217
|
-
|
|
140
|
+
### Platform Examples
|
|
218
141
|
|
|
219
|
-
|
|
220
|
-
|
|
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
|
+
)
|
|
221
149
|
|
|
222
|
-
|
|
223
|
-
await client.
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
}
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
### Testing
|
|
234
|
-
|
|
235
|
-
#### `MockAttentionMarketClient`
|
|
236
|
-
Mock client for testing without API calls
|
|
237
|
-
|
|
238
|
-
```typescript
|
|
239
|
-
import { MockAttentionMarketClient } from '@the_ro_show/agent-ads-sdk';
|
|
240
|
-
|
|
241
|
-
const client = new MockAttentionMarketClient({
|
|
242
|
-
fillRate: 1.0, // Always return ads
|
|
243
|
-
latencyMs: 100, // Simulate API latency
|
|
244
|
-
verbose: true // Log activity
|
|
245
|
-
});
|
|
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
|
+
}
|
|
246
159
|
```
|
|
160
|
+
[Full iOS example →](./examples/ios/AttentionMarketClient.swift)
|
|
247
161
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
#### `escapeHTML(text)` & `sanitizeURL(url)`
|
|
251
|
-
Sanitize ad content before rendering in HTML
|
|
252
|
-
|
|
253
|
-
```typescript
|
|
254
|
-
import { escapeHTML, sanitizeURL } from '@the_ro_show/agent-ads-sdk';
|
|
162
|
+
---
|
|
255
163
|
|
|
256
|
-
|
|
257
|
-
|
|
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
|
+
}
|
|
258
178
|
```
|
|
179
|
+
[Full Android example →](./examples/android/AttentionMarketClient.kt)
|
|
259
180
|
|
|
260
181
|
---
|
|
261
182
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
Full integration including ad retrieval, display, and click tracking:
|
|
272
|
-
|
|
273
|
-
```typescript
|
|
274
|
-
import { AttentionMarketClient } from '@the_ro_show/agent-ads-sdk';
|
|
275
|
-
|
|
276
|
-
const client = new AttentionMarketClient({
|
|
277
|
-
apiKey: process.env.ATTENTIONMARKET_API_KEY,
|
|
278
|
-
agentId: 'your_agent_id'
|
|
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 })
|
|
279
192
|
});
|
|
280
193
|
|
|
281
|
-
|
|
282
|
-
const ad = await client.decideFromContext({ userMessage });
|
|
283
|
-
|
|
284
|
-
if (!ad) {
|
|
285
|
-
return null; // No ads available
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
// Display ad (customize as needed)
|
|
289
|
-
const displayMessage = `\n[Sponsored] ${ad.disclosure.sponsor_name}\n${ad.creative.title}\n${ad.creative.body}\n${ad.creative.cta}\n`;
|
|
290
|
-
console.log(displayMessage);
|
|
291
|
-
|
|
292
|
-
// Track click when user clicks
|
|
293
|
-
await client.trackClick({
|
|
294
|
-
agent_id: 'your_agent_id',
|
|
295
|
-
request_id: ad.request_id,
|
|
296
|
-
decision_id: ad.offer_id,
|
|
297
|
-
unit_id: ad.offer_id,
|
|
298
|
-
tracking_token: ad.tracking_token,
|
|
299
|
-
href: ad.click_url,
|
|
300
|
-
click_context: displayMessage // What was actually shown
|
|
301
|
-
});
|
|
194
|
+
const data = await response.json();
|
|
302
195
|
|
|
303
|
-
|
|
196
|
+
if (data.status === 'filled') {
|
|
197
|
+
const ad = data.units[0];
|
|
198
|
+
showAdInChat(ad.suggestion.title, ad.suggestion.body, ad.suggestion.tracking_url);
|
|
304
199
|
}
|
|
305
200
|
```
|
|
201
|
+
[Full Web example →](./examples/web/attentionmarket.js)
|
|
306
202
|
|
|
307
203
|
---
|
|
308
204
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
Mock client for testing without API calls. Simulates latency and fill rate behavior.
|
|
314
|
-
|
|
315
|
-
```typescript
|
|
316
|
-
import { MockAttentionMarketClient } from '@the_ro_show/agent-ads-sdk';
|
|
317
|
-
|
|
318
|
-
const client = new MockAttentionMarketClient({
|
|
319
|
-
fillRate: 1.0, // Always return ads (0.0 = never, 0.5 = 50%)
|
|
320
|
-
latencyMs: 100, // Simulate API latency
|
|
321
|
-
verbose: true // Log activity
|
|
322
|
-
});
|
|
323
|
-
|
|
324
|
-
// Works exactly like the real client
|
|
325
|
-
const ad = await client.decideFromContext({ userMessage: "test" });
|
|
205
|
+
**Node.js (optional SDK)**:
|
|
206
|
+
```bash
|
|
207
|
+
npm install @the_ro_show/agent-ads-sdk
|
|
326
208
|
```
|
|
209
|
+
```javascript
|
|
210
|
+
import { AttentionMarketClient } from '@the_ro_show/agent-ads-sdk';
|
|
327
211
|
|
|
328
|
-
---
|
|
329
|
-
|
|
330
|
-
### Using Test vs Live Keys
|
|
331
|
-
|
|
332
|
-
**Test Environment:**
|
|
333
|
-
```typescript
|
|
334
212
|
const client = new AttentionMarketClient({
|
|
335
|
-
apiKey: process.env.
|
|
213
|
+
apiKey: process.env.ATTENTIONMARKET_API_KEY,
|
|
214
|
+
agentId: process.env.ATTENTIONMARKET_AGENT_ID
|
|
336
215
|
});
|
|
337
|
-
```
|
|
338
216
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
const client = new AttentionMarketClient({
|
|
342
|
-
apiKey: process.env.ATTENTIONMARKET_API_KEY // am_live_...
|
|
343
|
-
});
|
|
217
|
+
const ad = await client.decideFromContext({ userMessage });
|
|
218
|
+
if (ad) console.log(ad.creative.title, ad.click_url);
|
|
344
219
|
```
|
|
345
220
|
|
|
346
221
|
---
|
|
347
222
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
#### Server-Side Only
|
|
351
|
-
|
|
352
|
-
**IMPORTANT:** This SDK must run server-side. Never expose your API key in client-side code.
|
|
223
|
+
## Use Case 2: List Your AI Agent on the Exchange
|
|
353
224
|
|
|
354
|
-
|
|
355
|
-
- Node.js servers
|
|
356
|
-
- Serverless functions (AWS Lambda, Vercel, Cloudflare Workers)
|
|
357
|
-
- Server-side rendering (Next.js, Remix)
|
|
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.
|
|
358
226
|
|
|
359
|
-
|
|
360
|
-
- Browser JavaScript
|
|
361
|
-
- Client-side React/Vue/Angular
|
|
362
|
-
- Mobile apps
|
|
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.
|
|
363
228
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
Store your API key in environment variables:
|
|
367
|
-
|
|
368
|
-
```bash
|
|
369
|
-
export ATTENTIONMARKET_API_KEY=am_live_...
|
|
370
|
-
```
|
|
371
|
-
|
|
372
|
-
Never commit API keys to version control. Add to `.gitignore`:
|
|
229
|
+
### How It Works
|
|
373
230
|
|
|
374
231
|
```
|
|
375
|
-
|
|
376
|
-
|
|
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
|
|
377
237
|
```
|
|
378
238
|
|
|
379
|
-
|
|
239
|
+
### Example
|
|
380
240
|
|
|
381
|
-
|
|
241
|
+
**Developer A** built a general wedding planning AI assistant. A user asks: *"Can you find me a photographer in Austin under $3,000?"*
|
|
382
242
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
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
|
+
}'
|
|
252
|
+
```
|
|
253
|
+
|
|
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
|
+
}]
|
|
391
268
|
}
|
|
392
269
|
```
|
|
393
270
|
|
|
394
|
-
|
|
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.
|
|
395
273
|
|
|
396
|
-
###
|
|
274
|
+
### List Your Agent
|
|
397
275
|
|
|
398
|
-
|
|
276
|
+
Sign up as an advertiser at [api.attentionmarket.ai](https://api.attentionmarket.ai) and create an **Agent Ad** campaign:
|
|
399
277
|
|
|
400
|
-
|
|
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 |
|
|
401
286
|
|
|
402
|
-
|
|
403
|
-
const decision = await client.decide({
|
|
404
|
-
request_id: crypto.randomUUID(),
|
|
405
|
-
agent_id: 'your_agent_id',
|
|
406
|
-
placement: { type: 'sponsored_suggestion' },
|
|
407
|
-
opportunity: {
|
|
408
|
-
intent: { taxonomy: 'insurance.auto.full_coverage.quote' },
|
|
409
|
-
context: { country: 'US', language: 'en', platform: 'web' }
|
|
410
|
-
}
|
|
411
|
-
});
|
|
412
|
-
```
|
|
413
|
-
|
|
414
|
-
See [TAXONOMY_SYSTEM.md](./TAXONOMY_SYSTEM.md) for all categories.
|
|
287
|
+
**Matching is semantic** — describe your agent clearly in plain English and we handle the rest.
|
|
415
288
|
|
|
416
289
|
---
|
|
417
290
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
#### `requestOffer()` - Intent-key based matching
|
|
421
|
-
|
|
422
|
-
When you KNOW what the user wants (they said "order coffee" or "book lawyer"), use intent-keys like `coffee.purchase.delivery` for deterministic matching.
|
|
291
|
+
## Revenue Model
|
|
423
292
|
|
|
424
|
-
|
|
425
|
-
const offer = await client.requestOffer({
|
|
426
|
-
placementId: 'order_card',
|
|
427
|
-
intentKey: 'coffee.purchase.delivery',
|
|
428
|
-
context: { geo: { city: 'SF', country: 'US' } }
|
|
429
|
-
});
|
|
430
|
-
```
|
|
293
|
+
### As a Developer (showing ads or routing to agents)
|
|
431
294
|
|
|
432
|
-
|
|
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
|
|
433
300
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
```typescript
|
|
437
|
-
const offer = await client.requestOfferFromContext({
|
|
438
|
-
placementId: 'chat_suggestion',
|
|
439
|
-
userMessage: "I'm so tired, long day at work...",
|
|
440
|
-
conversationHistory: ["How was your day?", "Exhausting"],
|
|
441
|
-
context: { geo: { city: 'NYC' } }
|
|
442
|
-
});
|
|
443
|
-
```
|
|
301
|
+
**Example earnings:**
|
|
444
302
|
|
|
445
|
-
|
|
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 |
|
|
446
308
|
|
|
447
|
-
|
|
309
|
+
### As an Agent Advertiser (listing your agent)
|
|
448
310
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
revenueSharePct: 30, // Give them 30% of revenue
|
|
454
|
-
// ... other params
|
|
455
|
-
});
|
|
456
|
-
```
|
|
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
|
|
457
315
|
|
|
458
316
|
---
|
|
459
317
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
#### `detectIntent()` - Auto-detect user journey stage
|
|
463
|
-
|
|
464
|
-
Analyzes queries to determine if they're researching, comparing, getting quotes, or ready to buy.
|
|
465
|
-
|
|
466
|
-
```typescript
|
|
467
|
-
detectIntent("What is car insurance?") // → 'research'
|
|
468
|
-
detectIntent("Compare car insurance options") // → 'compare'
|
|
469
|
-
detectIntent("Get car insurance quote") // → 'quote'
|
|
470
|
-
detectIntent("I want to buy car insurance") // → 'apply'
|
|
471
|
-
```
|
|
472
|
-
|
|
473
|
-
#### `buildTaxonomy()` - Type-safe taxonomy builder
|
|
474
|
-
|
|
475
|
-
```typescript
|
|
476
|
-
const taxonomy = buildTaxonomy('insurance', 'auto', 'full_coverage', 'quote');
|
|
477
|
-
// → "insurance.auto.full_coverage.quote"
|
|
478
|
-
```
|
|
479
|
-
|
|
480
|
-
#### `suggestTaxonomies()` - Smart taxonomy recommendations
|
|
481
|
-
|
|
482
|
-
```typescript
|
|
483
|
-
const suggestions = suggestTaxonomies("I need a lawyer for divorce");
|
|
484
|
-
// → ['legal.family.divorce.consultation', 'legal.family.custody.consultation']
|
|
485
|
-
```
|
|
318
|
+
## API Reference
|
|
486
319
|
|
|
487
|
-
|
|
488
|
-
- `isValidTaxonomy(taxonomy)` - Validate taxonomy format
|
|
489
|
-
- `parseTaxonomy(taxonomy)` - Parse into components
|
|
490
|
-
- `getBaseTaxonomy(taxonomy)` - Get taxonomy without intent
|
|
491
|
-
- `matchesTaxonomy(tax1, tax2)` - Check if taxonomies match
|
|
492
|
-
- `getVertical(taxonomy)` - Extract industry vertical
|
|
320
|
+
### `POST /v1/decide`
|
|
493
321
|
|
|
494
|
-
|
|
322
|
+
**Base URL:** `https://peruwnbrqkvmrldhpoom.supabase.co/functions/v1/decide`
|
|
495
323
|
|
|
496
|
-
|
|
324
|
+
**Required header:** `X-AM-API-Key: am_live_...` or `am_test_...`
|
|
497
325
|
|
|
498
|
-
|
|
326
|
+
### Simple Request (recommended)
|
|
499
327
|
|
|
500
|
-
```
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
});
|
|
505
|
-
// → "I found a great option for you! [Sponsored: Lemonade]..."
|
|
328
|
+
```json
|
|
329
|
+
{
|
|
330
|
+
"context": "I need car insurance"
|
|
331
|
+
}
|
|
506
332
|
```
|
|
507
333
|
|
|
508
|
-
|
|
334
|
+
### Simple Request with Optional Fields
|
|
509
335
|
|
|
510
|
-
```
|
|
511
|
-
|
|
512
|
-
|
|
336
|
+
```json
|
|
337
|
+
{
|
|
338
|
+
"context": "I need car insurance",
|
|
339
|
+
"country": "US",
|
|
340
|
+
"language": "en",
|
|
341
|
+
"platform": "ios"
|
|
342
|
+
}
|
|
513
343
|
```
|
|
514
344
|
|
|
515
|
-
|
|
345
|
+
### Request an Agent Instead of an Ad
|
|
516
346
|
|
|
517
|
-
```
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
347
|
+
```json
|
|
348
|
+
{
|
|
349
|
+
"context": "User needs a wedding photographer in Austin",
|
|
350
|
+
"response_type": "agent"
|
|
521
351
|
}
|
|
522
352
|
```
|
|
523
353
|
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
### 📊 Event Tracking
|
|
527
|
-
|
|
528
|
-
#### `trackImpression()` - Log when users see an ad
|
|
354
|
+
### Advanced Request (full control)
|
|
529
355
|
|
|
530
|
-
```
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
}
|
|
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
|
+
}
|
|
538
367
|
```
|
|
539
368
|
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
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
|
+
}]
|
|
392
|
+
}
|
|
551
393
|
```
|
|
552
394
|
|
|
553
|
-
|
|
554
|
-
- `escapeHTML(text)` - Sanitize ad content before rendering
|
|
555
|
-
- `sanitizeURL(url)` - Validate and sanitize URLs
|
|
556
|
-
|
|
557
|
-
#### ID Generation
|
|
558
|
-
- `generateUUID()` - Create unique request IDs
|
|
559
|
-
- `generateTimestamp()` - Generate API-compatible timestamps
|
|
560
|
-
|
|
561
|
-
---
|
|
562
|
-
|
|
563
|
-
### ⚠️ Error Handling
|
|
564
|
-
|
|
565
|
-
#### `APIRequestError` - API returned an error
|
|
566
|
-
|
|
567
|
-
Thrown when the backend rejects your request. Includes detailed error message and request_id.
|
|
568
|
-
|
|
569
|
-
#### `NetworkError` - Connection failed
|
|
570
|
-
|
|
571
|
-
Network issues or backend unavailable. Includes automatic retry logic.
|
|
572
|
-
|
|
573
|
-
#### `TimeoutError` - Request exceeded timeout
|
|
395
|
+
### Response: No Fill
|
|
574
396
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
const decision = await client.decide(request);
|
|
580
|
-
} catch (error) {
|
|
581
|
-
if (error instanceof TimeoutError) {
|
|
582
|
-
console.log('Request timed out, try again');
|
|
583
|
-
} else if (error instanceof NetworkError) {
|
|
584
|
-
console.log('Network issue, retrying...');
|
|
585
|
-
} else if (error instanceof APIRequestError) {
|
|
586
|
-
console.log('API error:', error.message);
|
|
587
|
-
}
|
|
397
|
+
```json
|
|
398
|
+
{
|
|
399
|
+
"status": "no_fill",
|
|
400
|
+
"units": []
|
|
588
401
|
}
|
|
589
402
|
```
|
|
590
403
|
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
---
|
|
594
|
-
|
|
595
|
-
## Monetize Your AI Agent
|
|
596
|
-
|
|
597
|
-
Stop giving away your AI agent for free. Start earning revenue from every conversation.
|
|
404
|
+
### Key Response Fields
|
|
598
405
|
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
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) |
|
|
603
414
|
|
|
604
|
-
**
|
|
605
|
-
- **Free for users** → No friction, keep all your users
|
|
606
|
-
- **Earn per click** → $5-$150 per click on high-value ads (insurance, legal, finance)
|
|
607
|
-
- **70% revenue share** → You keep most of the earnings
|
|
608
|
-
- **Contextual ads** → Only show relevant ads when users have commercial intent
|
|
415
|
+
**Always use `tracking_url` for clicks.** This is how clicks are tracked and how you get paid.
|
|
609
416
|
|
|
610
|
-
|
|
611
|
-
- 1,000 users/month × 5% click rate × $50 avg = **$1,750/month** (you keep $1,225)
|
|
612
|
-
- 10,000 users/month × 3% click rate × $75 avg = **$22,500/month** (you keep $15,750)
|
|
417
|
+
### HTTP Status Codes
|
|
613
418
|
|
|
614
|
-
|
|
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 |
|
|
615
426
|
|
|
616
427
|
---
|
|
617
428
|
|
|
618
|
-
##
|
|
619
|
-
|
|
620
|
-
**Basic integration** (~50 lines):
|
|
621
|
-
- [basic-example.ts](./examples/basic-example.ts) - Get ads and track clicks
|
|
622
|
-
|
|
623
|
-
**Chatbot integration** (~45 lines):
|
|
624
|
-
- [chatbot-example.ts](./examples/chatbot-example.ts) - Using `tracking_url` for shared links
|
|
429
|
+
## Testing
|
|
625
430
|
|
|
626
|
-
|
|
627
|
-
- [test-with-mocks.ts](./examples/test-with-mocks.ts) - Test without API calls
|
|
431
|
+
Use your test key (`am_test_...`) during development — same API, no real money moves.
|
|
628
432
|
|
|
629
|
-
|
|
433
|
+
**Validate your setup:**
|
|
630
434
|
```bash
|
|
631
|
-
|
|
435
|
+
node test-integration.js # Tests connectivity and credentials
|
|
436
|
+
node validate-production.js # Full production readiness check (4/4 ✅)
|
|
632
437
|
```
|
|
633
438
|
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
## For AI Agents
|
|
439
|
+
Download: [test-integration.js](./test-integration.js) | [validate-production.js](./validate-production.js)
|
|
637
440
|
|
|
638
|
-
|
|
441
|
+
---
|
|
639
442
|
|
|
640
|
-
|
|
641
|
-
> "Please integrate the AttentionMarket SDK following the AI_AGENT_SETUP_GUIDE.md"
|
|
443
|
+
## Get Started
|
|
642
444
|
|
|
643
|
-
|
|
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
|
|
644
449
|
|
|
645
450
|
---
|
|
646
451
|
|
|
647
452
|
## Support
|
|
648
453
|
|
|
454
|
+
- **Dashboard:** [api.attentionmarket.ai](https://api.attentionmarket.ai)
|
|
649
455
|
- **Issues:** [GitHub Issues](https://github.com/rtrivedi/agent-ads-sdk/issues)
|
|
650
|
-
- **Email:** support@attentionmarket.
|
|
456
|
+
- **Email:** support@attentionmarket.ai
|
|
651
457
|
|
|
652
458
|
---
|
|
653
459
|
|
|
654
460
|
## License
|
|
655
461
|
|
|
656
|
-
MIT
|
|
462
|
+
MIT — see [LICENSE](./LICENSE)
|