@gravity-ai/api 1.0.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,6 +2,24 @@
2
2
 
3
3
  The official Node.js/TypeScript SDK for the Gravity AI advertising API. Fetch contextually relevant ads based on conversation content.
4
4
 
5
+ ## Table of Contents
6
+
7
+ - [Installation](#installation)
8
+ - [Quick Start](#quick-start)
9
+ - [Migrating from v0](#migrating-from-v0)
10
+ - [Client Configuration](#client-configuration)
11
+ - [Integration Types](#integration-types)
12
+ - [Web](#web)
13
+ - [IDE / CLI](#ide--cli)
14
+ - [Mobile](#mobile)
15
+ - [General](#general)
16
+ - [Response Types](#response-types)
17
+ - [Error Handling](#error-handling)
18
+ - [Using with React](#using-with-react)
19
+ - [Best Practices](#best-practices)
20
+
21
+ ---
22
+
5
23
  ## Installation
6
24
 
7
25
  ```bash
@@ -10,6 +28,8 @@ npm install @gravity-ai/api
10
28
 
11
29
  > **Note:** Requires Node.js 18+
12
30
 
31
+ ---
32
+
13
33
  ## Quick Start
14
34
 
15
35
  ```typescript
@@ -20,10 +40,14 @@ const client = new Client('your-api-key');
20
40
  const response = await client.getAd({
21
41
  messages: [
22
42
  { role: 'user', content: 'What are some good hiking trails?' },
23
- { role: 'assistant', content: 'Here are some popular trails...' }
24
43
  ],
25
- sessionId: 'session-123', // Recommended
26
- userId: 'user-456', // Recommended
44
+ sessionId: 'session-123',
45
+ userId: 'user-456',
46
+ numAds: 1,
47
+ render_context: {
48
+ placements: [{ placement: 'below_response' }]
49
+ },
50
+ testAd: true,
27
51
  });
28
52
 
29
53
  if (response) {
@@ -32,142 +56,347 @@ if (response) {
32
56
  }
33
57
  ```
34
58
 
59
+ ---
60
+
35
61
  ## Migrating from v0
36
62
 
37
- If you're upgrading from a previous version, the `getAd()` response format has changed:
63
+ If you're upgrading from a previous version, there are key changes:
64
+
65
+ **1. `sessionId` is now required**
66
+
67
+ **2. `render_context` object with `placements` array is now required**
68
+
69
+ **3. Response format changed to `ads` array**
38
70
 
39
71
  ```typescript
40
72
  // Before (v0)
41
73
  const ad = await client.getAd({ messages });
42
- if (ad) {
43
- console.log(ad.adText);
44
- }
45
74
 
46
75
  // After (v1)
47
- const response = await client.getAd({ messages, sessionId: '...' });
48
- if (response) {
49
- const ad = response.ads[0];
50
- console.log(ad.adText);
51
- }
76
+ const response = await client.getAd({
77
+ messages,
78
+ sessionId: 'session-123',
79
+ numAds: 1,
80
+ render_context: {
81
+ placements: [{ placement: 'below_response' }]
82
+ }
83
+ });
84
+ const ad = response?.ads[0];
52
85
  ```
53
86
 
54
- The response is now an object with an `ads` array instead of a single ad object.
55
-
56
87
  ---
57
88
 
58
89
  ## Client Configuration
59
90
 
60
- ### Basic Initialization
61
-
62
91
  ```typescript
63
92
  import { Client } from '@gravity-ai/api';
64
93
 
94
+ // Basic
65
95
  const client = new Client('your-api-key');
66
- ```
67
-
68
- ### Advanced Configuration
69
-
70
- ```typescript
71
- import { Client } from '@gravity-ai/api';
72
96
 
97
+ // Advanced
73
98
  const client = new Client('your-api-key', {
74
- // Topics to exclude globally (optional)
75
- excludedTopics: ['politics', 'religion'],
76
-
77
- // Minimum relevancy threshold 0-1 (optional)
78
- relevancy: 0.8,
99
+ excludedTopics: ['politics', 'religion'], // Global exclusions
100
+ relevancy: 0.6, // Min relevancy threshold (0.1-1)
79
101
  });
80
102
  ```
81
103
 
82
- #### Configuration Options
83
-
84
104
  | Option | Type | Default | Description |
85
105
  |--------|------|---------|-------------|
86
106
  | `endpoint` | `string` | `'https://server.trygravity.ai'` | API endpoint URL |
87
107
  | `excludedTopics` | `string[]` | `[]` | Topics to exclude from ad matching |
88
- | `relevancy` | `number \| null` | `null` | Minimum relevancy score (0-1) |
108
+ | `relevancy` | `number` | `null` | Minimum relevancy score (0.1-1) |
89
109
 
90
110
  ---
91
111
 
92
- ## `getAd()` — Fetch Contextual Ads
112
+ ## Integration Types
113
+
114
+ Choose the integration type that matches your application. All types share a **common schema**.
115
+
116
+ ### Common Fields
117
+
118
+ | Field | Type | Description |
119
+ |-------|------|-------------|
120
+ | `messages` | `MessageObject[]` | Conversation context. Array of `{role, content}` objects. **Required.** |
121
+ | `sessionId` | `string` | Session identifier for frequency capping. **Required.** |
122
+ | `render_context` | `RenderContextObject` | Describes how the ad will be rendered in your app. **Required.** |
123
+ | `userId` | `string` | Unique user identifier. |
124
+ | `testAd` | `boolean` | Returns real ad without tracking. Use for testing. |
125
+ | `numAds` | `number` | Number of ads to return (1-3). Must match `placements` length. |
126
+
127
+ #### What is `render_context`?
128
+
129
+ The `render_context` object describes how the ad will be rendered in your app, so Gravity can generate a more contextually relevant ad.
130
+
131
+ For example:
132
+ - **`placements`** — Where you plan to show the ad (below the response, in a sidebar, etc.)
133
+ - **`max_ad_length`** — Character limit you can display, so we don't send copy that gets truncated
134
+ - **`supports_markdown`** — Whether you can render formatted text
135
+ - **`supports_images`** — Whether you can display brand logos or product images
136
+
137
+ The more context you provide, the better we can optimize the ad copy, format, and creative for your specific integration.
138
+
139
+ <details>
140
+ <summary><strong>RenderContextObject</strong></summary>
141
+
142
+ | Field | Type | Description |
143
+ |-------|------|-------------|
144
+ | `placements` | `PlacementObject[]` | Array of placement objects (1-3). Length must match `numAds`. **Required.** |
145
+ | `max_ad_length` | `number` | Max characters for ad text. |
146
+ | `supports_markdown` | `boolean` | Whether markdown rendering is supported. |
147
+ | `supports_links` | `boolean` | Whether clickable links are supported. |
148
+ | `supports_images` | `boolean` | Whether images can be displayed. |
149
+ | `supports_cta_button` | `boolean` | Whether CTA buttons are supported. |
150
+
151
+ </details>
152
+
153
+ <details>
154
+ <summary><strong>PlacementObject</strong></summary>
93
155
 
94
- Fetch ads based on conversation context. Requires `messages` array.
156
+ | Field | Type | Description |
157
+ |-------|------|-------------|
158
+ | `placement` | `string` | **Required.** One of: `"above_response"`, `"below_response"`, `"inline_response"`, `"left_response"`, `"right_response"` |
159
+ | `placement_id` | `string` | Optional tracking ID for this ad slot. |
160
+
161
+ </details>
162
+
163
+ <details>
164
+ <summary><strong>DeviceObject</strong></summary>
165
+
166
+ | Field | Type | Description |
167
+ |-------|------|-------------|
168
+ | `ip` | `string` | IP address for geo-targeting. **Required.** |
169
+ | `ua` | `string` | User agent string. Enables browser/device detection. |
170
+ | `os` | `string` | Operating system: `"macos"`, `"windows"`, `"linux"`, `"iOS"`, `"Android"`. |
171
+ | `os_version` | `string` | OS version (e.g., `"17.2"`). |
172
+ | `browser` | `string` | Browser name: `"chrome"`, `"safari"`, `"firefox"`. |
173
+ | `device_type` | `string` | `"desktop"`, `"mobile"`, `"tablet"`. |
174
+ | `device_model` | `string` | Device model (e.g., `"iPhone 15 Pro"`). |
175
+ | `ifa` | `string` | IDFA/GAID for cross-app attribution. **Higher CPMs.** |
176
+ | `timezone` | `string` | IANA timezone (e.g., `"America/New_York"`). |
177
+ | `locale` | `string` | Locale (e.g., `"en-US"`). |
178
+ | `connection_type` | `string` | `"wifi"` or `"cellular"`. |
179
+
180
+ </details>
181
+
182
+ <details>
183
+ <summary><strong>UserObject</strong></summary>
184
+
185
+ | Field | Type | Description |
186
+ |-------|------|-------------|
187
+ | `email` | `string` | User's email for identity matching. **Higher CPMs.** |
188
+ | `gender` | `string` | `"male"`, `"female"`, `"other"`. |
189
+ | `age` | `string` | Age range: `"18-24"`, `"25-34"`, `"35-44"`, etc. |
190
+ | `keywords` | `string` | Comma-separated interest keywords. |
191
+ | `subscription_tier` | `string` | `"free"`, `"pro"`, `"premium"`, `"enterprise"`. |
192
+ | `user_created_at` | `string` | Account creation date (ISO 8601). |
193
+ | `user_interests` | `string[]` | Array of user interests for targeting. |
194
+
195
+ </details>
196
+
197
+ ---
198
+
199
+ ### Web
200
+
201
+ **For:** Chat interfaces, AI assistants, web apps with conversational UI
202
+
203
+ #### Web-specific Fields
204
+
205
+ | Field | Type | Description |
206
+ |-------|------|-------------|
207
+ | `web.referrer` | `string` | Referring URL. Enables traffic source targeting. |
208
+
209
+ #### Example
95
210
 
96
211
  ```typescript
97
212
  const response = await client.getAd({
213
+ // Common fields
98
214
  messages: [
99
- { role: 'user', content: 'I need help finding a new laptop.' },
100
- { role: 'assistant', content: 'What is your budget?' }
215
+ { role: 'user', content: 'What are the best practices for React performance?' }
101
216
  ],
102
- sessionId: 'session-123', // Recommended
103
- userId: 'user-456', // Recommended
104
- numAds: 1, // 1-3, default 1
217
+ sessionId: 'session-web-001',
218
+ userId: 'user-web-789',
219
+ numAds: 1,
220
+ testAd: true,
221
+ render_context: {
222
+ placements: [
223
+ { placement: 'right_response', placement_id: 'sidebar-1' }
224
+ ],
225
+ max_ad_length: 200
226
+ },
227
+
228
+ // Web-specific fields
229
+ user: {
230
+ email: 'webuser@example.com',
231
+ subscription_tier: 'pro'
232
+ },
233
+ device: {
234
+ ip: '203.0.113.50',
235
+ ua: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0',
236
+ browser: 'chrome',
237
+ device_type: 'desktop',
238
+ timezone: 'Europe/London',
239
+ locale: 'en-GB'
240
+ },
241
+ web: {
242
+ referrer: 'https://google.com'
243
+ }
105
244
  });
245
+ ```
106
246
 
107
- if (response) {
108
- const ad = response.ads[0];
109
- console.log(ad.adText);
110
- }
247
+ ---
248
+
249
+ ### IDE / CLI
250
+
251
+ **For:** Dev tools like Cursor, Claude Code, GitHub Copilot, Windsurf and VS Code extensions
252
+
253
+ #### IDE-specific Fields
254
+
255
+ <details>
256
+ <summary><strong>IDEObject</strong></summary>
257
+
258
+ | Field | Type | Description |
259
+ |-------|------|-------------|
260
+ | `name` | `string` | IDE name: `"cursor"`, `"vscode"`, `"intellij"`. |
261
+ | `session_duration_ms` | `number` | Time since IDE opened. Helps with engagement-based targeting. |
262
+ | `active_file_language` | `string` | Current file language (e.g., `"typescript"`). |
263
+
264
+ </details>
265
+
266
+ #### Example
267
+
268
+ ```typescript
269
+ const response = await client.getAd({
270
+ // Common fields
271
+ messages: [
272
+ { role: 'user', content: 'How do I set up authentication in my Express app?' }
273
+ ],
274
+ sessionId: 'session-ide-001',
275
+ userId: 'user-dev-123',
276
+ numAds: 1,
277
+ testAd: true,
278
+ render_context: {
279
+ placements: [
280
+ { placement: 'below_response' }
281
+ ],
282
+ max_ad_length: 280,
283
+ supports_markdown: true,
284
+ supports_links: true
285
+ },
286
+
287
+ // IDE-specific fields
288
+ user: {
289
+ email: 'developer@example.com'
290
+ },
291
+ device: {
292
+ ip: '192.168.1.100',
293
+ os: 'macos',
294
+ timezone: 'America/New_York',
295
+ locale: 'en-US'
296
+ },
297
+ ide: {
298
+ name: 'cursor',
299
+ session_duration_ms: 3600000,
300
+ active_file_language: 'typescript'
301
+ }
302
+ });
111
303
  ```
112
304
 
113
- ### Full Request with All Options
305
+ ---
306
+
307
+ ### Mobile
308
+
309
+ **For:** iOS apps, Android apps, React Native, Flutter
310
+
311
+ #### Mobile-specific Fields
312
+
313
+ <details>
314
+ <summary><strong>AppObject</strong></summary>
315
+
316
+ | Field | Type | Description |
317
+ |-------|------|-------------|
318
+ | `version` | `string` | Your app version. |
319
+
320
+ </details>
321
+
322
+ #### Example
114
323
 
115
324
  ```typescript
116
325
  const response = await client.getAd({
117
- // Required: conversation messages
326
+ // Common fields
118
327
  messages: [
119
- { role: 'user', content: 'I need help finding a new laptop.' },
120
- { role: 'assistant', content: 'What is your budget?' }
328
+ { role: 'assistant', content: 'I found several Italian restaurants nearby.' },
329
+ { role: 'user', content: 'Which one has the best pasta?' }
121
330
  ],
122
-
123
- // Recommended: session/user tracking (improves ad relevance & revenue)
124
- sessionId: 'session-123',
125
- userId: 'user-456',
126
-
127
- // Optional: user information for targeting
331
+ sessionId: 'session-mobile-001',
332
+ userId: 'user-app-456',
333
+ numAds: 1,
334
+ testAd: true,
335
+ render_context: {
336
+ placements: [
337
+ { placement: 'inline_response' }
338
+ ],
339
+ max_ad_length: 150,
340
+ supports_images: true,
341
+ supports_cta_button: true
342
+ },
343
+
344
+ // Mobile-specific fields
128
345
  user: {
129
- uid: 'user-123', // Unique user identifier
130
- gender: 'male', // 'male' | 'female' | 'other'
131
- age: '25-34', // Age range string
132
- keywords: 'tech,gadgets', // User interest keywords
346
+ email: 'user@example.com',
347
+ subscription_tier: 'premium',
348
+ user_created_at: '2023-06-15T00:00:00Z',
349
+ user_interests: ['food', 'dining', 'travel']
133
350
  },
134
-
135
- // Optional: device information
136
351
  device: {
137
- ip: '1.2.3.4', // User IP address
138
- country: 'US', // ISO country code
139
- ua: 'Mozilla/5.0...', // User agent string
140
- os: 'macOS', // Operating system
141
- ifa: 'device-ad-id', // Advertising identifier
352
+ ip: '198.51.100.23',
353
+ ua: 'MyApp/2.1.0 (iPhone; iOS 17.2)',
354
+ os: 'iOS',
355
+ os_version: '17.2',
356
+ device_model: 'iPhone 15 Pro',
357
+ ifa: '6D92078A-8246-4BA4-AE5B-76104861E7DC',
358
+ timezone: 'America/Los_Angeles',
359
+ locale: 'en-US',
360
+ connection_type: 'wifi'
142
361
  },
143
-
144
- // Optional: ad request settings
145
- excludedTopics: ['politics'], // Topics to exclude
146
- relevancy: 0.8, // Min relevancy threshold (0-1)
147
- numAds: 1, // Number of ads (1-3)
148
- testAd: false, // Return test ad when true
149
-
150
- // Optional: custom fields (open-ended, passed to matching)
151
- interests: ['coding', 'apple', 'software development'],
152
- summary: 'User wants a laptop for software development',
362
+ app: {
363
+ version: '2.1.0'
364
+ }
153
365
  });
154
366
  ```
155
367
 
156
368
  ---
157
369
 
158
- ## Request Parameters
370
+ ### General
371
+
372
+ **For:** Any integration not covered above.
373
+
374
+ #### Example
375
+
376
+ ```typescript
377
+ const response = await client.getAd({
378
+ // Common fields
379
+ messages: [
380
+ { role: 'user', content: 'Where can I buy marathon gear?' }
381
+ ],
382
+ sessionId: 'session-general-001',
383
+ userId: 'user-general-123',
384
+ numAds: 1,
385
+ testAd: true,
386
+ render_context: {
387
+ placements: [
388
+ { placement: 'below_response' }
389
+ ]
390
+ },
159
391
 
160
- | Parameter | Type | Required | Description |
161
- |-----------|------|----------|-------------|
162
- | `messages` | `MessageObject[]` | Yes | Conversation history |
163
- | `sessionId` | `string` | Recommended | Session identifier for tracking |
164
- | `userId` | `string` | Recommended | User identifier for frequency capping |
165
- | `device` | `DeviceObject` | - | Device/location info |
166
- | `user` | `UserObject` | - | User targeting info |
167
- | `excludedTopics` | `string[]` | - | Topics to exclude |
168
- | `relevancy` | `number` | - | Min relevancy (0-1) |
169
- | `numAds` | `number` | - | Number of ads (1-3, default 1) |
170
- | `testAd` | `boolean` | - | Return test ad when true |
392
+ // Optional fields
393
+ device: {
394
+ ip: '192.168.1.1',
395
+ timezone: 'America/New_York',
396
+ locale: 'en-US'
397
+ }
398
+ });
399
+ ```
171
400
 
172
401
  ---
173
402
 
@@ -175,15 +404,17 @@ const response = await client.getAd({
175
404
 
176
405
  ### AdResponse
177
406
 
178
- Returned by `getAd()`.
179
-
180
407
  ```typescript
181
408
  interface AdResponse {
182
- ads: Ad[]; // Array of ads
409
+ ads: Ad[]; // Array of ads (one per placement)
183
410
  numAds: number; // Number of ads returned
184
411
  totalPayout?: number; // Total payout across all ads
185
412
  }
413
+ ```
186
414
 
415
+ ### Ad
416
+
417
+ ```typescript
187
418
  interface Ad {
188
419
  adText: string; // Ad copy text
189
420
  adId: string; // Unique ad identifier
@@ -192,45 +423,32 @@ interface Ad {
192
423
  brandImage?: string; // Brand logo URL
193
424
  url?: string; // Landing page URL
194
425
  favicon?: string; // Favicon URL
195
- impUrl?: string; // Impression tracking URL
196
- clickUrl?: string; // Click-through URL
197
- payout?: number; // Payout amount
426
+ impUrl?: string; // Impression tracking URL (null for testAd)
427
+ clickUrl?: string; // Click-through URL (null for testAd)
428
+ payout?: number; // Payout amount (null for testAd)
198
429
  }
199
430
  ```
200
431
 
201
- ---
202
-
203
- ## Common Types
204
-
205
- ### Message Object
432
+ ### Request Types
206
433
 
207
434
  ```typescript
208
435
  interface MessageObject {
209
436
  role: 'user' | 'assistant';
210
437
  content: string;
211
438
  }
212
- ```
213
-
214
- ### User Object
215
439
 
216
- ```typescript
217
- interface UserObject {
218
- uid?: string; // Unique user ID
219
- gender?: 'male' | 'female' | 'other'; // User gender
220
- age?: string; // Age range (e.g., '25-34')
221
- keywords?: string; // Interest keywords
440
+ interface RenderContextObject {
441
+ placements: PlacementObject[]; // Required, 1-3 items
442
+ max_ad_length?: number;
443
+ supports_markdown?: boolean;
444
+ supports_links?: boolean;
445
+ supports_images?: boolean;
446
+ supports_cta_button?: boolean;
222
447
  }
223
- ```
224
-
225
- ### Device Object
226
448
 
227
- ```typescript
228
- interface DeviceObject {
229
- ip: string; // IP address
230
- country: string; // ISO country code
231
- ua: string; // User agent
232
- os?: string; // Operating system
233
- ifa?: string; // Advertising ID
449
+ interface PlacementObject {
450
+ placement: 'above_response' | 'below_response' | 'inline_response' | 'left_response' | 'right_response';
451
+ placement_id?: string;
234
452
  }
235
453
  ```
236
454
 
@@ -238,41 +456,41 @@ interface DeviceObject {
238
456
 
239
457
  ## Error Handling
240
458
 
241
- The client handles errors gracefully and returns `null` on failure. Errors are logged to the console.
459
+ The client returns `null` on failure. Errors are logged to console.
242
460
 
243
461
  ```typescript
244
- const response = await client.getAd({ messages, sessionId: '...' });
462
+ const response = await client.getAd({
463
+ messages,
464
+ sessionId: 'session-123',
465
+ numAds: 1,
466
+ render_context: { placements: [{ placement: 'below_response' }] }
467
+ });
245
468
 
246
469
  // Returns null on:
247
470
  // - Network errors
248
- // - API errors (4xx, 5xx)
249
- // - No relevant ad (204)
250
- // - Invalid response data
471
+ // - 401: Invalid API key
472
+ // - 422: Validation error (missing sessionId, render_context, or numAds/placements mismatch)
473
+ // - 204: No relevant ad found
474
+ // - 429: Rate limit exceeded
251
475
 
252
476
  if (!response) {
253
477
  // Handle gracefully - don't break the user experience
254
478
  }
255
479
  ```
256
480
 
257
- ## TypeScript
258
-
259
- Full TypeScript support with exported types:
481
+ | Status | Meaning |
482
+ |--------|---------|
483
+ | `200` | Ad(s) matched and returned successfully |
484
+ | `204` | No matching ads found (null response) |
485
+ | `401` | Invalid or missing API key |
486
+ | `422` | Validation error (e.g., missing `sessionId`, `render_context`, or `numAds`/`placements` mismatch) |
487
+ | `429` | Rate limit exceeded |
260
488
 
261
- ```typescript
262
- import { Client, ClientParams } from '@gravity-ai/api';
263
- import type {
264
- AdParams,
265
- Ad,
266
- AdResponse,
267
- MessageObject,
268
- DeviceObject,
269
- UserObject,
270
- } from '@gravity-ai/api';
271
- ```
489
+ ---
272
490
 
273
491
  ## Using with React
274
492
 
275
- For React applications, consider using the companion package `@gravity-ai/react` which provides ready-to-use components with automatic tracking:
493
+ For React applications, use the companion package `@gravity-ai/react`:
276
494
 
277
495
  ```bash
278
496
  npm install @gravity-ai/api @gravity-ai/react
@@ -286,12 +504,15 @@ const client = new Client('your-api-key');
286
504
 
287
505
  function ChatApp() {
288
506
  const [ad, setAd] = useState(null);
289
-
507
+
290
508
  useEffect(() => {
291
- client.getAd({
509
+ client.getAd({
292
510
  messages,
293
511
  sessionId: 'session-123',
294
512
  userId: 'user-456',
513
+ numAds: 1,
514
+ render_context: { placements: [{ placement: 'below_response' }] },
515
+ testAd: true,
295
516
  }).then(res => setAd(res?.ads[0] || null));
296
517
  }, [messages]);
297
518
 
@@ -299,13 +520,47 @@ function ChatApp() {
299
520
  }
300
521
  ```
301
522
 
523
+ ---
524
+
302
525
  ## Best Practices
303
526
 
304
- 1. **Always include `sessionId` and `userId`** These directly impact publisher revenue through better frequency capping and ad relevance.
527
+ 1. **`sessionId` and `render_context` are required** Enable frequency capping and ad placement tracking.
528
+
529
+ 2. **`numAds` must match `placements` length** — Request 2 ads? Provide 2 placement objects.
530
+
531
+ 3. **Include `userId` when available** — Improves targeting and increases CPMs.
305
532
 
306
- 2. **Handle null responses gracefully** — Don't break the user experience when no ad is available.
533
+ 4. **Use `testAd: true` during development** — Prevents generating real impressions or clicks.
307
534
 
308
- 3. **Fire impression url** — Use the `impUrl` when the ad becomes visible to properly track impressions.
535
+ 5. **Handle null responses gracefully** — Don't break the UX when no ad is available.
536
+
537
+ 6. **Fire `impUrl` when the ad is visible** — Required for proper impression tracking.
538
+
539
+ 7. **Include `device.ip` for geo-targeting** — Enables location-based ads and higher CPMs.
540
+
541
+ 8. **Include `user.email` when available** — Enables identity matching for significantly higher CPMs.
542
+
543
+ ---
544
+
545
+ ## TypeScript
546
+
547
+ Full TypeScript support with exported types:
548
+
549
+ ```typescript
550
+ import { Client } from '@gravity-ai/api';
551
+ import type {
552
+ AdParams,
553
+ Ad,
554
+ AdResponse,
555
+ MessageObject,
556
+ RenderContextObject,
557
+ PlacementObject,
558
+ DeviceObject,
559
+ UserObject,
560
+ } from '@gravity-ai/api';
561
+ ```
562
+
563
+ ---
309
564
 
310
565
  ## License
311
566
 
package/dist/index.d.mts CHANGED
@@ -8,6 +8,58 @@ type Role = 'user' | 'assistant';
8
8
  * @description Used for demographic targeting of advertisements
9
9
  */
10
10
  type Gender = 'male' | 'female' | 'other';
11
+ /**
12
+ * Placement positions for ad rendering
13
+ * @description Specifies where ads should appear relative to the AI response
14
+ */
15
+ type Placement = 'above_response' | 'below_response' | 'inline_response' | 'left_response' | 'right_response';
16
+ /**
17
+ * Individual ad placement specification
18
+ * @description Defines a single ad slot with its position and optional tracking ID
19
+ * @example
20
+ * ```typescript
21
+ * const placement: PlacementObject = {
22
+ * placement: 'below_response',
23
+ * placement_id: 'sidebar-1'
24
+ * };
25
+ * ```
26
+ */
27
+ interface PlacementObject {
28
+ /** Position where the ad should appear (required) */
29
+ placement: Placement;
30
+ /** Optional tracking ID for this specific ad slot */
31
+ placement_id?: string;
32
+ }
33
+ /**
34
+ * Describes how your app will display the ad
35
+ * @description Contains placement array and rendering capabilities for ad customization
36
+ * @example
37
+ * ```typescript
38
+ * const renderContext: RenderContextObject = {
39
+ * placements: [
40
+ * { placement: 'below_response' },
41
+ * { placement: 'right_response', placement_id: 'sidebar' }
42
+ * ],
43
+ * max_ad_length: 200
44
+ * };
45
+ * ```
46
+ */
47
+ interface RenderContextObject {
48
+ /** Where you plan to show the ad(s). Array of 1-3 placements, must match numAds. */
49
+ placements: PlacementObject[];
50
+ /** Character limit you can display, so we don't send copy that gets truncated */
51
+ max_ad_length?: number;
52
+ /** Whether you can render markdown-formatted text */
53
+ supports_markdown?: boolean;
54
+ /** Whether you can render clickable links */
55
+ supports_links?: boolean;
56
+ /** Whether you can display images (brand logos, product images) */
57
+ supports_images?: boolean;
58
+ /** Whether you can render CTA buttons */
59
+ supports_cta_button?: boolean;
60
+ /** Additional render context properties (supports JSON objects) */
61
+ [key: string]: PlacementObject[] | string | number | boolean | object | null | undefined;
62
+ }
11
63
  /**
12
64
  * Represents a single message in a conversation
13
65
  * @description Used to provide conversation context for contextual ad targeting
@@ -39,16 +91,18 @@ interface MessageObject {
39
91
  * ```
40
92
  */
41
93
  interface DeviceObject {
42
- /** User's IP address for geo-targeting */
94
+ /** User's IP address for geo-targeting (required) */
43
95
  ip: string;
96
+ /** Browser user-agent string (optional for non-web publishers like IDEs, CLIs, mobile apps) */
97
+ ua?: string;
44
98
  /** ISO 3166-1 alpha-2 country code (e.g., 'US', 'GB', 'DE') */
45
- country: string;
46
- /** User agent string from the browser */
47
- ua: string;
99
+ country?: string;
48
100
  /** Operating system name (e.g., 'macOS', 'Windows', 'iOS', 'Android') */
49
101
  os?: string;
50
102
  /** Identifier for Advertisers (mobile advertising ID) */
51
103
  ifa?: string;
104
+ /** Additional device properties (timezone, locale, browser, device_type, screen dimensions, etc.) */
105
+ [key: string]: string | number | boolean | undefined;
52
106
  }
53
107
  /**
54
108
  * User profile information for ad targeting
@@ -64,7 +118,7 @@ interface DeviceObject {
64
118
  * ```
65
119
  */
66
120
  interface UserObject {
67
- /** Unique user identifier for frequency capping and tracking */
121
+ /** Unique user identifier for improving ad relevance */
68
122
  uid?: string;
69
123
  /** User's gender for demographic targeting */
70
124
  gender?: Gender;
@@ -72,6 +126,8 @@ interface UserObject {
72
126
  age?: string;
73
127
  /** Comma-separated keywords representing user interests */
74
128
  keywords?: string;
129
+ /** Additional user properties (email, subscription_tier, user_interests, company_size, etc.) */
130
+ [key: string]: string | string[] | number | boolean | Gender | undefined;
75
131
  }
76
132
  /**
77
133
  * Parameters for requesting an advertisement
@@ -84,7 +140,12 @@ interface UserObject {
84
140
  * { role: 'assistant', content: 'What is your budget?' }
85
141
  * ],
86
142
  * sessionId: 'session-123',
143
+ * numAds: 1,
144
+ * render_context: {
145
+ * placements: [{ placement: 'below_response' }]
146
+ * },
87
147
  * userId: 'user-456',
148
+ * testAd: true,
88
149
  * user: { gender: 'male', age: '25-34' },
89
150
  * device: { ip: '1.2.3.4', country: 'US', ua: 'Mozilla/5.0...' },
90
151
  * excludedTopics: ['politics'],
@@ -95,8 +156,12 @@ interface UserObject {
95
156
  interface AdParams {
96
157
  /** Array of conversation messages for contextual targeting (required) */
97
158
  messages: MessageObject[];
98
- /** Session identifier for tracking user sessions */
99
- sessionId?: string;
159
+ /** Session identifier for ad relevance (required) */
160
+ sessionId: string;
161
+ /** Render context with placements array (required). Length of placements must match numAds. */
162
+ render_context: RenderContextObject;
163
+ /** Number of ads to return (1-3). Must match render_context.placements length. */
164
+ numAds?: number;
100
165
  /** Unique user identifier */
101
166
  userId?: string;
102
167
  /** Device and location information */
@@ -107,8 +172,6 @@ interface AdParams {
107
172
  excludedTopics?: string[];
108
173
  /** Minimum relevancy score threshold (0-1). Higher = more relevant but fewer ads */
109
174
  relevancy?: number | null;
110
- /** Number of ads to return (1-3, default 1) */
111
- numAds?: number;
112
175
  /** Returns a test ad when true */
113
176
  testAd?: boolean;
114
177
  /**
@@ -185,8 +248,12 @@ interface ApiErrorResponse {
185
248
  * Base fields shared across all ad requests.
186
249
  */
187
250
  interface AdRequestBase {
188
- /** Session identifier for tracking user sessions */
189
- sessionId?: string;
251
+ /** Session identifier for ad relevance (required) */
252
+ sessionId: string;
253
+ /** Render context with placements array (required). Length of placements must match numAds. */
254
+ render_context: RenderContextObject;
255
+ /** Number of ads to return (1-3). Must match render_context.placements length. */
256
+ numAds?: number;
190
257
  /** Unique user identifier */
191
258
  userId?: string;
192
259
  /** Device and location information */
@@ -197,8 +264,6 @@ interface AdRequestBase {
197
264
  excludedTopics?: string[];
198
265
  /** Minimum relevancy score threshold (0-1) */
199
266
  relevancy?: number | null;
200
- /** Number of ads to return (1-3, default 1) */
201
- numAds?: number;
202
267
  /** Returns a test ad when true */
203
268
  testAd?: boolean;
204
269
  /** Additional custom fields */
@@ -221,13 +286,16 @@ interface NonContextualAdParams extends AdRequestBase {
221
286
  /**
222
287
  * POST /api/v1/bid
223
288
  * @description Two-phase bid request. Returns bid price and bidId.
224
- * @note Does NOT extend AdRequestBaseV1 - has its own field set.
225
289
  */
226
290
  interface BidParams {
227
291
  /** Array of conversation messages (required) */
228
292
  messages: MessageObject[];
229
- /** Session identifier */
230
- sessionId?: string;
293
+ /** Session identifier for ad relevance (required) */
294
+ sessionId: string;
295
+ /** Render context with placements array (required). Length of placements must match numAds. */
296
+ render_context: RenderContextObject;
297
+ /** Number of ads to return (1-3). Must match render_context.placements length. */
298
+ numAds?: number;
231
299
  /** Unique user identifier */
232
300
  userId?: string;
233
301
  /** Chat/conversation identifier */
@@ -304,6 +372,10 @@ interface ClientParams {
304
372
  * { role: 'user', content: 'What laptop should I buy?' }
305
373
  * ],
306
374
  * sessionId: 'session-123',
375
+ * numAds: 1,
376
+ * render_context: {
377
+ * placements: [{ placement: 'below_response' }]
378
+ * }
307
379
  * });
308
380
  *
309
381
  * if (response) {
@@ -370,6 +442,10 @@ declare class Client {
370
442
  * { role: 'assistant', content: 'What is your budget range?' }
371
443
  * ],
372
444
  * sessionId: 'session-123',
445
+ * numAds: 1,
446
+ * render_context: {
447
+ * placements: [{ placement: 'below_response' }]
448
+ * },
373
449
  * userId: 'user-456',
374
450
  * });
375
451
  *
@@ -384,6 +460,11 @@ declare class Client {
384
460
  * const response = await client.getAd({
385
461
  * messages: [...],
386
462
  * sessionId: 'session-123',
463
+ * numAds: 1,
464
+ * render_context: {
465
+ * placements: [{ placement: 'below_response' }],
466
+ * max_ad_length: 200
467
+ * },
387
468
  * userId: 'user-456',
388
469
  * user: {
389
470
  * uid: 'user-123',
@@ -402,7 +483,12 @@ declare class Client {
402
483
  *
403
484
  * @example Handling the response
404
485
  * ```typescript
405
- * const response = await client.getAd({ messages, sessionId: '...' });
486
+ * const response = await client.getAd({
487
+ * messages,
488
+ * sessionId: '...',
489
+ * numAds: 1,
490
+ * render_context: { placements: [{ placement: 'below_response' }] }
491
+ * });
406
492
  *
407
493
  * if (response) {
408
494
  * const ad = response.ads[0];
@@ -433,10 +519,10 @@ declare class Client {
433
519
  * @description Fetches ads without context matching. Useful for brand awareness placements.
434
520
  * Returns null if no ad is available or on error.
435
521
  *
436
- * @param params - Optional request parameters
522
+ * @param params - Request parameters (sessionId required)
437
523
  * @returns Promise resolving to AdResponse or null if no ad available
438
524
  */
439
- nonContextualAd(params?: NonContextualAdParams): Promise<AdResponse | null>;
525
+ nonContextualAd(params: NonContextualAdParams): Promise<AdResponse | null>;
440
526
  /**
441
527
  * Request a bid price for contextual ad placement
442
528
  *
@@ -472,4 +558,4 @@ declare class Client {
472
558
  private handleError;
473
559
  }
474
560
 
475
- export { type Ad, type AdParams, type AdRequestBase, type AdResponse, type ApiErrorResponse, type BidParams, type BidResponse, Client, type ClientParams, type DeviceObject, type Gender, type MessageObject, type NonContextualAdParams, type RenderParams, type Role, type SummaryAdParams, type UserObject };
561
+ export { type Ad, type AdParams, type AdRequestBase, type AdResponse, type ApiErrorResponse, type BidParams, type BidResponse, Client, type ClientParams, type DeviceObject, type Gender, type MessageObject, type NonContextualAdParams, type Placement, type PlacementObject, type RenderContextObject, type RenderParams, type Role, type SummaryAdParams, type UserObject };
package/dist/index.d.ts CHANGED
@@ -8,6 +8,58 @@ type Role = 'user' | 'assistant';
8
8
  * @description Used for demographic targeting of advertisements
9
9
  */
10
10
  type Gender = 'male' | 'female' | 'other';
11
+ /**
12
+ * Placement positions for ad rendering
13
+ * @description Specifies where ads should appear relative to the AI response
14
+ */
15
+ type Placement = 'above_response' | 'below_response' | 'inline_response' | 'left_response' | 'right_response';
16
+ /**
17
+ * Individual ad placement specification
18
+ * @description Defines a single ad slot with its position and optional tracking ID
19
+ * @example
20
+ * ```typescript
21
+ * const placement: PlacementObject = {
22
+ * placement: 'below_response',
23
+ * placement_id: 'sidebar-1'
24
+ * };
25
+ * ```
26
+ */
27
+ interface PlacementObject {
28
+ /** Position where the ad should appear (required) */
29
+ placement: Placement;
30
+ /** Optional tracking ID for this specific ad slot */
31
+ placement_id?: string;
32
+ }
33
+ /**
34
+ * Describes how your app will display the ad
35
+ * @description Contains placement array and rendering capabilities for ad customization
36
+ * @example
37
+ * ```typescript
38
+ * const renderContext: RenderContextObject = {
39
+ * placements: [
40
+ * { placement: 'below_response' },
41
+ * { placement: 'right_response', placement_id: 'sidebar' }
42
+ * ],
43
+ * max_ad_length: 200
44
+ * };
45
+ * ```
46
+ */
47
+ interface RenderContextObject {
48
+ /** Where you plan to show the ad(s). Array of 1-3 placements, must match numAds. */
49
+ placements: PlacementObject[];
50
+ /** Character limit you can display, so we don't send copy that gets truncated */
51
+ max_ad_length?: number;
52
+ /** Whether you can render markdown-formatted text */
53
+ supports_markdown?: boolean;
54
+ /** Whether you can render clickable links */
55
+ supports_links?: boolean;
56
+ /** Whether you can display images (brand logos, product images) */
57
+ supports_images?: boolean;
58
+ /** Whether you can render CTA buttons */
59
+ supports_cta_button?: boolean;
60
+ /** Additional render context properties (supports JSON objects) */
61
+ [key: string]: PlacementObject[] | string | number | boolean | object | null | undefined;
62
+ }
11
63
  /**
12
64
  * Represents a single message in a conversation
13
65
  * @description Used to provide conversation context for contextual ad targeting
@@ -39,16 +91,18 @@ interface MessageObject {
39
91
  * ```
40
92
  */
41
93
  interface DeviceObject {
42
- /** User's IP address for geo-targeting */
94
+ /** User's IP address for geo-targeting (required) */
43
95
  ip: string;
96
+ /** Browser user-agent string (optional for non-web publishers like IDEs, CLIs, mobile apps) */
97
+ ua?: string;
44
98
  /** ISO 3166-1 alpha-2 country code (e.g., 'US', 'GB', 'DE') */
45
- country: string;
46
- /** User agent string from the browser */
47
- ua: string;
99
+ country?: string;
48
100
  /** Operating system name (e.g., 'macOS', 'Windows', 'iOS', 'Android') */
49
101
  os?: string;
50
102
  /** Identifier for Advertisers (mobile advertising ID) */
51
103
  ifa?: string;
104
+ /** Additional device properties (timezone, locale, browser, device_type, screen dimensions, etc.) */
105
+ [key: string]: string | number | boolean | undefined;
52
106
  }
53
107
  /**
54
108
  * User profile information for ad targeting
@@ -64,7 +118,7 @@ interface DeviceObject {
64
118
  * ```
65
119
  */
66
120
  interface UserObject {
67
- /** Unique user identifier for frequency capping and tracking */
121
+ /** Unique user identifier for improving ad relevance */
68
122
  uid?: string;
69
123
  /** User's gender for demographic targeting */
70
124
  gender?: Gender;
@@ -72,6 +126,8 @@ interface UserObject {
72
126
  age?: string;
73
127
  /** Comma-separated keywords representing user interests */
74
128
  keywords?: string;
129
+ /** Additional user properties (email, subscription_tier, user_interests, company_size, etc.) */
130
+ [key: string]: string | string[] | number | boolean | Gender | undefined;
75
131
  }
76
132
  /**
77
133
  * Parameters for requesting an advertisement
@@ -84,7 +140,12 @@ interface UserObject {
84
140
  * { role: 'assistant', content: 'What is your budget?' }
85
141
  * ],
86
142
  * sessionId: 'session-123',
143
+ * numAds: 1,
144
+ * render_context: {
145
+ * placements: [{ placement: 'below_response' }]
146
+ * },
87
147
  * userId: 'user-456',
148
+ * testAd: true,
88
149
  * user: { gender: 'male', age: '25-34' },
89
150
  * device: { ip: '1.2.3.4', country: 'US', ua: 'Mozilla/5.0...' },
90
151
  * excludedTopics: ['politics'],
@@ -95,8 +156,12 @@ interface UserObject {
95
156
  interface AdParams {
96
157
  /** Array of conversation messages for contextual targeting (required) */
97
158
  messages: MessageObject[];
98
- /** Session identifier for tracking user sessions */
99
- sessionId?: string;
159
+ /** Session identifier for ad relevance (required) */
160
+ sessionId: string;
161
+ /** Render context with placements array (required). Length of placements must match numAds. */
162
+ render_context: RenderContextObject;
163
+ /** Number of ads to return (1-3). Must match render_context.placements length. */
164
+ numAds?: number;
100
165
  /** Unique user identifier */
101
166
  userId?: string;
102
167
  /** Device and location information */
@@ -107,8 +172,6 @@ interface AdParams {
107
172
  excludedTopics?: string[];
108
173
  /** Minimum relevancy score threshold (0-1). Higher = more relevant but fewer ads */
109
174
  relevancy?: number | null;
110
- /** Number of ads to return (1-3, default 1) */
111
- numAds?: number;
112
175
  /** Returns a test ad when true */
113
176
  testAd?: boolean;
114
177
  /**
@@ -185,8 +248,12 @@ interface ApiErrorResponse {
185
248
  * Base fields shared across all ad requests.
186
249
  */
187
250
  interface AdRequestBase {
188
- /** Session identifier for tracking user sessions */
189
- sessionId?: string;
251
+ /** Session identifier for ad relevance (required) */
252
+ sessionId: string;
253
+ /** Render context with placements array (required). Length of placements must match numAds. */
254
+ render_context: RenderContextObject;
255
+ /** Number of ads to return (1-3). Must match render_context.placements length. */
256
+ numAds?: number;
190
257
  /** Unique user identifier */
191
258
  userId?: string;
192
259
  /** Device and location information */
@@ -197,8 +264,6 @@ interface AdRequestBase {
197
264
  excludedTopics?: string[];
198
265
  /** Minimum relevancy score threshold (0-1) */
199
266
  relevancy?: number | null;
200
- /** Number of ads to return (1-3, default 1) */
201
- numAds?: number;
202
267
  /** Returns a test ad when true */
203
268
  testAd?: boolean;
204
269
  /** Additional custom fields */
@@ -221,13 +286,16 @@ interface NonContextualAdParams extends AdRequestBase {
221
286
  /**
222
287
  * POST /api/v1/bid
223
288
  * @description Two-phase bid request. Returns bid price and bidId.
224
- * @note Does NOT extend AdRequestBaseV1 - has its own field set.
225
289
  */
226
290
  interface BidParams {
227
291
  /** Array of conversation messages (required) */
228
292
  messages: MessageObject[];
229
- /** Session identifier */
230
- sessionId?: string;
293
+ /** Session identifier for ad relevance (required) */
294
+ sessionId: string;
295
+ /** Render context with placements array (required). Length of placements must match numAds. */
296
+ render_context: RenderContextObject;
297
+ /** Number of ads to return (1-3). Must match render_context.placements length. */
298
+ numAds?: number;
231
299
  /** Unique user identifier */
232
300
  userId?: string;
233
301
  /** Chat/conversation identifier */
@@ -304,6 +372,10 @@ interface ClientParams {
304
372
  * { role: 'user', content: 'What laptop should I buy?' }
305
373
  * ],
306
374
  * sessionId: 'session-123',
375
+ * numAds: 1,
376
+ * render_context: {
377
+ * placements: [{ placement: 'below_response' }]
378
+ * }
307
379
  * });
308
380
  *
309
381
  * if (response) {
@@ -370,6 +442,10 @@ declare class Client {
370
442
  * { role: 'assistant', content: 'What is your budget range?' }
371
443
  * ],
372
444
  * sessionId: 'session-123',
445
+ * numAds: 1,
446
+ * render_context: {
447
+ * placements: [{ placement: 'below_response' }]
448
+ * },
373
449
  * userId: 'user-456',
374
450
  * });
375
451
  *
@@ -384,6 +460,11 @@ declare class Client {
384
460
  * const response = await client.getAd({
385
461
  * messages: [...],
386
462
  * sessionId: 'session-123',
463
+ * numAds: 1,
464
+ * render_context: {
465
+ * placements: [{ placement: 'below_response' }],
466
+ * max_ad_length: 200
467
+ * },
387
468
  * userId: 'user-456',
388
469
  * user: {
389
470
  * uid: 'user-123',
@@ -402,7 +483,12 @@ declare class Client {
402
483
  *
403
484
  * @example Handling the response
404
485
  * ```typescript
405
- * const response = await client.getAd({ messages, sessionId: '...' });
486
+ * const response = await client.getAd({
487
+ * messages,
488
+ * sessionId: '...',
489
+ * numAds: 1,
490
+ * render_context: { placements: [{ placement: 'below_response' }] }
491
+ * });
406
492
  *
407
493
  * if (response) {
408
494
  * const ad = response.ads[0];
@@ -433,10 +519,10 @@ declare class Client {
433
519
  * @description Fetches ads without context matching. Useful for brand awareness placements.
434
520
  * Returns null if no ad is available or on error.
435
521
  *
436
- * @param params - Optional request parameters
522
+ * @param params - Request parameters (sessionId required)
437
523
  * @returns Promise resolving to AdResponse or null if no ad available
438
524
  */
439
- nonContextualAd(params?: NonContextualAdParams): Promise<AdResponse | null>;
525
+ nonContextualAd(params: NonContextualAdParams): Promise<AdResponse | null>;
440
526
  /**
441
527
  * Request a bid price for contextual ad placement
442
528
  *
@@ -472,4 +558,4 @@ declare class Client {
472
558
  private handleError;
473
559
  }
474
560
 
475
- export { type Ad, type AdParams, type AdRequestBase, type AdResponse, type ApiErrorResponse, type BidParams, type BidResponse, Client, type ClientParams, type DeviceObject, type Gender, type MessageObject, type NonContextualAdParams, type RenderParams, type Role, type SummaryAdParams, type UserObject };
561
+ export { type Ad, type AdParams, type AdRequestBase, type AdResponse, type ApiErrorResponse, type BidParams, type BidResponse, Client, type ClientParams, type DeviceObject, type Gender, type MessageObject, type NonContextualAdParams, type Placement, type PlacementObject, type RenderContextObject, type RenderParams, type Role, type SummaryAdParams, type UserObject };
package/dist/index.js CHANGED
@@ -90,6 +90,10 @@ var Client = class {
90
90
  * { role: 'assistant', content: 'What is your budget range?' }
91
91
  * ],
92
92
  * sessionId: 'session-123',
93
+ * numAds: 1,
94
+ * render_context: {
95
+ * placements: [{ placement: 'below_response' }]
96
+ * },
93
97
  * userId: 'user-456',
94
98
  * });
95
99
  *
@@ -104,6 +108,11 @@ var Client = class {
104
108
  * const response = await client.getAd({
105
109
  * messages: [...],
106
110
  * sessionId: 'session-123',
111
+ * numAds: 1,
112
+ * render_context: {
113
+ * placements: [{ placement: 'below_response' }],
114
+ * max_ad_length: 200
115
+ * },
107
116
  * userId: 'user-456',
108
117
  * user: {
109
118
  * uid: 'user-123',
@@ -122,7 +131,12 @@ var Client = class {
122
131
  *
123
132
  * @example Handling the response
124
133
  * ```typescript
125
- * const response = await client.getAd({ messages, sessionId: '...' });
134
+ * const response = await client.getAd({
135
+ * messages,
136
+ * sessionId: '...',
137
+ * numAds: 1,
138
+ * render_context: { placements: [{ placement: 'below_response' }] }
139
+ * });
126
140
  *
127
141
  * if (response) {
128
142
  * const ad = response.ads[0];
@@ -194,10 +208,10 @@ var Client = class {
194
208
  * @description Fetches ads without context matching. Useful for brand awareness placements.
195
209
  * Returns null if no ad is available or on error.
196
210
  *
197
- * @param params - Optional request parameters
211
+ * @param params - Request parameters (sessionId required)
198
212
  * @returns Promise resolving to AdResponse or null if no ad available
199
213
  */
200
- async nonContextualAd(params = {}) {
214
+ async nonContextualAd(params) {
201
215
  try {
202
216
  const body = {
203
217
  ...params,
package/dist/index.mjs CHANGED
@@ -54,6 +54,10 @@ var Client = class {
54
54
  * { role: 'assistant', content: 'What is your budget range?' }
55
55
  * ],
56
56
  * sessionId: 'session-123',
57
+ * numAds: 1,
58
+ * render_context: {
59
+ * placements: [{ placement: 'below_response' }]
60
+ * },
57
61
  * userId: 'user-456',
58
62
  * });
59
63
  *
@@ -68,6 +72,11 @@ var Client = class {
68
72
  * const response = await client.getAd({
69
73
  * messages: [...],
70
74
  * sessionId: 'session-123',
75
+ * numAds: 1,
76
+ * render_context: {
77
+ * placements: [{ placement: 'below_response' }],
78
+ * max_ad_length: 200
79
+ * },
71
80
  * userId: 'user-456',
72
81
  * user: {
73
82
  * uid: 'user-123',
@@ -86,7 +95,12 @@ var Client = class {
86
95
  *
87
96
  * @example Handling the response
88
97
  * ```typescript
89
- * const response = await client.getAd({ messages, sessionId: '...' });
98
+ * const response = await client.getAd({
99
+ * messages,
100
+ * sessionId: '...',
101
+ * numAds: 1,
102
+ * render_context: { placements: [{ placement: 'below_response' }] }
103
+ * });
90
104
  *
91
105
  * if (response) {
92
106
  * const ad = response.ads[0];
@@ -158,10 +172,10 @@ var Client = class {
158
172
  * @description Fetches ads without context matching. Useful for brand awareness placements.
159
173
  * Returns null if no ad is available or on error.
160
174
  *
161
- * @param params - Optional request parameters
175
+ * @param params - Request parameters (sessionId required)
162
176
  * @returns Promise resolving to AdResponse or null if no ad available
163
177
  */
164
- async nonContextualAd(params = {}) {
178
+ async nonContextualAd(params) {
165
179
  try {
166
180
  const body = {
167
181
  ...params,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ai/api",
3
- "version": "1.0.2",
3
+ "version": "1.1.0",
4
4
  "description": "Gravity JS SDK for retrieving targeted advertisements",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",