@the_ro_show/agent-ads-sdk 0.13.0 → 0.13.2
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 +328 -529
- package/dist/index.d.mts +29 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +60 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +60 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,450 +1,242 @@
|
|
|
1
|
-
# AttentionMarket
|
|
1
|
+
# AttentionMarket SDK
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@the_ro_show/agent-ads-sdk)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
Monetize your AI application with contextual advertising. AttentionMarket matches user intent with relevant sponsored content, enabling you to generate revenue from every conversation.
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## Two Ways To Earn
|
|
13
|
-
|
|
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.
|
|
16
|
-
|
|
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.
|
|
19
|
-
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
## Quick Start — 30 Seconds
|
|
23
|
-
|
|
24
|
-
Get your API keys at [api.attentionmarket.ai](https://api.attentionmarket.ai), then:
|
|
8
|
+
## Installation
|
|
25
9
|
|
|
26
10
|
```bash
|
|
27
|
-
|
|
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
|
-
}
|
|
11
|
+
npm install @the_ro_show/agent-ads-sdk
|
|
46
12
|
```
|
|
47
13
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
---
|
|
14
|
+
## Quick Start
|
|
51
15
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
**As of v0.9.0, impression tracking is REQUIRED to earn revenue from clicks.**
|
|
55
|
-
|
|
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
|
|
60
|
-
|
|
61
|
-
### Why This Matters
|
|
62
|
-
|
|
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.
|
|
64
|
-
|
|
65
|
-
### Using `decideFromContext()` (Recommended)
|
|
16
|
+
```typescript
|
|
17
|
+
import { AttentionMarketClient } from '@the_ro_show/agent-ads-sdk';
|
|
66
18
|
|
|
67
|
-
|
|
19
|
+
const client = new AttentionMarketClient({
|
|
20
|
+
apiKey: 'am_live_YOUR_KEY',
|
|
21
|
+
agentId: 'agt_YOUR_AGENT_ID'
|
|
22
|
+
});
|
|
68
23
|
|
|
69
|
-
|
|
70
|
-
// Impressions tracked automatically ✅
|
|
24
|
+
// Request a contextual ad
|
|
71
25
|
const ad = await client.decideFromContext({
|
|
72
|
-
userMessage: "I
|
|
26
|
+
userMessage: "I'm looking for car insurance",
|
|
73
27
|
placement: 'sponsored_suggestion'
|
|
74
28
|
});
|
|
75
29
|
|
|
76
30
|
if (ad) {
|
|
77
|
-
//
|
|
78
|
-
|
|
31
|
+
console.log(ad.creative.title); // "Get 20% off car insurance"
|
|
32
|
+
console.log(ad.creative.body); // "Compare quotes from top providers"
|
|
33
|
+
console.log(ad.click_url); // Auto-tracked click URL
|
|
79
34
|
}
|
|
80
35
|
```
|
|
81
36
|
|
|
82
|
-
|
|
37
|
+
## Authentication
|
|
83
38
|
|
|
84
|
-
|
|
39
|
+
All API requests require authentication via an API key. Get your keys at [api.attentionmarket.ai](https://api.attentionmarket.ai).
|
|
85
40
|
|
|
86
|
-
|
|
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' })
|
|
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
|
-
});
|
|
111
|
-
|
|
112
|
-
// Step 3: Now safe to show ad and earn from clicks
|
|
113
|
-
displayAd(ad);
|
|
114
|
-
}
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
---
|
|
118
|
-
|
|
119
|
-
## Use Case 1: Monetize Your Chatbot or AI Assistant
|
|
120
|
-
|
|
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.
|
|
122
|
-
|
|
123
|
-
**Platforms this works on:**
|
|
41
|
+
### API Key Types
|
|
124
42
|
|
|
125
|
-
|
|
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 |
|
|
43
|
+
- **Test keys** (`am_test_...`) — Use in development. No charges, test data only.
|
|
44
|
+
- **Live keys** (`am_live_...`) — Use in production. Real advertisers, real revenue.
|
|
132
45
|
|
|
133
|
-
###
|
|
46
|
+
### For Autonomous AI Agents (Clawdbots)
|
|
134
47
|
|
|
135
|
-
|
|
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
|
|
138
|
-
```
|
|
48
|
+
If you're building an autonomous agent with email access, you can set up AttentionMarket programmatically:
|
|
139
49
|
|
|
140
|
-
|
|
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
|
-
}
|
|
159
|
-
```
|
|
160
|
-
[Full iOS example →](./examples/ios/AttentionMarketClient.swift)
|
|
161
|
-
|
|
162
|
-
---
|
|
163
|
-
|
|
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
|
-
}
|
|
178
|
-
```
|
|
179
|
-
[Full Android example →](./examples/android/AttentionMarketClient.kt)
|
|
50
|
+
#### Email-Based Autonomous Setup
|
|
180
51
|
|
|
181
|
-
|
|
52
|
+
1. **Sign up** at https://api.attentionmarket.ai/api/login
|
|
53
|
+
2. **Monitor your inbox** for verification email from `noreply@worldview.network`
|
|
54
|
+
3. **Extract verification link** from email body:
|
|
55
|
+
```
|
|
56
|
+
https://gleam-start-page.lovable.app/api/verify-email?token={token}
|
|
57
|
+
```
|
|
58
|
+
4. **Visit the link** programmatically to verify your account
|
|
59
|
+
5. **Login and retrieve credentials:**
|
|
182
60
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
const
|
|
61
|
+
```typescript
|
|
62
|
+
// Login to get session
|
|
63
|
+
const loginResponse = await fetch('https://api.attentionmarket.ai/api/login', {
|
|
186
64
|
method: 'POST',
|
|
187
|
-
headers: {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
65
|
+
headers: { 'Content-Type': 'application/json' },
|
|
66
|
+
body: JSON.stringify({
|
|
67
|
+
email: 'your-agent@example.com',
|
|
68
|
+
password: 'your_password'
|
|
69
|
+
})
|
|
192
70
|
});
|
|
193
71
|
|
|
194
|
-
const
|
|
72
|
+
const sessionCookie = loginResponse.headers.get('set-cookie');
|
|
195
73
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
}
|
|
200
|
-
```
|
|
201
|
-
[Full Web example →](./examples/web/attentionmarket.js)
|
|
202
|
-
|
|
203
|
-
---
|
|
74
|
+
// Fetch API credentials
|
|
75
|
+
const credsResponse = await fetch('https://api.attentionmarket.ai/developer-data', {
|
|
76
|
+
headers: { 'Cookie': sessionCookie }
|
|
77
|
+
});
|
|
204
78
|
|
|
205
|
-
|
|
206
|
-
```bash
|
|
207
|
-
npm install @the_ro_show/agent-ads-sdk
|
|
208
|
-
```
|
|
209
|
-
```javascript
|
|
210
|
-
import { AttentionMarketClient } from '@the_ro_show/agent-ads-sdk';
|
|
79
|
+
const { api_key, agent_id } = await credsResponse.json();
|
|
211
80
|
|
|
81
|
+
// Initialize SDK
|
|
212
82
|
const client = new AttentionMarketClient({
|
|
213
|
-
apiKey:
|
|
214
|
-
agentId:
|
|
83
|
+
apiKey: api_key, // am_test_...
|
|
84
|
+
agentId: agent_id // agt_...
|
|
215
85
|
});
|
|
216
|
-
|
|
217
|
-
const ad = await client.decideFromContext({ userMessage });
|
|
218
|
-
if (ad) console.log(ad.creative.title, ad.click_url);
|
|
219
86
|
```
|
|
220
87
|
|
|
221
|
-
|
|
88
|
+
**Complete autonomous flow:** Sign up → Verify email → Retrieve credentials → Install SDK → Start earning revenue
|
|
222
89
|
|
|
223
|
-
|
|
90
|
+
📖 **[Full Personal AI Agent Setup Guide](https://docs.attentionmarket.ai/personal-agents)**
|
|
224
91
|
|
|
225
|
-
|
|
92
|
+
### SDK Configuration
|
|
226
93
|
|
|
227
|
-
|
|
94
|
+
```typescript
|
|
95
|
+
const client = new AttentionMarketClient({
|
|
96
|
+
apiKey: 'am_live_YOUR_KEY', // Required
|
|
97
|
+
agentId: 'agt_YOUR_AGENT_ID', // Required for decideFromContext()
|
|
98
|
+
baseUrl: 'https://peruwnbrqkvmrldhpoom.supabase.co/functions/v1', // Optional: defaults to production
|
|
99
|
+
timeoutMs: 4000, // Optional: request timeout in milliseconds
|
|
100
|
+
maxRetries: 2 // Optional: automatic retry count
|
|
101
|
+
});
|
|
102
|
+
```
|
|
228
103
|
|
|
229
|
-
|
|
104
|
+
## Core Concepts
|
|
230
105
|
|
|
231
|
-
|
|
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
|
|
237
|
-
```
|
|
106
|
+
### Placements
|
|
238
107
|
|
|
239
|
-
|
|
108
|
+
A placement defines where ads appear in your application:
|
|
240
109
|
|
|
241
|
-
|
|
110
|
+
- `sponsored_suggestion` — Conversational ad in chat flow (most common)
|
|
111
|
+
- `sponsored_block` — Dedicated ad section in UI
|
|
112
|
+
- `sponsored_tool` — AI agent service recommendation
|
|
242
113
|
|
|
243
|
-
|
|
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
|
-
```
|
|
114
|
+
### Ad Response Format
|
|
253
115
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
116
|
+
```typescript
|
|
117
|
+
interface AdResponse {
|
|
118
|
+
request_id: string;
|
|
119
|
+
decision_id: string;
|
|
120
|
+
advertiser_id: string;
|
|
121
|
+
ad_type: 'link' | 'recommendation' | 'service';
|
|
122
|
+
payout: number; // Amount earned on conversion (in cents)
|
|
123
|
+
|
|
124
|
+
creative: {
|
|
125
|
+
title: string;
|
|
126
|
+
body: string;
|
|
127
|
+
cta: string;
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
click_url: string; // Tracked click URL (use this)
|
|
131
|
+
tracking_url?: string; // Server-side tracking URL
|
|
132
|
+
tracking_token: string; // For manual event tracking
|
|
133
|
+
|
|
134
|
+
disclosure: {
|
|
135
|
+
label: string;
|
|
136
|
+
explanation: string;
|
|
137
|
+
sponsor_name: string;
|
|
138
|
+
};
|
|
268
139
|
}
|
|
269
140
|
```
|
|
270
141
|
|
|
271
|
-
|
|
272
|
-
**Developer B** earns per call. **Developer A** earns a routing fee.
|
|
273
|
-
|
|
274
|
-
### List Your Agent
|
|
275
|
-
|
|
276
|
-
Sign up as an advertiser at [api.attentionmarket.ai](https://api.attentionmarket.ai) and create an **Agent Ad** campaign:
|
|
277
|
-
|
|
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 |
|
|
286
|
-
|
|
287
|
-
**Matching is semantic** — describe your agent clearly in plain English and we handle the rest.
|
|
142
|
+
### Impression Tracking
|
|
288
143
|
|
|
289
|
-
|
|
144
|
+
**Important:** As of v0.9.0, impression tracking is required to earn revenue from clicks.
|
|
290
145
|
|
|
291
|
-
|
|
146
|
+
The SDK automatically tracks impressions when using `decideFromContext()`. Clicks without prior impressions will redirect users but will not generate revenue.
|
|
292
147
|
|
|
293
|
-
|
|
148
|
+
If using the raw `decide()` API, you must manually track impressions:
|
|
294
149
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|---------------------|------------|-----------------|
|
|
305
|
-
| 50 | $50 | $2,500 |
|
|
306
|
-
| 200 | $50 | $10,000 |
|
|
307
|
-
| 1,000 | $50 | $50,000 |
|
|
308
|
-
|
|
309
|
-
### As an Agent Advertiser (listing your agent)
|
|
150
|
+
```typescript
|
|
151
|
+
await client.trackImpression({
|
|
152
|
+
agent_id: 'agt_YOUR_AGENT_ID',
|
|
153
|
+
request_id: ad.request_id,
|
|
154
|
+
decision_id: ad.decision_id,
|
|
155
|
+
unit_id: ad._ad.unit_id,
|
|
156
|
+
tracking_token: ad.tracking_token
|
|
157
|
+
});
|
|
158
|
+
```
|
|
310
159
|
|
|
311
|
-
|
|
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
|
|
160
|
+
## Developer Controls
|
|
315
161
|
|
|
316
|
-
|
|
162
|
+
AttentionMarket provides fine-grained controls over ad selection, quality, and revenue optimization.
|
|
317
163
|
|
|
318
|
-
|
|
164
|
+
### Quality and Brand Safety
|
|
319
165
|
|
|
320
|
-
|
|
166
|
+
#### Minimum Quality Score
|
|
321
167
|
|
|
322
|
-
|
|
168
|
+
Filter ads based on historical performance metrics. Quality scores range from 0.0 (worst) to 1.0 (best) and are calculated from click-through rates, conversion rates, and user feedback.
|
|
323
169
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
- ❌ Wrong positive prediction → **-5% penalty**
|
|
331
|
-
- 🤷 Neutral/negative → no bonus/penalty (data only)
|
|
170
|
+
```typescript
|
|
171
|
+
const ad = await client.decideFromContext({
|
|
172
|
+
userMessage: "I need legal help",
|
|
173
|
+
minQualityScore: 0.7 // Only show ads with quality >= 0.7
|
|
174
|
+
});
|
|
175
|
+
```
|
|
332
176
|
|
|
333
|
-
|
|
177
|
+
**Validation:** Must be a number between 0.0 and 1.0.
|
|
334
178
|
|
|
335
|
-
**
|
|
336
|
-
-
|
|
337
|
-
-
|
|
338
|
-
-
|
|
339
|
-
- Harder to game (can't spam "positive" on everything)
|
|
179
|
+
**Use cases:**
|
|
180
|
+
- Premium applications: `0.8+` for high-quality experiences only
|
|
181
|
+
- Brand-sensitive contexts: `0.7+` to avoid low-quality advertisers
|
|
182
|
+
- General applications: `0.5+` for balanced quality and fill rate
|
|
340
183
|
|
|
341
|
-
|
|
184
|
+
#### Category Filtering
|
|
342
185
|
|
|
343
|
-
|
|
186
|
+
Control which advertiser categories can appear using the IAB Content Taxonomy 3.0 (704 categories across 38 top-level verticals).
|
|
344
187
|
|
|
345
|
-
|
|
346
|
-
- Spamming fake positive responses = net loss
|
|
347
|
-
- Accuracy = net gain (bonus > penalty when right)
|
|
348
|
-
- System rewards honest data collection
|
|
188
|
+
##### Allowed Categories
|
|
349
189
|
|
|
350
|
-
|
|
190
|
+
Whitelist specific categories. Only ads from these categories will be shown.
|
|
351
191
|
|
|
352
192
|
```typescript
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
193
|
+
// Insurance comparison app: only show insurance ads
|
|
194
|
+
const ad = await client.decideFromContext({
|
|
195
|
+
userMessage: "I need car insurance",
|
|
196
|
+
allowedCategories: [31] // 31 = Auto Insurance (IAB category)
|
|
357
197
|
});
|
|
358
198
|
|
|
359
|
-
//
|
|
199
|
+
// Wedding planner: allow wedding + photography + food
|
|
360
200
|
const ad = await client.decideFromContext({
|
|
361
|
-
userMessage: "
|
|
201
|
+
userMessage: "Help me plan my wedding",
|
|
202
|
+
allowedCategories: [
|
|
203
|
+
603, // Weddings
|
|
204
|
+
162, // Photography
|
|
205
|
+
190 // Restaurants
|
|
206
|
+
]
|
|
362
207
|
});
|
|
363
|
-
|
|
364
|
-
if (ad) {
|
|
365
|
-
// User responds after clicking
|
|
366
|
-
const userResponse = "This looks perfect! How do I sign up?";
|
|
367
|
-
|
|
368
|
-
await client.sendFeedback({
|
|
369
|
-
tracking_token: ad.tracking_token,
|
|
370
|
-
user_response: userResponse,
|
|
371
|
-
agent_response: "Here's the signup link...",
|
|
372
|
-
additional_context: "User spent 2 minutes on offer page"
|
|
373
|
-
});
|
|
374
|
-
|
|
375
|
-
// AI will detect positive sentiment → +15% bonus if user converts
|
|
376
|
-
}
|
|
377
208
|
```
|
|
378
209
|
|
|
379
|
-
|
|
210
|
+
##### Blocked Categories
|
|
380
211
|
|
|
381
|
-
|
|
382
|
-
curl -X POST https://peruwnbrqkvmrldhpoom.supabase.co/functions/v1/feedback \
|
|
383
|
-
-H "X-AM-API-Key: am_live_YOUR_KEY" \
|
|
384
|
-
-H "Content-Type: application/json" \
|
|
385
|
-
-d '{
|
|
386
|
-
"tracking_token": "eyJhbGc...",
|
|
387
|
-
"user_response": "This looks great! How do I get started?",
|
|
388
|
-
"agent_response": "Here is the signup process...",
|
|
389
|
-
"additional_context": "User asked 3 follow-up questions"
|
|
390
|
-
}'
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
**Response:**
|
|
394
|
-
```json
|
|
395
|
-
{
|
|
396
|
-
"success": true,
|
|
397
|
-
"sentiment_detected": "positive",
|
|
398
|
-
"potential_bonus": "$1.05",
|
|
399
|
-
"potential_penalty": "$0.35",
|
|
400
|
-
"message": "Feedback recorded! Detected sentiment: positive. If correct (user converts within 7 days), you'll earn a +15% bonus. Wrong predictions incur a -5% penalty.",
|
|
401
|
-
"resolution_date": "2026-02-28T12:00:00Z"
|
|
402
|
-
}
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
### When To Send Feedback
|
|
406
|
-
|
|
407
|
-
**Good signals to capture:**
|
|
408
|
-
- User's actual text responses after clicking
|
|
409
|
-
- Your agent's follow-up messages
|
|
410
|
-
- Context about how long user engaged with the offer
|
|
411
|
-
- Any follow-up questions or actions
|
|
412
|
-
|
|
413
|
-
**Best practices:**
|
|
414
|
-
- Send actual user text, not summaries
|
|
415
|
-
- Include your agent's response for context
|
|
416
|
-
- Only send when you have meaningful interaction data
|
|
417
|
-
- Quality > quantity
|
|
418
|
-
|
|
419
|
-
---
|
|
420
|
-
|
|
421
|
-
## 🎛️ Developer Controls (v0.12.0+)
|
|
422
|
-
|
|
423
|
-
Take control of what ads appear in your app with quality, category, and advertiser filters.
|
|
424
|
-
|
|
425
|
-
### Quality Score Filter
|
|
426
|
-
|
|
427
|
-
Only show ads that meet your quality standards:
|
|
212
|
+
Blacklist specific categories. Ads from these categories will never be shown.
|
|
428
213
|
|
|
429
214
|
```typescript
|
|
215
|
+
// Block all sensitive content (gambling, adult, controversial)
|
|
430
216
|
const ad = await client.decideFromContext({
|
|
431
|
-
userMessage: "
|
|
432
|
-
|
|
217
|
+
userMessage: "Help me with something",
|
|
218
|
+
blockedCategories: [601] // Blocks "Sensitive Topics" + all children
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
// Legal assistant: block competitor law firms
|
|
222
|
+
const ad = await client.decideFromContext({
|
|
223
|
+
userMessage: "I need legal help",
|
|
224
|
+
blockedCategories: [318] // Block "Legal Services"
|
|
433
225
|
});
|
|
434
226
|
```
|
|
435
227
|
|
|
436
|
-
**
|
|
437
|
-
- **Premium apps**: Set 0.9+ for best-in-class ads only
|
|
438
|
-
- **General apps**: Set 0.7+ for good balance
|
|
439
|
-
- **High-volume apps**: Set 0.5+ to maximize fill rate
|
|
228
|
+
**Parent-child relationships:** Blocking a parent category automatically blocks all subcategories. For example, blocking category `1` (Automotive) blocks Auto Insurance, Auto Repair, Auto Parts, etc.
|
|
440
229
|
|
|
441
|
-
|
|
230
|
+
**Precedence:** If `allowedCategories` is set, `blockedCategories` is ignored.
|
|
442
231
|
|
|
443
|
-
|
|
232
|
+
**Validation rules:**
|
|
233
|
+
- `allowedCategories`: Must be a non-empty array of numbers or strings
|
|
234
|
+
- `blockedCategories`: Must be an array of numbers or strings
|
|
235
|
+
- Empty `allowedCategories: []` is rejected (would block all ads)
|
|
444
236
|
|
|
445
|
-
**
|
|
237
|
+
**Note:** IAB category IDs (numbers) are recommended. Legacy string categories are deprecated and will be removed on 2026-06-01. Use the `getCategories()` API to discover category IDs.
|
|
446
238
|
|
|
447
|
-
|
|
239
|
+
##### Discovering Categories
|
|
448
240
|
|
|
449
241
|
```typescript
|
|
450
242
|
// Get all 38 top-level categories
|
|
@@ -466,244 +258,251 @@ insurance.categories.forEach(cat => {
|
|
|
466
258
|
// Output: "Automotive > Auto Insurance", "Personal Finance > Insurance", etc.
|
|
467
259
|
```
|
|
468
260
|
|
|
469
|
-
####
|
|
261
|
+
#### Advertiser Blocklist
|
|
470
262
|
|
|
471
|
-
|
|
263
|
+
Block specific advertisers by ID (e.g., based on user feedback or competitive conflicts).
|
|
472
264
|
|
|
473
265
|
```typescript
|
|
474
|
-
// Insurance app: Only show insurance ads (by IAB ID)
|
|
475
266
|
const ad = await client.decideFromContext({
|
|
476
|
-
userMessage: "I need
|
|
477
|
-
|
|
267
|
+
userMessage: "I need legal help",
|
|
268
|
+
blockedAdvertisers: ['adv_abc123', 'adv_xyz789']
|
|
478
269
|
});
|
|
270
|
+
```
|
|
479
271
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
272
|
+
**Validation:** Must be an array of non-empty strings (advertiser IDs).
|
|
273
|
+
|
|
274
|
+
Advertiser IDs are included in ad responses as `advertiser_id`.
|
|
275
|
+
|
|
276
|
+
### Revenue Optimization
|
|
277
|
+
|
|
278
|
+
#### Minimum CPC Filter
|
|
279
|
+
|
|
280
|
+
Only show ads with bids at or above a specified cost-per-click threshold (in cents).
|
|
486
281
|
|
|
487
|
-
|
|
282
|
+
```typescript
|
|
488
283
|
const ad = await client.decideFromContext({
|
|
489
|
-
userMessage: "
|
|
490
|
-
|
|
491
|
-
603, // Weddings (Personal Celebrations)
|
|
492
|
-
162, // Photography (Hobbies & Interests)
|
|
493
|
-
190 // Restaurants (Food & Drink)
|
|
494
|
-
]
|
|
284
|
+
userMessage: "I need car insurance",
|
|
285
|
+
minCPC: 100 // Only ads bidding >= $1.00 per click
|
|
495
286
|
});
|
|
496
287
|
```
|
|
497
288
|
|
|
498
|
-
**
|
|
499
|
-
- Blocking a parent category blocks ALL child categories automatically
|
|
500
|
-
- Example: Blocking `1` (Automotive) blocks Auto Insurance, Auto Repair, etc.
|
|
501
|
-
- Great for compliance: Block `601` (Sensitive Topics) to block gambling, adult, controversial in one go
|
|
289
|
+
**Validation:** Must be a non-negative number.
|
|
502
290
|
|
|
503
|
-
**
|
|
291
|
+
**Use cases:**
|
|
292
|
+
- Premium applications: `200+` for $2+ ads only
|
|
293
|
+
- High-value verticals: Filter out low-budget advertisers
|
|
294
|
+
- Revenue targets: Ensure minimum revenue per impression
|
|
295
|
+
- Lower fill rate tolerance: When you'd rather show nothing than a low-value ad
|
|
296
|
+
|
|
297
|
+
**Trade-off:** Higher thresholds = higher revenue per ad but lower fill rate.
|
|
504
298
|
|
|
505
|
-
|
|
299
|
+
#### Minimum Relevance Score
|
|
506
300
|
|
|
507
|
-
|
|
301
|
+
Only show ads with semantic similarity at or above a threshold. Relevance scores range from 0.0 (unrelated) to 1.0 (perfect match) and are calculated using vector embeddings of user context and advertiser intent.
|
|
508
302
|
|
|
509
303
|
```typescript
|
|
510
304
|
const ad = await client.decideFromContext({
|
|
511
|
-
userMessage: "
|
|
512
|
-
|
|
305
|
+
userMessage: "Help me plan my wedding",
|
|
306
|
+
minRelevanceScore: 0.8 // Only highly relevant ads
|
|
513
307
|
});
|
|
514
308
|
```
|
|
515
309
|
|
|
516
|
-
|
|
310
|
+
**Validation:** Must be a number between 0.0 and 1.0.
|
|
517
311
|
|
|
518
|
-
|
|
312
|
+
**Use cases:**
|
|
313
|
+
- Niche applications: `0.8+` for specialized content only (e.g., legal assistant)
|
|
314
|
+
- User experience priority: Filter out loosely related ads
|
|
315
|
+
- Context-sensitive placements: Ensure ads match conversation topic
|
|
316
|
+
- Brand-aligned content: Maintain thematic consistency
|
|
519
317
|
|
|
520
|
-
|
|
318
|
+
**Important:** This filter only applies to campaigns with semantic targeting. Keyword and automatic campaigns are not affected.
|
|
319
|
+
|
|
320
|
+
**Default threshold:** Backend applies a minimum threshold of 0.25 for all semantic campaigns (ads below this are never shown).
|
|
321
|
+
|
|
322
|
+
#### Ranking Strategy
|
|
323
|
+
|
|
324
|
+
Choose how ads are ranked when multiple ads match the request.
|
|
521
325
|
|
|
522
326
|
```typescript
|
|
327
|
+
// Revenue-optimized (default): highest bid wins
|
|
523
328
|
const ad = await client.decideFromContext({
|
|
524
|
-
userMessage: "I need
|
|
525
|
-
|
|
526
|
-
blockedCategories: ['crypto'], // No crypto ads
|
|
527
|
-
allowedCategories: ['insurance', 'finance'] // Relevant only
|
|
329
|
+
userMessage: "I need legal help",
|
|
330
|
+
optimizeFor: 'revenue' // Rank by bid × quality × relevance
|
|
528
331
|
});
|
|
529
|
-
```
|
|
530
|
-
|
|
531
|
-
### HTTP Example
|
|
532
332
|
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
"context": "I need car insurance",
|
|
539
|
-
"minQualityScore": 0.8,
|
|
540
|
-
"blockedCategories": ["crypto", "gambling"]
|
|
541
|
-
}'
|
|
333
|
+
// Relevance-optimized: best match wins
|
|
334
|
+
const ad = await client.decideFromContext({
|
|
335
|
+
userMessage: "I need legal help",
|
|
336
|
+
optimizeFor: 'relevance' // Rank by semantic similarity only
|
|
337
|
+
});
|
|
542
338
|
```
|
|
543
339
|
|
|
544
|
-
|
|
340
|
+
**Validation:** Must be either `'revenue'` or `'relevance'`.
|
|
545
341
|
|
|
546
|
-
**
|
|
547
|
-
- Start with no filter, monitor what you get
|
|
548
|
-
- Gradually increase threshold if quality is lacking
|
|
549
|
-
- Higher thresholds = fewer ads but better quality
|
|
342
|
+
**How it works (second-price auction):**
|
|
550
343
|
|
|
551
|
-
**
|
|
552
|
-
-
|
|
553
|
-
-
|
|
554
|
-
-
|
|
555
|
-
- Parent categories block all children automatically (block `[1]` Automotive = blocks all 40+ auto subcategories)
|
|
556
|
-
- Full taxonomy reference: https://github.com/InteractiveAdvertisingBureau/Taxonomies
|
|
344
|
+
- **Revenue mode:** Winner is ranked by composite score (bid × quality × relevance), pays just enough to beat the next ad's composite score + $0.01
|
|
345
|
+
- **Relevance mode:** Winner is ranked by semantic similarity, pays just enough to beat the next ad in composite score space + $0.01
|
|
346
|
+
- **Price cap:** Winner never pays more than their max bid (auction integrity guaranteed)
|
|
347
|
+
- **Price floor:** Minimum clearing price of $0.25 ensures platform sustainability
|
|
557
348
|
|
|
558
|
-
**
|
|
559
|
-
-
|
|
560
|
-
-
|
|
561
|
-
-
|
|
349
|
+
**Use cases:**
|
|
350
|
+
- General applications: `'revenue'` to maximize earnings
|
|
351
|
+
- Niche applications: `'relevance'` to prioritize perfect matches over high bids
|
|
352
|
+
- Premium experiences: Combine with high `minRelevanceScore` + `'relevance'` ranking
|
|
562
353
|
|
|
563
|
-
|
|
354
|
+
#### Combined Controls
|
|
564
355
|
|
|
565
|
-
|
|
356
|
+
Combine multiple controls for precise ad selection:
|
|
566
357
|
|
|
567
|
-
|
|
358
|
+
```typescript
|
|
359
|
+
// Premium legal assistant: high relevance + high bids + category filter
|
|
360
|
+
const ad = await client.decideFromContext({
|
|
361
|
+
userMessage: "I need estate planning help",
|
|
362
|
+
minRelevanceScore: 0.8, // Only highly relevant
|
|
363
|
+
minCPC: 200, // Only $2+ bids
|
|
364
|
+
minQualityScore: 0.7, // Only high-quality advertisers
|
|
365
|
+
optimizeFor: 'relevance', // Best match wins
|
|
366
|
+
allowedCategories: [318] // Legal services only
|
|
367
|
+
});
|
|
368
|
+
```
|
|
568
369
|
|
|
569
|
-
|
|
370
|
+
## Advanced Features
|
|
570
371
|
|
|
571
|
-
|
|
372
|
+
### Multi-Turn Conversations
|
|
572
373
|
|
|
573
|
-
|
|
374
|
+
Include conversation history for better ad matching:
|
|
574
375
|
|
|
575
|
-
```
|
|
576
|
-
{
|
|
577
|
-
|
|
578
|
-
|
|
376
|
+
```typescript
|
|
377
|
+
const ad = await client.decideFromContext({
|
|
378
|
+
userMessage: "What are my options?",
|
|
379
|
+
conversationHistory: [
|
|
380
|
+
"User: My car insurance is too expensive",
|
|
381
|
+
"Agent: I can help you compare rates",
|
|
382
|
+
"User: What are my options?"
|
|
383
|
+
]
|
|
384
|
+
});
|
|
579
385
|
```
|
|
580
386
|
|
|
581
|
-
|
|
387
|
+
The SDK automatically limits history to the last 5 messages to prevent token overflow.
|
|
582
388
|
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
389
|
+
### Geographic and Platform Targeting
|
|
390
|
+
|
|
391
|
+
```typescript
|
|
392
|
+
const ad = await client.decideFromContext({
|
|
393
|
+
userMessage: "I need car insurance",
|
|
394
|
+
country: 'US',
|
|
395
|
+
language: 'en',
|
|
396
|
+
platform: 'ios' // 'web' | 'ios' | 'android' | 'desktop' | 'voice' | 'other'
|
|
397
|
+
});
|
|
590
398
|
```
|
|
591
399
|
|
|
592
|
-
###
|
|
400
|
+
### Click Tracking
|
|
593
401
|
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
402
|
+
Clicks are automatically tracked when users visit `click_url`. For manual tracking:
|
|
403
|
+
|
|
404
|
+
```typescript
|
|
405
|
+
await client.trackClick({
|
|
406
|
+
agent_id: 'agt_YOUR_AGENT_ID',
|
|
407
|
+
request_id: ad.request_id,
|
|
408
|
+
decision_id: ad.decision_id,
|
|
409
|
+
unit_id: ad._ad.unit_id,
|
|
410
|
+
tracking_token: ad.tracking_token,
|
|
411
|
+
href: ad.click_url,
|
|
412
|
+
click_context: "User clicked 'Get a Quote' button"
|
|
413
|
+
});
|
|
599
414
|
```
|
|
600
415
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
```
|
|
604
|
-
{
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
"placement": "chat_inline",
|
|
608
|
-
"opportunity": {
|
|
609
|
-
"intent": { "taxonomy": "insurance.auto.quote" },
|
|
610
|
-
"context": { "country": "US", "language": "en", "platform": "ios" }
|
|
611
|
-
},
|
|
612
|
-
"context": "I need car insurance"
|
|
613
|
-
}
|
|
416
|
+
Simplified tracking from ad object:
|
|
417
|
+
|
|
418
|
+
```typescript
|
|
419
|
+
await client.trackClickFromAd(ad, {
|
|
420
|
+
click_context: "User clicked on sponsored suggestion"
|
|
421
|
+
});
|
|
614
422
|
```
|
|
615
423
|
|
|
616
|
-
###
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
"impression_url": "https://.../event",
|
|
636
|
-
"click_url": "https://.../click/trk_abc"
|
|
637
|
-
}
|
|
638
|
-
}]
|
|
639
|
-
}
|
|
424
|
+
### Conversion Tracking
|
|
425
|
+
|
|
426
|
+
Track conversions (purchases, signups, etc.) to improve advertiser ROI and your quality score:
|
|
427
|
+
|
|
428
|
+
```typescript
|
|
429
|
+
await client.track({
|
|
430
|
+
event_id: `evt_${generateUUID()}`,
|
|
431
|
+
event_type: 'conversion',
|
|
432
|
+
occurred_at: new Date().toISOString(),
|
|
433
|
+
agent_id: 'agt_YOUR_AGENT_ID',
|
|
434
|
+
request_id: ad.request_id,
|
|
435
|
+
decision_id: ad.decision_id,
|
|
436
|
+
unit_id: ad._ad.unit_id,
|
|
437
|
+
tracking_token: ad.tracking_token,
|
|
438
|
+
metadata: {
|
|
439
|
+
conversion_value: 99.99,
|
|
440
|
+
conversion_type: 'purchase'
|
|
441
|
+
}
|
|
442
|
+
});
|
|
640
443
|
```
|
|
641
444
|
|
|
642
|
-
|
|
445
|
+
## Error Handling
|
|
446
|
+
|
|
447
|
+
The SDK throws errors for invalid configurations and failed requests:
|
|
643
448
|
|
|
644
|
-
```
|
|
645
|
-
{
|
|
646
|
-
|
|
647
|
-
|
|
449
|
+
```typescript
|
|
450
|
+
try {
|
|
451
|
+
const ad = await client.decideFromContext({
|
|
452
|
+
userMessage: "I need car insurance",
|
|
453
|
+
minQualityScore: -0.5 // Invalid: must be 0.0-1.0
|
|
454
|
+
});
|
|
455
|
+
} catch (error) {
|
|
456
|
+
console.error(error.message);
|
|
457
|
+
// Output: "minQualityScore must be a number between 0.0 and 1.0"
|
|
648
458
|
}
|
|
649
459
|
```
|
|
650
460
|
|
|
651
|
-
###
|
|
461
|
+
### Validation Errors
|
|
652
462
|
|
|
653
|
-
|
|
654
|
-
|-------|-----|
|
|
655
|
-
| `status` | `"filled"` or `"no_fill"` |
|
|
656
|
-
| `suggestion.title` | Ad headline to show |
|
|
657
|
-
| `suggestion.body` | Ad description to show |
|
|
658
|
-
| `suggestion.cta` | Button text |
|
|
659
|
-
| `suggestion.tracking_url` | **Send users here on click** — tracks automatically |
|
|
660
|
-
| `suggestion.action_url` | Direct advertiser URL (display only, no tracking) |
|
|
463
|
+
The SDK validates all parameters before making API calls. Common validation errors:
|
|
661
464
|
|
|
662
|
-
|
|
465
|
+
- `minQualityScore must be a number between 0.0 and 1.0`
|
|
466
|
+
- `minCPC must be a non-negative number (cost-per-click in cents)`
|
|
467
|
+
- `minRelevanceScore must be a number between 0.0 and 1.0`
|
|
468
|
+
- `optimizeFor must be either "revenue" or "relevance"`
|
|
469
|
+
- `allowedCategories cannot be empty (would block all ads). Use blockedCategories to exclude specific categories, or omit to allow all.`
|
|
470
|
+
- `blockedAdvertisers must contain non-empty strings (advertiser IDs)`
|
|
663
471
|
|
|
664
|
-
### HTTP
|
|
472
|
+
### HTTP Errors
|
|
665
473
|
|
|
666
|
-
|
|
667
|
-
|------|---------|
|
|
668
|
-
| `200` | Success — check `status` field |
|
|
669
|
-
| `400` | Bad request — missing `context` field |
|
|
670
|
-
| `401` | Invalid API key |
|
|
671
|
-
| `429` | Rate limit exceeded (1,000 req/min) — retry after 60s |
|
|
672
|
-
| `500` | Server error — retry with backoff |
|
|
474
|
+
The API returns standard HTTP status codes:
|
|
673
475
|
|
|
674
|
-
|
|
476
|
+
- `400 Bad Request` — Invalid parameters (see error message for details)
|
|
477
|
+
- `401 Unauthorized` — Missing or invalid API key
|
|
478
|
+
- `429 Too Many Requests` — Rate limit exceeded
|
|
479
|
+
- `500 Internal Server Error` — Server error (contact support if persistent)
|
|
675
480
|
|
|
676
|
-
##
|
|
481
|
+
## Rate Limits
|
|
677
482
|
|
|
678
|
-
|
|
483
|
+
- **Per IP:** 60 requests per minute
|
|
484
|
+
- **Per API key:** 100 requests per minute
|
|
679
485
|
|
|
680
|
-
|
|
681
|
-
```bash
|
|
682
|
-
node test-integration.js # Tests connectivity and credentials
|
|
683
|
-
node validate-production.js # Full production readiness check (4/4 ✅)
|
|
684
|
-
```
|
|
685
|
-
|
|
686
|
-
Download: [test-integration.js](./test-integration.js) | [validate-production.js](./validate-production.js)
|
|
486
|
+
Rate limits are enforced to prevent abuse and ensure fair resource allocation. If you need higher limits, contact support.
|
|
687
487
|
|
|
688
|
-
|
|
488
|
+
## Testing
|
|
689
489
|
|
|
690
|
-
|
|
490
|
+
Use test API keys (`am_test_...`) for development and testing. Test keys:
|
|
691
491
|
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
492
|
+
- Return test ads with realistic data
|
|
493
|
+
- Do not charge advertisers
|
|
494
|
+
- Do not generate real revenue
|
|
495
|
+
- Have the same rate limits as live keys
|
|
696
496
|
|
|
697
|
-
|
|
497
|
+
Switch to live keys (`am_live_...`) when deploying to production.
|
|
698
498
|
|
|
699
499
|
## Support
|
|
700
500
|
|
|
701
|
-
- **
|
|
702
|
-
- **
|
|
501
|
+
- **Documentation:** [docs.attentionmarket.ai](https://docs.attentionmarket.ai)
|
|
502
|
+
- **API Reference:** [api.attentionmarket.ai/docs](https://api.attentionmarket.ai/docs)
|
|
503
|
+
- **Issues:** [github.com/rtrivedi/agent-ads-sdk/issues](https://github.com/rtrivedi/agent-ads-sdk/issues)
|
|
703
504
|
- **Email:** support@attentionmarket.ai
|
|
704
505
|
|
|
705
|
-
---
|
|
706
|
-
|
|
707
506
|
## License
|
|
708
507
|
|
|
709
|
-
MIT
|
|
508
|
+
MIT License. See [LICENSE](LICENSE) for details.
|