@gravity-ai/api 0.1.1 → 1.0.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 +244 -35
- package/dist/index.d.mts +247 -1
- package/dist/index.d.ts +247 -1
- package/dist/index.js +218 -2
- package/dist/index.mjs +218 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,14 +17,18 @@ import { Client } from '@gravity-ai/api';
|
|
|
17
17
|
|
|
18
18
|
const client = new Client('your-api-key');
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
// Contextual ads (v1 API)
|
|
21
|
+
const response = await client.contextualAd({
|
|
21
22
|
messages: [
|
|
22
23
|
{ role: 'user', content: 'What are some good hiking trails?' },
|
|
23
24
|
{ role: 'assistant', content: 'Here are some popular trails...' }
|
|
24
|
-
]
|
|
25
|
+
],
|
|
26
|
+
sessionId: 'session-123', // Recommended
|
|
27
|
+
userId: 'user-456', // Recommended
|
|
25
28
|
});
|
|
26
29
|
|
|
27
|
-
if (
|
|
30
|
+
if (response) {
|
|
31
|
+
const ad = response.ads[0];
|
|
28
32
|
console.log(ad.adText);
|
|
29
33
|
}
|
|
30
34
|
```
|
|
@@ -61,29 +65,47 @@ const client = new Client('your-api-key', {
|
|
|
61
65
|
| `excludedTopics` | `string[]` | `[]` | Topics to exclude from ad matching |
|
|
62
66
|
| `relevancy` | `number \| null` | `null` | Minimum relevancy score (0-1) |
|
|
63
67
|
|
|
64
|
-
|
|
68
|
+
---
|
|
65
69
|
|
|
66
|
-
|
|
70
|
+
## v1 API Methods
|
|
71
|
+
|
|
72
|
+
The v1 API provides explicit endpoints for different ad types with multi-ad support.
|
|
73
|
+
|
|
74
|
+
### `contextualAd()` — Contextual Ads
|
|
75
|
+
|
|
76
|
+
Fetch ads based on conversation context. Requires `messages` array.
|
|
67
77
|
|
|
68
78
|
```typescript
|
|
69
|
-
const
|
|
79
|
+
const response = await client.contextualAd({
|
|
70
80
|
messages: [
|
|
71
81
|
{ role: 'user', content: 'I need help finding a new laptop.' },
|
|
72
82
|
{ role: 'assistant', content: 'What is your budget?' }
|
|
73
|
-
]
|
|
83
|
+
],
|
|
84
|
+
sessionId: 'session-123', // Recommended
|
|
85
|
+
userId: 'user-456', // Recommended
|
|
86
|
+
numAds: 1, // 1-3, default 1
|
|
74
87
|
});
|
|
88
|
+
|
|
89
|
+
if (response) {
|
|
90
|
+
const ad = response.ads[0];
|
|
91
|
+
console.log(ad.adText);
|
|
92
|
+
}
|
|
75
93
|
```
|
|
76
94
|
|
|
77
|
-
|
|
95
|
+
#### Full Request with All Options
|
|
78
96
|
|
|
79
97
|
```typescript
|
|
80
|
-
const
|
|
98
|
+
const response = await client.contextualAd({
|
|
81
99
|
// Required: conversation messages
|
|
82
100
|
messages: [
|
|
83
101
|
{ role: 'user', content: 'I need help finding a new laptop.' },
|
|
84
102
|
{ role: 'assistant', content: 'What is your budget?' }
|
|
85
103
|
],
|
|
86
104
|
|
|
105
|
+
// Recommended: session/user tracking (improves ad relevance & revenue)
|
|
106
|
+
sessionId: 'session-123',
|
|
107
|
+
userId: 'user-456',
|
|
108
|
+
|
|
87
109
|
// Optional: user information for targeting
|
|
88
110
|
user: {
|
|
89
111
|
uid: 'user-123', // Unique user identifier
|
|
@@ -101,27 +123,158 @@ const ad = await client.getAd({
|
|
|
101
123
|
ifa: 'device-ad-id', // Advertising identifier
|
|
102
124
|
},
|
|
103
125
|
|
|
104
|
-
// Optional:
|
|
105
|
-
excludedTopics: ['politics'], //
|
|
106
|
-
relevancy: 0.8, //
|
|
126
|
+
// Optional: ad request settings
|
|
127
|
+
excludedTopics: ['politics'], // Topics to exclude
|
|
128
|
+
relevancy: 0.8, // Min relevancy threshold (0-1)
|
|
129
|
+
numAds: 1, // Number of ads (1-3)
|
|
130
|
+
testAd: false, // Return test ad when true
|
|
107
131
|
|
|
108
|
-
// Optional: custom fields (open-ended)
|
|
132
|
+
// Optional: custom fields (open-ended, passed to matching)
|
|
109
133
|
interests: ['coding', 'apple', 'software development'],
|
|
110
134
|
summary: 'User wants a laptop for software development',
|
|
111
135
|
});
|
|
112
136
|
```
|
|
113
137
|
|
|
114
|
-
###
|
|
138
|
+
### `summaryAd()` — Summary-Based Ads
|
|
139
|
+
|
|
140
|
+
Fetch ads based on a search query or summary string. Requires `queryString`.
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
const response = await client.summaryAd({
|
|
144
|
+
queryString: 'User wants a laptop for software development',
|
|
145
|
+
sessionId: 'session-123',
|
|
146
|
+
userId: 'user-456',
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
if (response) {
|
|
150
|
+
const ad = response.ads[0];
|
|
151
|
+
console.log(ad.adText);
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### `nonContextualAd()` — Non-Contextual Ads
|
|
156
|
+
|
|
157
|
+
Fetch ads without context matching. Ideal for:
|
|
158
|
+
- **Integration testing** — Test your ad implementation on a subset of users before rolling out contextual ads
|
|
159
|
+
- **Brand awareness** — Show ads without requiring conversation context
|
|
160
|
+
- **Fallback placements** — Ad slots where context isn't available
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
const response = await client.nonContextualAd({
|
|
164
|
+
sessionId: 'session-123',
|
|
165
|
+
userId: 'user-456',
|
|
166
|
+
numAds: 2, // Request multiple ads
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
if (response) {
|
|
170
|
+
response.ads.forEach(ad => console.log(ad.adText));
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### `bid()` + `render()` — Two-Phase Flow
|
|
175
|
+
|
|
176
|
+
For publishers who need to know the clearing price before rendering the ad.
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
// Phase 1: Get bid price
|
|
180
|
+
const bidResult = await client.bid({
|
|
181
|
+
messages: [
|
|
182
|
+
{ role: 'user', content: 'I need help with my code' }
|
|
183
|
+
],
|
|
184
|
+
sessionId: 'session-123',
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
if (bidResult) {
|
|
188
|
+
console.log(`Clearing price: $${bidResult.bid} CPM`);
|
|
189
|
+
console.log(`Bid ID: ${bidResult.bidId}`);
|
|
190
|
+
|
|
191
|
+
// Decide whether to show ad based on price...
|
|
192
|
+
|
|
193
|
+
// Phase 2: Render the ad
|
|
194
|
+
const response = await client.render({
|
|
195
|
+
bidId: bidResult.bidId,
|
|
196
|
+
realizedPrice: bidResult.bid,
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
if (response) {
|
|
200
|
+
const ad = response.ads[0];
|
|
201
|
+
console.log(ad.adText);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
> **Note:** Bids expire after 60 seconds. Call `render()` promptly after `bid()`.
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## v1 Request Parameters
|
|
211
|
+
|
|
212
|
+
### Base Parameters (All v1 Methods)
|
|
115
213
|
|
|
116
214
|
| Parameter | Type | Required | Description |
|
|
117
215
|
|-----------|------|----------|-------------|
|
|
118
|
-
| `
|
|
119
|
-
| `
|
|
216
|
+
| `sessionId` | `string` | Recommended | Session identifier for tracking |
|
|
217
|
+
| `userId` | `string` | Recommended | User identifier for frequency capping |
|
|
120
218
|
| `device` | `DeviceObject` | - | Device/location info |
|
|
219
|
+
| `user` | `UserObject` | - | User targeting info |
|
|
121
220
|
| `excludedTopics` | `string[]` | - | Topics to exclude |
|
|
122
221
|
| `relevancy` | `number` | - | Min relevancy (0-1) |
|
|
123
|
-
| `
|
|
124
|
-
| `
|
|
222
|
+
| `numAds` | `number` | - | Number of ads (1-3, default 1) |
|
|
223
|
+
| `testAd` | `boolean` | - | Return test ad when true |
|
|
224
|
+
|
|
225
|
+
### Method-Specific Parameters
|
|
226
|
+
|
|
227
|
+
| Method | Required Parameter | Description |
|
|
228
|
+
|--------|-------------------|-------------|
|
|
229
|
+
| `contextualAd()` | `messages: MessageObject[]` | Conversation history |
|
|
230
|
+
| `summaryAd()` | `queryString: string` | Search/summary query |
|
|
231
|
+
| `nonContextualAd()` | None | No context required |
|
|
232
|
+
| `bid()` | `messages: MessageObject[]` | Conversation for bid |
|
|
233
|
+
| `render()` | `bidId: string`, `realizedPrice: number` | From bid response |
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## v1 Response Types
|
|
238
|
+
|
|
239
|
+
### AdResponseV1
|
|
240
|
+
|
|
241
|
+
Returned by `contextualAd()`, `summaryAd()`, `nonContextualAd()`, and `render()`.
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
interface AdResponseV1 {
|
|
245
|
+
ads: AdV1[]; // Array of ads
|
|
246
|
+
numAds: number; // Number of ads returned
|
|
247
|
+
totalPayout?: number; // Total payout across all ads
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
interface AdV1 {
|
|
251
|
+
adText: string; // Ad copy text
|
|
252
|
+
adId: string; // Unique ad identifier
|
|
253
|
+
title?: string; // Ad title
|
|
254
|
+
brandName?: string; // Brand name
|
|
255
|
+
brandImage?: string; // Brand logo URL
|
|
256
|
+
url?: string; // Landing page URL
|
|
257
|
+
favicon?: string; // Favicon URL
|
|
258
|
+
impUrl?: string; // Impression tracking URL
|
|
259
|
+
clickUrl?: string; // Click-through URL
|
|
260
|
+
payout?: number; // Payout amount
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### BidResponse
|
|
265
|
+
|
|
266
|
+
Returned by `bid()`.
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
interface BidResponse {
|
|
270
|
+
bid: number; // Clearing price (CPM)
|
|
271
|
+
bidId: string; // Use this in render()
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## Common Types
|
|
125
278
|
|
|
126
279
|
### Message Object
|
|
127
280
|
|
|
@@ -155,39 +308,59 @@ interface DeviceObject {
|
|
|
155
308
|
}
|
|
156
309
|
```
|
|
157
310
|
|
|
158
|
-
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## Legacy API (v0)
|
|
159
314
|
|
|
160
|
-
The `getAd` method
|
|
315
|
+
The original `getAd()` method is still available for backward compatibility.
|
|
316
|
+
|
|
317
|
+
### Basic Request
|
|
318
|
+
|
|
319
|
+
```typescript
|
|
320
|
+
const ad = await client.getAd({
|
|
321
|
+
messages: [
|
|
322
|
+
{ role: 'user', content: 'I need help finding a new laptop.' },
|
|
323
|
+
{ role: 'assistant', content: 'What is your budget?' }
|
|
324
|
+
]
|
|
325
|
+
});
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Full Request with All Options
|
|
329
|
+
|
|
330
|
+
```typescript
|
|
331
|
+
const ad = await client.getAd({
|
|
332
|
+
messages: [...],
|
|
333
|
+
user: { uid: 'user-123', gender: 'male', age: '25-34' },
|
|
334
|
+
device: { ip: '1.2.3.4', country: 'US', ua: 'Mozilla/5.0...' },
|
|
335
|
+
excludedTopics: ['politics'],
|
|
336
|
+
relevancy: 0.8,
|
|
337
|
+
});
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Legacy Response
|
|
161
341
|
|
|
162
342
|
```typescript
|
|
163
343
|
interface AdResponse {
|
|
164
344
|
adText: string; // The ad copy to display
|
|
165
|
-
impUrl?: string; // Impression tracking URL
|
|
345
|
+
impUrl?: string; // Impression tracking URL
|
|
166
346
|
clickUrl?: string; // Click-through URL
|
|
167
347
|
payout?: number; // Payout amount
|
|
168
348
|
}
|
|
169
349
|
```
|
|
170
350
|
|
|
171
|
-
### Handling the Response
|
|
351
|
+
### Handling the Legacy Response
|
|
172
352
|
|
|
173
353
|
```typescript
|
|
174
354
|
const ad = await client.getAd({ messages });
|
|
175
355
|
|
|
176
356
|
if (ad) {
|
|
177
|
-
// Display the ad
|
|
178
357
|
console.log('Ad:', ad.adText);
|
|
179
358
|
|
|
180
|
-
// Track impression
|
|
359
|
+
// Track impression
|
|
181
360
|
if (ad.impUrl) {
|
|
182
|
-
fetch(ad.impUrl);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// Handle clicks
|
|
186
|
-
if (ad.clickUrl) {
|
|
187
|
-
// Navigate user to ad.clickUrl on click
|
|
361
|
+
fetch(ad.impUrl);
|
|
188
362
|
}
|
|
189
363
|
} else {
|
|
190
|
-
// No relevant ad found - show fallback or nothing
|
|
191
364
|
console.log('No ad available');
|
|
192
365
|
}
|
|
193
366
|
```
|
|
@@ -197,15 +370,16 @@ if (ad) {
|
|
|
197
370
|
The client handles errors gracefully and returns `null` on failure. Errors are logged to the console.
|
|
198
371
|
|
|
199
372
|
```typescript
|
|
200
|
-
const
|
|
373
|
+
const response = await client.contextualAd({ messages, sessionId: '...' });
|
|
201
374
|
|
|
202
375
|
// Returns null on:
|
|
203
376
|
// - Network errors
|
|
204
377
|
// - API errors (4xx, 5xx)
|
|
205
378
|
// - No relevant ad (204)
|
|
206
379
|
// - Invalid response data
|
|
380
|
+
// - Expired bid (404 for render())
|
|
207
381
|
|
|
208
|
-
if (!
|
|
382
|
+
if (!response) {
|
|
209
383
|
// Handle gracefully - don't break the user experience
|
|
210
384
|
}
|
|
211
385
|
```
|
|
@@ -216,7 +390,24 @@ Full TypeScript support with exported types:
|
|
|
216
390
|
|
|
217
391
|
```typescript
|
|
218
392
|
import { Client, ClientParams } from '@gravity-ai/api';
|
|
219
|
-
import type {
|
|
393
|
+
import type {
|
|
394
|
+
// v1 types
|
|
395
|
+
ContextualAdParams,
|
|
396
|
+
SummaryAdParams,
|
|
397
|
+
NonContextualAdParams,
|
|
398
|
+
BidParams,
|
|
399
|
+
RenderParams,
|
|
400
|
+
AdV1,
|
|
401
|
+
AdResponseV1,
|
|
402
|
+
BidResponse,
|
|
403
|
+
// Common types
|
|
404
|
+
MessageObject,
|
|
405
|
+
DeviceObject,
|
|
406
|
+
UserObject,
|
|
407
|
+
// Legacy types
|
|
408
|
+
AdParams,
|
|
409
|
+
AdResponse,
|
|
410
|
+
} from '@gravity-ai/api';
|
|
220
411
|
```
|
|
221
412
|
|
|
222
413
|
## Using with React
|
|
@@ -237,13 +428,31 @@ function ChatApp() {
|
|
|
237
428
|
const [ad, setAd] = useState(null);
|
|
238
429
|
|
|
239
430
|
useEffect(() => {
|
|
240
|
-
client.
|
|
431
|
+
client.contextualAd({
|
|
432
|
+
messages,
|
|
433
|
+
sessionId: 'session-123',
|
|
434
|
+
userId: 'user-456',
|
|
435
|
+
}).then(res => setAd(res?.ads[0] || null));
|
|
241
436
|
}, [messages]);
|
|
242
437
|
|
|
243
438
|
return <AdBanner ad={ad} theme="dark" />;
|
|
244
439
|
}
|
|
245
440
|
```
|
|
246
441
|
|
|
442
|
+
## Best Practices
|
|
443
|
+
|
|
444
|
+
1. **Always include `sessionId` and `userId`** — These directly impact publisher revenue through better frequency capping and ad relevance.
|
|
445
|
+
|
|
446
|
+
2. **Choose the right method**:
|
|
447
|
+
- Chat/conversation → `contextualAd()`
|
|
448
|
+
- Chat summary → `summaryAd()`
|
|
449
|
+
- Brand awareness → `nonContextualAd()`
|
|
450
|
+
- Custom auction → `bid()` + `render()`
|
|
451
|
+
|
|
452
|
+
3. **Handle null responses gracefully** — Don't break the user experience when no ad is available.
|
|
453
|
+
|
|
454
|
+
4. **Fire impression url** — Use the `impUrl` when the ad becomes visible to properly track impressions.
|
|
455
|
+
|
|
247
456
|
## License
|
|
248
457
|
|
|
249
458
|
MIT
|
package/dist/index.d.mts
CHANGED
|
@@ -153,6 +153,127 @@ interface ApiErrorResponse {
|
|
|
153
153
|
/** HTTP status code */
|
|
154
154
|
statusCode?: number;
|
|
155
155
|
}
|
|
156
|
+
/**
|
|
157
|
+
* Base fields shared across all v1 ad requests.
|
|
158
|
+
* @description Mirrors engine's AdRequestBaseV1. All fields are optional.
|
|
159
|
+
*/
|
|
160
|
+
interface AdRequestBaseV1 {
|
|
161
|
+
/** Session identifier for tracking user sessions */
|
|
162
|
+
sessionId?: string;
|
|
163
|
+
/** Unique user identifier */
|
|
164
|
+
userId?: string;
|
|
165
|
+
/** Device and location information */
|
|
166
|
+
device?: DeviceObject;
|
|
167
|
+
/** User demographic and interest data */
|
|
168
|
+
user?: UserObject;
|
|
169
|
+
/** Topics to exclude from ad matching */
|
|
170
|
+
excludedTopics?: string[];
|
|
171
|
+
/** Minimum relevancy score threshold (0-1) */
|
|
172
|
+
relevancy?: number | null;
|
|
173
|
+
/** Number of ads to return (1-3, default 1) */
|
|
174
|
+
numAds?: number;
|
|
175
|
+
/** Returns a test ad when true */
|
|
176
|
+
testAd?: boolean;
|
|
177
|
+
/** Additional custom fields */
|
|
178
|
+
[key: string]: unknown;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* POST /api/v1/ad/contextual
|
|
182
|
+
* @description Requires messages array for contextual targeting.
|
|
183
|
+
*/
|
|
184
|
+
interface ContextualAdParams extends AdRequestBaseV1 {
|
|
185
|
+
/** Array of conversation messages (required) */
|
|
186
|
+
messages: MessageObject[];
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* POST /api/v1/ad/summary
|
|
190
|
+
* @description Requires queryString for summary-based targeting.
|
|
191
|
+
*/
|
|
192
|
+
interface SummaryAdParams extends AdRequestBaseV1 {
|
|
193
|
+
/** Search/summary query string (required) */
|
|
194
|
+
queryString: string;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* POST /api/v1/ad/non-contextual
|
|
198
|
+
* @description No context required - returns ads without context matching.
|
|
199
|
+
*/
|
|
200
|
+
interface NonContextualAdParams extends AdRequestBaseV1 {
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* POST /api/v1/bid
|
|
204
|
+
* @description Two-phase bid request. Returns bid price and bidId.
|
|
205
|
+
* @note Does NOT extend AdRequestBaseV1 - has its own field set.
|
|
206
|
+
*/
|
|
207
|
+
interface BidParams {
|
|
208
|
+
/** Array of conversation messages (required) */
|
|
209
|
+
messages: MessageObject[];
|
|
210
|
+
/** Session identifier */
|
|
211
|
+
sessionId?: string;
|
|
212
|
+
/** Unique user identifier */
|
|
213
|
+
userId?: string;
|
|
214
|
+
/** Chat/conversation identifier */
|
|
215
|
+
chatId?: string;
|
|
216
|
+
/** Device and location information */
|
|
217
|
+
device?: DeviceObject;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* POST /api/v1/render
|
|
221
|
+
* @description Two-phase render request using cached bid context.
|
|
222
|
+
*/
|
|
223
|
+
interface RenderParams {
|
|
224
|
+
/** Bid identifier from the bid phase (required) */
|
|
225
|
+
bidId: string;
|
|
226
|
+
/** Realized price to charge (required) */
|
|
227
|
+
realizedPrice: number;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Single ad object in v1 responses.
|
|
231
|
+
* @description Contains all ad creative and tracking data.
|
|
232
|
+
*/
|
|
233
|
+
interface AdV1 {
|
|
234
|
+
/** The advertisement copy text */
|
|
235
|
+
adText: string;
|
|
236
|
+
/** Unique ad identifier */
|
|
237
|
+
adId: string;
|
|
238
|
+
/** Ad title */
|
|
239
|
+
title?: string;
|
|
240
|
+
/** Brand/advertiser name */
|
|
241
|
+
brandName?: string;
|
|
242
|
+
/** Brand logo image URL */
|
|
243
|
+
brandImage?: string;
|
|
244
|
+
/** Landing page URL */
|
|
245
|
+
url?: string;
|
|
246
|
+
/** Favicon URL */
|
|
247
|
+
favicon?: string;
|
|
248
|
+
/** Impression tracking URL */
|
|
249
|
+
impUrl?: string;
|
|
250
|
+
/** Click-through tracking URL */
|
|
251
|
+
clickUrl?: string;
|
|
252
|
+
/** Payout amount in USD */
|
|
253
|
+
payout?: number;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* v1 ad response (multi-ad support).
|
|
257
|
+
* @description Returned by contextual, summary, non-contextual, and render endpoints.
|
|
258
|
+
*/
|
|
259
|
+
interface AdResponseV1 {
|
|
260
|
+
/** Array of ad objects */
|
|
261
|
+
ads: AdV1[];
|
|
262
|
+
/** Number of ads returned */
|
|
263
|
+
numAds: number;
|
|
264
|
+
/** Total payout across all ads */
|
|
265
|
+
totalPayout?: number;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* v1 bid response.
|
|
269
|
+
* @description Returned by the bid endpoint.
|
|
270
|
+
*/
|
|
271
|
+
interface BidResponse {
|
|
272
|
+
/** Clearing price (CPM) */
|
|
273
|
+
bid: number;
|
|
274
|
+
/** Bid identifier for the render phase */
|
|
275
|
+
bidId: string;
|
|
276
|
+
}
|
|
156
277
|
|
|
157
278
|
/**
|
|
158
279
|
* Configuration options for the Gravity API Client
|
|
@@ -303,6 +424,131 @@ declare class Client {
|
|
|
303
424
|
* ```
|
|
304
425
|
*/
|
|
305
426
|
getAd(params: AdParams): Promise<AdResponse | null>;
|
|
427
|
+
/**
|
|
428
|
+
* Request contextual advertisements (v1 API)
|
|
429
|
+
*
|
|
430
|
+
* @description Fetches ads based on conversation context. Requires messages array.
|
|
431
|
+
* Returns null if no relevant ad is available or on error.
|
|
432
|
+
*
|
|
433
|
+
* @param params - Request parameters including messages array
|
|
434
|
+
* @returns Promise resolving to AdResponseV1 or null if no ad available
|
|
435
|
+
*
|
|
436
|
+
* @example
|
|
437
|
+
* ```typescript
|
|
438
|
+
* const response = await client.contextualAd({
|
|
439
|
+
* messages: [
|
|
440
|
+
* { role: 'user', content: 'What laptop should I buy?' }
|
|
441
|
+
* ],
|
|
442
|
+
* sessionId: 'session-123',
|
|
443
|
+
* userId: 'user-456',
|
|
444
|
+
* });
|
|
445
|
+
*
|
|
446
|
+
* if (response) {
|
|
447
|
+
* const ad = response.ads[0];
|
|
448
|
+
* console.log(ad.adText);
|
|
449
|
+
* }
|
|
450
|
+
* ```
|
|
451
|
+
*/
|
|
452
|
+
contextualAd(params: ContextualAdParams): Promise<AdResponseV1 | null>;
|
|
453
|
+
/**
|
|
454
|
+
* Request summary-based advertisements (v1 API)
|
|
455
|
+
*
|
|
456
|
+
* @description Fetches ads based on a search/summary query string.
|
|
457
|
+
* Returns null if no relevant ad is available or on error.
|
|
458
|
+
*
|
|
459
|
+
* @param params - Request parameters including queryString
|
|
460
|
+
* @returns Promise resolving to AdResponseV1 or null if no ad available
|
|
461
|
+
*
|
|
462
|
+
* @example
|
|
463
|
+
* ```typescript
|
|
464
|
+
* const response = await client.summaryAd({
|
|
465
|
+
* queryString: 'best laptops for programming 2025',
|
|
466
|
+
* sessionId: 'session-123',
|
|
467
|
+
* });
|
|
468
|
+
*
|
|
469
|
+
* if (response) {
|
|
470
|
+
* const ad = response.ads[0];
|
|
471
|
+
* console.log(ad.adText);
|
|
472
|
+
* }
|
|
473
|
+
* ```
|
|
474
|
+
*/
|
|
475
|
+
summaryAd(params: SummaryAdParams): Promise<AdResponseV1 | null>;
|
|
476
|
+
/**
|
|
477
|
+
* Request non-contextual advertisements (v1 API)
|
|
478
|
+
*
|
|
479
|
+
* @description Fetches ads without context matching. Useful for brand awareness placements.
|
|
480
|
+
* Returns null if no ad is available or on error.
|
|
481
|
+
*
|
|
482
|
+
* @param params - Optional request parameters
|
|
483
|
+
* @returns Promise resolving to AdResponseV1 or null if no ad available
|
|
484
|
+
*
|
|
485
|
+
* @example
|
|
486
|
+
* ```typescript
|
|
487
|
+
* const response = await client.nonContextualAd({
|
|
488
|
+
* sessionId: 'session-123',
|
|
489
|
+
* numAds: 2,
|
|
490
|
+
* });
|
|
491
|
+
*
|
|
492
|
+
* if (response) {
|
|
493
|
+
* response.ads.forEach(ad => console.log(ad.adText));
|
|
494
|
+
* }
|
|
495
|
+
* ```
|
|
496
|
+
*/
|
|
497
|
+
nonContextualAd(params?: NonContextualAdParams): Promise<AdResponseV1 | null>;
|
|
498
|
+
/**
|
|
499
|
+
* Request a bid price for contextual ad placement (v1 API)
|
|
500
|
+
*
|
|
501
|
+
* @description First phase of two-phase ad flow. Returns bid price and bidId.
|
|
502
|
+
* Use the bidId with render() to generate the actual ad creative.
|
|
503
|
+
* Returns null if no bid is available or on error.
|
|
504
|
+
*
|
|
505
|
+
* @param params - Request parameters including messages array
|
|
506
|
+
* @returns Promise resolving to BidResponse or null if no bid available
|
|
507
|
+
*
|
|
508
|
+
* @example
|
|
509
|
+
* ```typescript
|
|
510
|
+
* const bidResult = await client.bid({
|
|
511
|
+
* messages: [
|
|
512
|
+
* { role: 'user', content: 'I need help with my code' }
|
|
513
|
+
* ],
|
|
514
|
+
* sessionId: 'session-123',
|
|
515
|
+
* });
|
|
516
|
+
*
|
|
517
|
+
* if (bidResult) {
|
|
518
|
+
* console.log(`Bid price: $${bidResult.bid} CPM`);
|
|
519
|
+
* // Decide whether to show ad based on price...
|
|
520
|
+
* const ad = await client.render({
|
|
521
|
+
* bidId: bidResult.bidId,
|
|
522
|
+
* realizedPrice: bidResult.bid,
|
|
523
|
+
* });
|
|
524
|
+
* }
|
|
525
|
+
* ```
|
|
526
|
+
*/
|
|
527
|
+
bid(params: BidParams): Promise<BidResponse | null>;
|
|
528
|
+
/**
|
|
529
|
+
* Render an ad from a cached bid (v1 API)
|
|
530
|
+
*
|
|
531
|
+
* @description Second phase of two-phase ad flow. Generates ad creative using cached bid context.
|
|
532
|
+
* Returns null if bid expired (404) or on error. Bid expires after 60 seconds.
|
|
533
|
+
*
|
|
534
|
+
* @param params - Request parameters including bidId and realizedPrice
|
|
535
|
+
* @returns Promise resolving to AdResponseV1 or null if bid expired/error
|
|
536
|
+
*
|
|
537
|
+
* @example
|
|
538
|
+
* ```typescript
|
|
539
|
+
* // After getting a bid...
|
|
540
|
+
* const ad = await client.render({
|
|
541
|
+
* bidId: bidResult.bidId,
|
|
542
|
+
* realizedPrice: bidResult.bid,
|
|
543
|
+
* });
|
|
544
|
+
*
|
|
545
|
+
* if (ad) {
|
|
546
|
+
* const firstAd = ad.ads[0];
|
|
547
|
+
* displayAd(firstAd);
|
|
548
|
+
* }
|
|
549
|
+
* ```
|
|
550
|
+
*/
|
|
551
|
+
render(params: RenderParams): Promise<AdResponseV1 | null>;
|
|
306
552
|
/**
|
|
307
553
|
* Handle and log API errors
|
|
308
554
|
*
|
|
@@ -317,4 +563,4 @@ declare class Client {
|
|
|
317
563
|
private handleError;
|
|
318
564
|
}
|
|
319
565
|
|
|
320
|
-
export { type AdParams, type AdResponse, type ApiErrorResponse, Client, type ClientParams };
|
|
566
|
+
export { type AdParams, type AdRequestBaseV1, type AdResponse, type AdResponseV1, type AdV1, type ApiErrorResponse, type BidParams, type BidResponse, Client, type ClientParams, type ContextualAdParams, type DeviceObject, type Gender, type MessageObject, type NonContextualAdParams, type RenderParams, type Role, type SummaryAdParams, type UserObject };
|
package/dist/index.d.ts
CHANGED
|
@@ -153,6 +153,127 @@ interface ApiErrorResponse {
|
|
|
153
153
|
/** HTTP status code */
|
|
154
154
|
statusCode?: number;
|
|
155
155
|
}
|
|
156
|
+
/**
|
|
157
|
+
* Base fields shared across all v1 ad requests.
|
|
158
|
+
* @description Mirrors engine's AdRequestBaseV1. All fields are optional.
|
|
159
|
+
*/
|
|
160
|
+
interface AdRequestBaseV1 {
|
|
161
|
+
/** Session identifier for tracking user sessions */
|
|
162
|
+
sessionId?: string;
|
|
163
|
+
/** Unique user identifier */
|
|
164
|
+
userId?: string;
|
|
165
|
+
/** Device and location information */
|
|
166
|
+
device?: DeviceObject;
|
|
167
|
+
/** User demographic and interest data */
|
|
168
|
+
user?: UserObject;
|
|
169
|
+
/** Topics to exclude from ad matching */
|
|
170
|
+
excludedTopics?: string[];
|
|
171
|
+
/** Minimum relevancy score threshold (0-1) */
|
|
172
|
+
relevancy?: number | null;
|
|
173
|
+
/** Number of ads to return (1-3, default 1) */
|
|
174
|
+
numAds?: number;
|
|
175
|
+
/** Returns a test ad when true */
|
|
176
|
+
testAd?: boolean;
|
|
177
|
+
/** Additional custom fields */
|
|
178
|
+
[key: string]: unknown;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* POST /api/v1/ad/contextual
|
|
182
|
+
* @description Requires messages array for contextual targeting.
|
|
183
|
+
*/
|
|
184
|
+
interface ContextualAdParams extends AdRequestBaseV1 {
|
|
185
|
+
/** Array of conversation messages (required) */
|
|
186
|
+
messages: MessageObject[];
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* POST /api/v1/ad/summary
|
|
190
|
+
* @description Requires queryString for summary-based targeting.
|
|
191
|
+
*/
|
|
192
|
+
interface SummaryAdParams extends AdRequestBaseV1 {
|
|
193
|
+
/** Search/summary query string (required) */
|
|
194
|
+
queryString: string;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* POST /api/v1/ad/non-contextual
|
|
198
|
+
* @description No context required - returns ads without context matching.
|
|
199
|
+
*/
|
|
200
|
+
interface NonContextualAdParams extends AdRequestBaseV1 {
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* POST /api/v1/bid
|
|
204
|
+
* @description Two-phase bid request. Returns bid price and bidId.
|
|
205
|
+
* @note Does NOT extend AdRequestBaseV1 - has its own field set.
|
|
206
|
+
*/
|
|
207
|
+
interface BidParams {
|
|
208
|
+
/** Array of conversation messages (required) */
|
|
209
|
+
messages: MessageObject[];
|
|
210
|
+
/** Session identifier */
|
|
211
|
+
sessionId?: string;
|
|
212
|
+
/** Unique user identifier */
|
|
213
|
+
userId?: string;
|
|
214
|
+
/** Chat/conversation identifier */
|
|
215
|
+
chatId?: string;
|
|
216
|
+
/** Device and location information */
|
|
217
|
+
device?: DeviceObject;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* POST /api/v1/render
|
|
221
|
+
* @description Two-phase render request using cached bid context.
|
|
222
|
+
*/
|
|
223
|
+
interface RenderParams {
|
|
224
|
+
/** Bid identifier from the bid phase (required) */
|
|
225
|
+
bidId: string;
|
|
226
|
+
/** Realized price to charge (required) */
|
|
227
|
+
realizedPrice: number;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Single ad object in v1 responses.
|
|
231
|
+
* @description Contains all ad creative and tracking data.
|
|
232
|
+
*/
|
|
233
|
+
interface AdV1 {
|
|
234
|
+
/** The advertisement copy text */
|
|
235
|
+
adText: string;
|
|
236
|
+
/** Unique ad identifier */
|
|
237
|
+
adId: string;
|
|
238
|
+
/** Ad title */
|
|
239
|
+
title?: string;
|
|
240
|
+
/** Brand/advertiser name */
|
|
241
|
+
brandName?: string;
|
|
242
|
+
/** Brand logo image URL */
|
|
243
|
+
brandImage?: string;
|
|
244
|
+
/** Landing page URL */
|
|
245
|
+
url?: string;
|
|
246
|
+
/** Favicon URL */
|
|
247
|
+
favicon?: string;
|
|
248
|
+
/** Impression tracking URL */
|
|
249
|
+
impUrl?: string;
|
|
250
|
+
/** Click-through tracking URL */
|
|
251
|
+
clickUrl?: string;
|
|
252
|
+
/** Payout amount in USD */
|
|
253
|
+
payout?: number;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* v1 ad response (multi-ad support).
|
|
257
|
+
* @description Returned by contextual, summary, non-contextual, and render endpoints.
|
|
258
|
+
*/
|
|
259
|
+
interface AdResponseV1 {
|
|
260
|
+
/** Array of ad objects */
|
|
261
|
+
ads: AdV1[];
|
|
262
|
+
/** Number of ads returned */
|
|
263
|
+
numAds: number;
|
|
264
|
+
/** Total payout across all ads */
|
|
265
|
+
totalPayout?: number;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* v1 bid response.
|
|
269
|
+
* @description Returned by the bid endpoint.
|
|
270
|
+
*/
|
|
271
|
+
interface BidResponse {
|
|
272
|
+
/** Clearing price (CPM) */
|
|
273
|
+
bid: number;
|
|
274
|
+
/** Bid identifier for the render phase */
|
|
275
|
+
bidId: string;
|
|
276
|
+
}
|
|
156
277
|
|
|
157
278
|
/**
|
|
158
279
|
* Configuration options for the Gravity API Client
|
|
@@ -303,6 +424,131 @@ declare class Client {
|
|
|
303
424
|
* ```
|
|
304
425
|
*/
|
|
305
426
|
getAd(params: AdParams): Promise<AdResponse | null>;
|
|
427
|
+
/**
|
|
428
|
+
* Request contextual advertisements (v1 API)
|
|
429
|
+
*
|
|
430
|
+
* @description Fetches ads based on conversation context. Requires messages array.
|
|
431
|
+
* Returns null if no relevant ad is available or on error.
|
|
432
|
+
*
|
|
433
|
+
* @param params - Request parameters including messages array
|
|
434
|
+
* @returns Promise resolving to AdResponseV1 or null if no ad available
|
|
435
|
+
*
|
|
436
|
+
* @example
|
|
437
|
+
* ```typescript
|
|
438
|
+
* const response = await client.contextualAd({
|
|
439
|
+
* messages: [
|
|
440
|
+
* { role: 'user', content: 'What laptop should I buy?' }
|
|
441
|
+
* ],
|
|
442
|
+
* sessionId: 'session-123',
|
|
443
|
+
* userId: 'user-456',
|
|
444
|
+
* });
|
|
445
|
+
*
|
|
446
|
+
* if (response) {
|
|
447
|
+
* const ad = response.ads[0];
|
|
448
|
+
* console.log(ad.adText);
|
|
449
|
+
* }
|
|
450
|
+
* ```
|
|
451
|
+
*/
|
|
452
|
+
contextualAd(params: ContextualAdParams): Promise<AdResponseV1 | null>;
|
|
453
|
+
/**
|
|
454
|
+
* Request summary-based advertisements (v1 API)
|
|
455
|
+
*
|
|
456
|
+
* @description Fetches ads based on a search/summary query string.
|
|
457
|
+
* Returns null if no relevant ad is available or on error.
|
|
458
|
+
*
|
|
459
|
+
* @param params - Request parameters including queryString
|
|
460
|
+
* @returns Promise resolving to AdResponseV1 or null if no ad available
|
|
461
|
+
*
|
|
462
|
+
* @example
|
|
463
|
+
* ```typescript
|
|
464
|
+
* const response = await client.summaryAd({
|
|
465
|
+
* queryString: 'best laptops for programming 2025',
|
|
466
|
+
* sessionId: 'session-123',
|
|
467
|
+
* });
|
|
468
|
+
*
|
|
469
|
+
* if (response) {
|
|
470
|
+
* const ad = response.ads[0];
|
|
471
|
+
* console.log(ad.adText);
|
|
472
|
+
* }
|
|
473
|
+
* ```
|
|
474
|
+
*/
|
|
475
|
+
summaryAd(params: SummaryAdParams): Promise<AdResponseV1 | null>;
|
|
476
|
+
/**
|
|
477
|
+
* Request non-contextual advertisements (v1 API)
|
|
478
|
+
*
|
|
479
|
+
* @description Fetches ads without context matching. Useful for brand awareness placements.
|
|
480
|
+
* Returns null if no ad is available or on error.
|
|
481
|
+
*
|
|
482
|
+
* @param params - Optional request parameters
|
|
483
|
+
* @returns Promise resolving to AdResponseV1 or null if no ad available
|
|
484
|
+
*
|
|
485
|
+
* @example
|
|
486
|
+
* ```typescript
|
|
487
|
+
* const response = await client.nonContextualAd({
|
|
488
|
+
* sessionId: 'session-123',
|
|
489
|
+
* numAds: 2,
|
|
490
|
+
* });
|
|
491
|
+
*
|
|
492
|
+
* if (response) {
|
|
493
|
+
* response.ads.forEach(ad => console.log(ad.adText));
|
|
494
|
+
* }
|
|
495
|
+
* ```
|
|
496
|
+
*/
|
|
497
|
+
nonContextualAd(params?: NonContextualAdParams): Promise<AdResponseV1 | null>;
|
|
498
|
+
/**
|
|
499
|
+
* Request a bid price for contextual ad placement (v1 API)
|
|
500
|
+
*
|
|
501
|
+
* @description First phase of two-phase ad flow. Returns bid price and bidId.
|
|
502
|
+
* Use the bidId with render() to generate the actual ad creative.
|
|
503
|
+
* Returns null if no bid is available or on error.
|
|
504
|
+
*
|
|
505
|
+
* @param params - Request parameters including messages array
|
|
506
|
+
* @returns Promise resolving to BidResponse or null if no bid available
|
|
507
|
+
*
|
|
508
|
+
* @example
|
|
509
|
+
* ```typescript
|
|
510
|
+
* const bidResult = await client.bid({
|
|
511
|
+
* messages: [
|
|
512
|
+
* { role: 'user', content: 'I need help with my code' }
|
|
513
|
+
* ],
|
|
514
|
+
* sessionId: 'session-123',
|
|
515
|
+
* });
|
|
516
|
+
*
|
|
517
|
+
* if (bidResult) {
|
|
518
|
+
* console.log(`Bid price: $${bidResult.bid} CPM`);
|
|
519
|
+
* // Decide whether to show ad based on price...
|
|
520
|
+
* const ad = await client.render({
|
|
521
|
+
* bidId: bidResult.bidId,
|
|
522
|
+
* realizedPrice: bidResult.bid,
|
|
523
|
+
* });
|
|
524
|
+
* }
|
|
525
|
+
* ```
|
|
526
|
+
*/
|
|
527
|
+
bid(params: BidParams): Promise<BidResponse | null>;
|
|
528
|
+
/**
|
|
529
|
+
* Render an ad from a cached bid (v1 API)
|
|
530
|
+
*
|
|
531
|
+
* @description Second phase of two-phase ad flow. Generates ad creative using cached bid context.
|
|
532
|
+
* Returns null if bid expired (404) or on error. Bid expires after 60 seconds.
|
|
533
|
+
*
|
|
534
|
+
* @param params - Request parameters including bidId and realizedPrice
|
|
535
|
+
* @returns Promise resolving to AdResponseV1 or null if bid expired/error
|
|
536
|
+
*
|
|
537
|
+
* @example
|
|
538
|
+
* ```typescript
|
|
539
|
+
* // After getting a bid...
|
|
540
|
+
* const ad = await client.render({
|
|
541
|
+
* bidId: bidResult.bidId,
|
|
542
|
+
* realizedPrice: bidResult.bid,
|
|
543
|
+
* });
|
|
544
|
+
*
|
|
545
|
+
* if (ad) {
|
|
546
|
+
* const firstAd = ad.ads[0];
|
|
547
|
+
* displayAd(firstAd);
|
|
548
|
+
* }
|
|
549
|
+
* ```
|
|
550
|
+
*/
|
|
551
|
+
render(params: RenderParams): Promise<AdResponseV1 | null>;
|
|
306
552
|
/**
|
|
307
553
|
* Handle and log API errors
|
|
308
554
|
*
|
|
@@ -317,4 +563,4 @@ declare class Client {
|
|
|
317
563
|
private handleError;
|
|
318
564
|
}
|
|
319
565
|
|
|
320
|
-
export { type AdParams, type AdResponse, type ApiErrorResponse, Client, type ClientParams };
|
|
566
|
+
export { type AdParams, type AdRequestBaseV1, type AdResponse, type AdResponseV1, type AdV1, type ApiErrorResponse, type BidParams, type BidResponse, Client, type ClientParams, type ContextualAdParams, type DeviceObject, type Gender, type MessageObject, type NonContextualAdParams, type RenderParams, type Role, type SummaryAdParams, type UserObject };
|
package/dist/index.js
CHANGED
|
@@ -130,8 +130,6 @@ var Client = class {
|
|
|
130
130
|
try {
|
|
131
131
|
const body = {
|
|
132
132
|
...params,
|
|
133
|
-
// Prefer explicit apiKey in params, else use client's apiKey
|
|
134
|
-
apiKey: params.apiKey ?? this.apiKey,
|
|
135
133
|
// Use request-level excludedTopics, or fall back to client-level
|
|
136
134
|
excludedTopics: params.excludedTopics ?? this.excludedTopics,
|
|
137
135
|
// Use request-level relevancy, or fall back to client-level
|
|
@@ -155,6 +153,224 @@ var Client = class {
|
|
|
155
153
|
return null;
|
|
156
154
|
}
|
|
157
155
|
}
|
|
156
|
+
// ===========================================================================
|
|
157
|
+
// v1 API Methods
|
|
158
|
+
// ===========================================================================
|
|
159
|
+
/**
|
|
160
|
+
* Request contextual advertisements (v1 API)
|
|
161
|
+
*
|
|
162
|
+
* @description Fetches ads based on conversation context. Requires messages array.
|
|
163
|
+
* Returns null if no relevant ad is available or on error.
|
|
164
|
+
*
|
|
165
|
+
* @param params - Request parameters including messages array
|
|
166
|
+
* @returns Promise resolving to AdResponseV1 or null if no ad available
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* ```typescript
|
|
170
|
+
* const response = await client.contextualAd({
|
|
171
|
+
* messages: [
|
|
172
|
+
* { role: 'user', content: 'What laptop should I buy?' }
|
|
173
|
+
* ],
|
|
174
|
+
* sessionId: 'session-123',
|
|
175
|
+
* userId: 'user-456',
|
|
176
|
+
* });
|
|
177
|
+
*
|
|
178
|
+
* if (response) {
|
|
179
|
+
* const ad = response.ads[0];
|
|
180
|
+
* console.log(ad.adText);
|
|
181
|
+
* }
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
async contextualAd(params) {
|
|
185
|
+
try {
|
|
186
|
+
const body = {
|
|
187
|
+
...params,
|
|
188
|
+
excludedTopics: params.excludedTopics ?? this.excludedTopics,
|
|
189
|
+
relevancy: params.relevancy ?? this.relevancy
|
|
190
|
+
};
|
|
191
|
+
const response = await this.axios.post("/api/v1/ad/contextual", body);
|
|
192
|
+
if (response.status === 204) {
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
if (response.data && response.data.ads && response.data.ads.length > 0) {
|
|
196
|
+
return response.data;
|
|
197
|
+
}
|
|
198
|
+
return null;
|
|
199
|
+
} catch (error) {
|
|
200
|
+
this.handleError(error, "contextualAd");
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Request summary-based advertisements (v1 API)
|
|
206
|
+
*
|
|
207
|
+
* @description Fetches ads based on a search/summary query string.
|
|
208
|
+
* Returns null if no relevant ad is available or on error.
|
|
209
|
+
*
|
|
210
|
+
* @param params - Request parameters including queryString
|
|
211
|
+
* @returns Promise resolving to AdResponseV1 or null if no ad available
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* ```typescript
|
|
215
|
+
* const response = await client.summaryAd({
|
|
216
|
+
* queryString: 'best laptops for programming 2025',
|
|
217
|
+
* sessionId: 'session-123',
|
|
218
|
+
* });
|
|
219
|
+
*
|
|
220
|
+
* if (response) {
|
|
221
|
+
* const ad = response.ads[0];
|
|
222
|
+
* console.log(ad.adText);
|
|
223
|
+
* }
|
|
224
|
+
* ```
|
|
225
|
+
*/
|
|
226
|
+
async summaryAd(params) {
|
|
227
|
+
try {
|
|
228
|
+
const body = {
|
|
229
|
+
...params,
|
|
230
|
+
excludedTopics: params.excludedTopics ?? this.excludedTopics,
|
|
231
|
+
relevancy: params.relevancy ?? this.relevancy
|
|
232
|
+
};
|
|
233
|
+
const response = await this.axios.post("/api/v1/ad/summary", body);
|
|
234
|
+
if (response.status === 204) {
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
if (response.data && response.data.ads && response.data.ads.length > 0) {
|
|
238
|
+
return response.data;
|
|
239
|
+
}
|
|
240
|
+
return null;
|
|
241
|
+
} catch (error) {
|
|
242
|
+
this.handleError(error, "summaryAd");
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Request non-contextual advertisements (v1 API)
|
|
248
|
+
*
|
|
249
|
+
* @description Fetches ads without context matching. Useful for brand awareness placements.
|
|
250
|
+
* Returns null if no ad is available or on error.
|
|
251
|
+
*
|
|
252
|
+
* @param params - Optional request parameters
|
|
253
|
+
* @returns Promise resolving to AdResponseV1 or null if no ad available
|
|
254
|
+
*
|
|
255
|
+
* @example
|
|
256
|
+
* ```typescript
|
|
257
|
+
* const response = await client.nonContextualAd({
|
|
258
|
+
* sessionId: 'session-123',
|
|
259
|
+
* numAds: 2,
|
|
260
|
+
* });
|
|
261
|
+
*
|
|
262
|
+
* if (response) {
|
|
263
|
+
* response.ads.forEach(ad => console.log(ad.adText));
|
|
264
|
+
* }
|
|
265
|
+
* ```
|
|
266
|
+
*/
|
|
267
|
+
async nonContextualAd(params = {}) {
|
|
268
|
+
try {
|
|
269
|
+
const body = {
|
|
270
|
+
...params,
|
|
271
|
+
excludedTopics: params.excludedTopics ?? this.excludedTopics
|
|
272
|
+
};
|
|
273
|
+
const response = await this.axios.post("/api/v1/ad/non-contextual", body);
|
|
274
|
+
if (response.status === 204) {
|
|
275
|
+
return null;
|
|
276
|
+
}
|
|
277
|
+
if (response.data && response.data.ads && response.data.ads.length > 0) {
|
|
278
|
+
return response.data;
|
|
279
|
+
}
|
|
280
|
+
return null;
|
|
281
|
+
} catch (error) {
|
|
282
|
+
this.handleError(error, "nonContextualAd");
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Request a bid price for contextual ad placement (v1 API)
|
|
288
|
+
*
|
|
289
|
+
* @description First phase of two-phase ad flow. Returns bid price and bidId.
|
|
290
|
+
* Use the bidId with render() to generate the actual ad creative.
|
|
291
|
+
* Returns null if no bid is available or on error.
|
|
292
|
+
*
|
|
293
|
+
* @param params - Request parameters including messages array
|
|
294
|
+
* @returns Promise resolving to BidResponse or null if no bid available
|
|
295
|
+
*
|
|
296
|
+
* @example
|
|
297
|
+
* ```typescript
|
|
298
|
+
* const bidResult = await client.bid({
|
|
299
|
+
* messages: [
|
|
300
|
+
* { role: 'user', content: 'I need help with my code' }
|
|
301
|
+
* ],
|
|
302
|
+
* sessionId: 'session-123',
|
|
303
|
+
* });
|
|
304
|
+
*
|
|
305
|
+
* if (bidResult) {
|
|
306
|
+
* console.log(`Bid price: $${bidResult.bid} CPM`);
|
|
307
|
+
* // Decide whether to show ad based on price...
|
|
308
|
+
* const ad = await client.render({
|
|
309
|
+
* bidId: bidResult.bidId,
|
|
310
|
+
* realizedPrice: bidResult.bid,
|
|
311
|
+
* });
|
|
312
|
+
* }
|
|
313
|
+
* ```
|
|
314
|
+
*/
|
|
315
|
+
async bid(params) {
|
|
316
|
+
try {
|
|
317
|
+
const response = await this.axios.post("/api/v1/bid", params);
|
|
318
|
+
if (response.status === 204) {
|
|
319
|
+
return null;
|
|
320
|
+
}
|
|
321
|
+
if (response.data && response.data.data) {
|
|
322
|
+
return {
|
|
323
|
+
bid: response.data.data.bid,
|
|
324
|
+
bidId: response.data.data.bidId
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
return null;
|
|
328
|
+
} catch (error) {
|
|
329
|
+
this.handleError(error, "bid");
|
|
330
|
+
return null;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Render an ad from a cached bid (v1 API)
|
|
335
|
+
*
|
|
336
|
+
* @description Second phase of two-phase ad flow. Generates ad creative using cached bid context.
|
|
337
|
+
* Returns null if bid expired (404) or on error. Bid expires after 60 seconds.
|
|
338
|
+
*
|
|
339
|
+
* @param params - Request parameters including bidId and realizedPrice
|
|
340
|
+
* @returns Promise resolving to AdResponseV1 or null if bid expired/error
|
|
341
|
+
*
|
|
342
|
+
* @example
|
|
343
|
+
* ```typescript
|
|
344
|
+
* // After getting a bid...
|
|
345
|
+
* const ad = await client.render({
|
|
346
|
+
* bidId: bidResult.bidId,
|
|
347
|
+
* realizedPrice: bidResult.bid,
|
|
348
|
+
* });
|
|
349
|
+
*
|
|
350
|
+
* if (ad) {
|
|
351
|
+
* const firstAd = ad.ads[0];
|
|
352
|
+
* displayAd(firstAd);
|
|
353
|
+
* }
|
|
354
|
+
* ```
|
|
355
|
+
*/
|
|
356
|
+
async render(params) {
|
|
357
|
+
try {
|
|
358
|
+
const response = await this.axios.post("/api/v1/render", params);
|
|
359
|
+
if (response.status === 204) {
|
|
360
|
+
return null;
|
|
361
|
+
}
|
|
362
|
+
if (response.data && response.data.ads && response.data.ads.length > 0) {
|
|
363
|
+
return response.data;
|
|
364
|
+
}
|
|
365
|
+
return null;
|
|
366
|
+
} catch (error) {
|
|
367
|
+
if (import_axios.default.isAxiosError(error) && error.response?.status === 404) {
|
|
368
|
+
return null;
|
|
369
|
+
}
|
|
370
|
+
this.handleError(error, "render");
|
|
371
|
+
return null;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
158
374
|
/**
|
|
159
375
|
* Handle and log API errors
|
|
160
376
|
*
|
package/dist/index.mjs
CHANGED
|
@@ -94,8 +94,6 @@ var Client = class {
|
|
|
94
94
|
try {
|
|
95
95
|
const body = {
|
|
96
96
|
...params,
|
|
97
|
-
// Prefer explicit apiKey in params, else use client's apiKey
|
|
98
|
-
apiKey: params.apiKey ?? this.apiKey,
|
|
99
97
|
// Use request-level excludedTopics, or fall back to client-level
|
|
100
98
|
excludedTopics: params.excludedTopics ?? this.excludedTopics,
|
|
101
99
|
// Use request-level relevancy, or fall back to client-level
|
|
@@ -119,6 +117,224 @@ var Client = class {
|
|
|
119
117
|
return null;
|
|
120
118
|
}
|
|
121
119
|
}
|
|
120
|
+
// ===========================================================================
|
|
121
|
+
// v1 API Methods
|
|
122
|
+
// ===========================================================================
|
|
123
|
+
/**
|
|
124
|
+
* Request contextual advertisements (v1 API)
|
|
125
|
+
*
|
|
126
|
+
* @description Fetches ads based on conversation context. Requires messages array.
|
|
127
|
+
* Returns null if no relevant ad is available or on error.
|
|
128
|
+
*
|
|
129
|
+
* @param params - Request parameters including messages array
|
|
130
|
+
* @returns Promise resolving to AdResponseV1 or null if no ad available
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```typescript
|
|
134
|
+
* const response = await client.contextualAd({
|
|
135
|
+
* messages: [
|
|
136
|
+
* { role: 'user', content: 'What laptop should I buy?' }
|
|
137
|
+
* ],
|
|
138
|
+
* sessionId: 'session-123',
|
|
139
|
+
* userId: 'user-456',
|
|
140
|
+
* });
|
|
141
|
+
*
|
|
142
|
+
* if (response) {
|
|
143
|
+
* const ad = response.ads[0];
|
|
144
|
+
* console.log(ad.adText);
|
|
145
|
+
* }
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
async contextualAd(params) {
|
|
149
|
+
try {
|
|
150
|
+
const body = {
|
|
151
|
+
...params,
|
|
152
|
+
excludedTopics: params.excludedTopics ?? this.excludedTopics,
|
|
153
|
+
relevancy: params.relevancy ?? this.relevancy
|
|
154
|
+
};
|
|
155
|
+
const response = await this.axios.post("/api/v1/ad/contextual", body);
|
|
156
|
+
if (response.status === 204) {
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
if (response.data && response.data.ads && response.data.ads.length > 0) {
|
|
160
|
+
return response.data;
|
|
161
|
+
}
|
|
162
|
+
return null;
|
|
163
|
+
} catch (error) {
|
|
164
|
+
this.handleError(error, "contextualAd");
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Request summary-based advertisements (v1 API)
|
|
170
|
+
*
|
|
171
|
+
* @description Fetches ads based on a search/summary query string.
|
|
172
|
+
* Returns null if no relevant ad is available or on error.
|
|
173
|
+
*
|
|
174
|
+
* @param params - Request parameters including queryString
|
|
175
|
+
* @returns Promise resolving to AdResponseV1 or null if no ad available
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* ```typescript
|
|
179
|
+
* const response = await client.summaryAd({
|
|
180
|
+
* queryString: 'best laptops for programming 2025',
|
|
181
|
+
* sessionId: 'session-123',
|
|
182
|
+
* });
|
|
183
|
+
*
|
|
184
|
+
* if (response) {
|
|
185
|
+
* const ad = response.ads[0];
|
|
186
|
+
* console.log(ad.adText);
|
|
187
|
+
* }
|
|
188
|
+
* ```
|
|
189
|
+
*/
|
|
190
|
+
async summaryAd(params) {
|
|
191
|
+
try {
|
|
192
|
+
const body = {
|
|
193
|
+
...params,
|
|
194
|
+
excludedTopics: params.excludedTopics ?? this.excludedTopics,
|
|
195
|
+
relevancy: params.relevancy ?? this.relevancy
|
|
196
|
+
};
|
|
197
|
+
const response = await this.axios.post("/api/v1/ad/summary", body);
|
|
198
|
+
if (response.status === 204) {
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
if (response.data && response.data.ads && response.data.ads.length > 0) {
|
|
202
|
+
return response.data;
|
|
203
|
+
}
|
|
204
|
+
return null;
|
|
205
|
+
} catch (error) {
|
|
206
|
+
this.handleError(error, "summaryAd");
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Request non-contextual advertisements (v1 API)
|
|
212
|
+
*
|
|
213
|
+
* @description Fetches ads without context matching. Useful for brand awareness placements.
|
|
214
|
+
* Returns null if no ad is available or on error.
|
|
215
|
+
*
|
|
216
|
+
* @param params - Optional request parameters
|
|
217
|
+
* @returns Promise resolving to AdResponseV1 or null if no ad available
|
|
218
|
+
*
|
|
219
|
+
* @example
|
|
220
|
+
* ```typescript
|
|
221
|
+
* const response = await client.nonContextualAd({
|
|
222
|
+
* sessionId: 'session-123',
|
|
223
|
+
* numAds: 2,
|
|
224
|
+
* });
|
|
225
|
+
*
|
|
226
|
+
* if (response) {
|
|
227
|
+
* response.ads.forEach(ad => console.log(ad.adText));
|
|
228
|
+
* }
|
|
229
|
+
* ```
|
|
230
|
+
*/
|
|
231
|
+
async nonContextualAd(params = {}) {
|
|
232
|
+
try {
|
|
233
|
+
const body = {
|
|
234
|
+
...params,
|
|
235
|
+
excludedTopics: params.excludedTopics ?? this.excludedTopics
|
|
236
|
+
};
|
|
237
|
+
const response = await this.axios.post("/api/v1/ad/non-contextual", body);
|
|
238
|
+
if (response.status === 204) {
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
if (response.data && response.data.ads && response.data.ads.length > 0) {
|
|
242
|
+
return response.data;
|
|
243
|
+
}
|
|
244
|
+
return null;
|
|
245
|
+
} catch (error) {
|
|
246
|
+
this.handleError(error, "nonContextualAd");
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Request a bid price for contextual ad placement (v1 API)
|
|
252
|
+
*
|
|
253
|
+
* @description First phase of two-phase ad flow. Returns bid price and bidId.
|
|
254
|
+
* Use the bidId with render() to generate the actual ad creative.
|
|
255
|
+
* Returns null if no bid is available or on error.
|
|
256
|
+
*
|
|
257
|
+
* @param params - Request parameters including messages array
|
|
258
|
+
* @returns Promise resolving to BidResponse or null if no bid available
|
|
259
|
+
*
|
|
260
|
+
* @example
|
|
261
|
+
* ```typescript
|
|
262
|
+
* const bidResult = await client.bid({
|
|
263
|
+
* messages: [
|
|
264
|
+
* { role: 'user', content: 'I need help with my code' }
|
|
265
|
+
* ],
|
|
266
|
+
* sessionId: 'session-123',
|
|
267
|
+
* });
|
|
268
|
+
*
|
|
269
|
+
* if (bidResult) {
|
|
270
|
+
* console.log(`Bid price: $${bidResult.bid} CPM`);
|
|
271
|
+
* // Decide whether to show ad based on price...
|
|
272
|
+
* const ad = await client.render({
|
|
273
|
+
* bidId: bidResult.bidId,
|
|
274
|
+
* realizedPrice: bidResult.bid,
|
|
275
|
+
* });
|
|
276
|
+
* }
|
|
277
|
+
* ```
|
|
278
|
+
*/
|
|
279
|
+
async bid(params) {
|
|
280
|
+
try {
|
|
281
|
+
const response = await this.axios.post("/api/v1/bid", params);
|
|
282
|
+
if (response.status === 204) {
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
if (response.data && response.data.data) {
|
|
286
|
+
return {
|
|
287
|
+
bid: response.data.data.bid,
|
|
288
|
+
bidId: response.data.data.bidId
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
return null;
|
|
292
|
+
} catch (error) {
|
|
293
|
+
this.handleError(error, "bid");
|
|
294
|
+
return null;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Render an ad from a cached bid (v1 API)
|
|
299
|
+
*
|
|
300
|
+
* @description Second phase of two-phase ad flow. Generates ad creative using cached bid context.
|
|
301
|
+
* Returns null if bid expired (404) or on error. Bid expires after 60 seconds.
|
|
302
|
+
*
|
|
303
|
+
* @param params - Request parameters including bidId and realizedPrice
|
|
304
|
+
* @returns Promise resolving to AdResponseV1 or null if bid expired/error
|
|
305
|
+
*
|
|
306
|
+
* @example
|
|
307
|
+
* ```typescript
|
|
308
|
+
* // After getting a bid...
|
|
309
|
+
* const ad = await client.render({
|
|
310
|
+
* bidId: bidResult.bidId,
|
|
311
|
+
* realizedPrice: bidResult.bid,
|
|
312
|
+
* });
|
|
313
|
+
*
|
|
314
|
+
* if (ad) {
|
|
315
|
+
* const firstAd = ad.ads[0];
|
|
316
|
+
* displayAd(firstAd);
|
|
317
|
+
* }
|
|
318
|
+
* ```
|
|
319
|
+
*/
|
|
320
|
+
async render(params) {
|
|
321
|
+
try {
|
|
322
|
+
const response = await this.axios.post("/api/v1/render", params);
|
|
323
|
+
if (response.status === 204) {
|
|
324
|
+
return null;
|
|
325
|
+
}
|
|
326
|
+
if (response.data && response.data.ads && response.data.ads.length > 0) {
|
|
327
|
+
return response.data;
|
|
328
|
+
}
|
|
329
|
+
return null;
|
|
330
|
+
} catch (error) {
|
|
331
|
+
if (axios.isAxiosError(error) && error.response?.status === 404) {
|
|
332
|
+
return null;
|
|
333
|
+
}
|
|
334
|
+
this.handleError(error, "render");
|
|
335
|
+
return null;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
122
338
|
/**
|
|
123
339
|
* Handle and log API errors
|
|
124
340
|
*
|