@gravity-ai/api 1.1.1 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -27,38 +27,8 @@ type Placement = 'above_response' | 'below_response' | 'inline_response' | 'left
27
27
  interface PlacementObject {
28
28
  /** Position where the ad should appear (required) */
29
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;
30
+ /** Tracking ID for this specific ad slot (required) */
31
+ placement_id: string;
62
32
  }
63
33
  /**
64
34
  * Represents a single message in a conversation
@@ -140,14 +110,10 @@ interface UserObject {
140
110
  * { role: 'assistant', content: 'What is your budget?' }
141
111
  * ],
142
112
  * sessionId: 'session-123',
143
- * numAds: 1,
144
- * render_context: {
145
- * placements: [{ placement: 'below_response' }]
146
- * },
113
+ * placements: [{ placement: 'below_response' }],
147
114
  * userId: 'user-456',
148
- * testAd: true,
149
115
  * user: { gender: 'male', age: '25-34' },
150
- * device: { ip: '1.2.3.4', country: 'US', ua: 'Mozilla/5.0...' },
116
+ * device: { ip: '1.2.3.4', country: 'US' },
151
117
  * excludedTopics: ['politics'],
152
118
  * relevancy: 0.5
153
119
  * };
@@ -158,10 +124,8 @@ interface AdParams {
158
124
  messages: MessageObject[];
159
125
  /** Session identifier for ad relevance (required) */
160
126
  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;
127
+ /** Ad placement specifications (required). Array of 1-10 placements. */
128
+ placements: PlacementObject[];
165
129
  /** Unique user identifier */
166
130
  userId?: string;
167
131
  /** Device and location information */
@@ -172,7 +136,7 @@ interface AdParams {
172
136
  excludedTopics?: string[];
173
137
  /** Minimum relevancy score threshold (0-1). Higher = more relevant but fewer ads */
174
138
  relevancy?: number | null;
175
- /** Returns a test ad when true */
139
+ /** Returns a test ad when true (no billing, for integration testing) */
176
140
  testAd?: boolean;
177
141
  /**
178
142
  * Additional custom fields for publisher-specific targeting
@@ -182,55 +146,37 @@ interface AdParams {
182
146
  }
183
147
  /**
184
148
  * Single ad object in responses.
185
- * @description Contains all ad creative and tracking data.
149
+ * @description Contains ad creative and tracking data. Returned as a flat array from v1 API.
150
+ * @example
151
+ * ```typescript
152
+ * const ad: Ad = {
153
+ * adText: 'Check out our amazing laptops!',
154
+ * title: 'Dell XPS 15',
155
+ * cta: 'Shop Now',
156
+ * brandName: 'Dell',
157
+ * url: 'https://dell.com/xps',
158
+ * impUrl: 'https://tracking.example.com/imp?id=123',
159
+ * clickUrl: 'https://tracking.example.com/click?id=123'
160
+ * };
161
+ * ```
186
162
  */
187
163
  interface Ad {
188
164
  /** The advertisement copy text */
189
165
  adText: string;
190
- /** Unique ad identifier */
191
- adId: string;
192
166
  /** Ad title */
193
167
  title?: string;
168
+ /** Call-to-action text (e.g., 'Learn More', 'Shop Now') */
169
+ cta?: string;
194
170
  /** Brand/advertiser name */
195
171
  brandName?: string;
196
- /** Brand logo image URL */
197
- brandImage?: string;
198
172
  /** Landing page URL */
199
173
  url?: string;
200
174
  /** Favicon URL */
201
175
  favicon?: string;
202
- /** Impression tracking URL */
176
+ /** Impression tracking URL - fire this when ad is displayed */
203
177
  impUrl?: string;
204
- /** Click-through tracking URL */
178
+ /** Click-through tracking URL - use this as href for ad clicks */
205
179
  clickUrl?: string;
206
- /** Payout amount in USD */
207
- payout?: number;
208
- }
209
- /**
210
- * Response from the Gravity API containing ad data
211
- * @description Returned by getAd() when a relevant advertisement is found
212
- * @example
213
- * ```typescript
214
- * const response: AdResponse = {
215
- * ads: [{
216
- * adText: 'Check out our amazing laptops!',
217
- * adId: 'ad-123',
218
- * impUrl: 'https://tracking.example.com/imp?id=123',
219
- * clickUrl: 'https://example.com/laptops',
220
- * payout: 0.50
221
- * }],
222
- * numAds: 1,
223
- * totalPayout: 0.50
224
- * };
225
- * ```
226
- */
227
- interface AdResponse {
228
- /** Array of ad objects */
229
- ads: Ad[];
230
- /** Number of ads returned */
231
- numAds: number;
232
- /** Total payout across all ads */
233
- totalPayout?: number;
234
180
  }
235
181
  /**
236
182
  * Error response structure from the Gravity API
@@ -244,85 +190,6 @@ interface ApiErrorResponse {
244
190
  /** HTTP status code */
245
191
  statusCode?: number;
246
192
  }
247
- /**
248
- * Base fields shared across all ad requests.
249
- */
250
- interface AdRequestBase {
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;
257
- /** Unique user identifier */
258
- userId?: string;
259
- /** Device and location information */
260
- device?: DeviceObject;
261
- /** User demographic and interest data */
262
- user?: UserObject;
263
- /** Topics to exclude from ad matching */
264
- excludedTopics?: string[];
265
- /** Minimum relevancy score threshold (0-1) */
266
- relevancy?: number | null;
267
- /** Returns a test ad when true */
268
- testAd?: boolean;
269
- /** Additional custom fields */
270
- [key: string]: unknown;
271
- }
272
- /**
273
- * POST /api/v1/ad/summary
274
- * @description Requires queryString for summary-based targeting.
275
- */
276
- interface SummaryAdParams extends AdRequestBase {
277
- /** Search/summary query string (required) */
278
- queryString: string;
279
- }
280
- /**
281
- * POST /api/v1/ad/non-contextual
282
- * @description No context required - returns ads without context matching.
283
- */
284
- interface NonContextualAdParams extends AdRequestBase {
285
- }
286
- /**
287
- * POST /api/v1/bid
288
- * @description Two-phase bid request. Returns bid price and bidId.
289
- */
290
- interface BidParams {
291
- /** Array of conversation messages (required) */
292
- messages: MessageObject[];
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;
299
- /** Unique user identifier */
300
- userId?: string;
301
- /** Chat/conversation identifier */
302
- chatId?: string;
303
- /** Device and location information */
304
- device?: DeviceObject;
305
- }
306
- /**
307
- * POST /api/v1/render
308
- * @description Two-phase render request using cached bid context.
309
- */
310
- interface RenderParams {
311
- /** Bid identifier from the bid phase (required) */
312
- bidId: string;
313
- /** Realized price to charge (required) */
314
- realizedPrice: number;
315
- }
316
- /**
317
- * Bid response.
318
- * @description Returned by the bid endpoint.
319
- */
320
- interface BidResponse {
321
- /** Clearing price (CPM) */
322
- bid: number;
323
- /** Bid identifier for the render phase */
324
- bidId: string;
325
- }
326
193
 
327
194
  /**
328
195
  * Configuration options for the Gravity API Client
@@ -367,20 +234,16 @@ interface ClientParams {
367
234
  *
368
235
  * const client = new Client('your-api-key');
369
236
  *
370
- * const response = await client.getAd({
237
+ * const ads = await client.getAd({
371
238
  * messages: [
372
239
  * { role: 'user', content: 'What laptop should I buy?' }
373
240
  * ],
374
241
  * sessionId: 'session-123',
375
- * numAds: 1,
376
- * render_context: {
377
- * placements: [{ placement: 'below_response' }]
378
- * }
242
+ * placements: [{ placement: 'below_response' }]
379
243
  * });
380
244
  *
381
- * if (response) {
382
- * const ad = response.ads[0];
383
- * console.log(ad.adText);
245
+ * if (ads) {
246
+ * console.log(ads[0].adText);
384
247
  * }
385
248
  * ```
386
249
  *
@@ -426,124 +289,64 @@ declare class Client {
426
289
  */
427
290
  constructor(apiKey: string, params?: ClientParams);
428
291
  /**
429
- * Request a contextually relevant advertisement
292
+ * Request contextually relevant advertisements
430
293
  *
431
294
  * @description Fetches ads based on the provided conversation context and targeting parameters.
432
295
  * Returns `null` if no relevant ad is available or if an error occurs.
433
296
  *
434
297
  * @param params - Ad request parameters including conversation messages
435
- * @returns Promise resolving to AdResponse or null if no ad available
298
+ * @returns Promise resolving to Ad array or null if no ads available
436
299
  *
437
300
  * @example Basic request
438
301
  * ```typescript
439
- * const response = await client.getAd({
302
+ * const ads = await client.getAd({
440
303
  * messages: [
441
304
  * { role: 'user', content: 'I need a new laptop for programming' },
442
305
  * { role: 'assistant', content: 'What is your budget range?' }
443
306
  * ],
444
307
  * sessionId: 'session-123',
445
- * numAds: 1,
446
- * render_context: {
447
- * placements: [{ placement: 'below_response' }]
448
- * },
449
- * userId: 'user-456',
308
+ * placements: [{ placement: 'below_response' }]
450
309
  * });
451
310
  *
452
- * if (response) {
453
- * const ad = response.ads[0];
454
- * console.log(ad.adText);
311
+ * if (ads) {
312
+ * console.log(ads[0].adText);
455
313
  * }
456
314
  * ```
457
315
  *
458
- * @example Full request with targeting
316
+ * @example With targeting options
459
317
  * ```typescript
460
- * const response = await client.getAd({
318
+ * const ads = await client.getAd({
461
319
  * messages: [...],
462
320
  * sessionId: 'session-123',
463
- * numAds: 1,
464
- * render_context: {
465
- * placements: [{ placement: 'below_response' }],
466
- * max_ad_length: 200
467
- * },
321
+ * placements: [{ placement: 'below_response' }],
468
322
  * userId: 'user-456',
469
- * user: {
470
- * uid: 'user-123',
471
- * gender: 'male',
472
- * age: '25-34'
473
- * },
474
- * device: {
475
- * ip: '192.168.1.1',
476
- * country: 'US',
477
- * ua: navigator.userAgent
478
- * },
323
+ * user: { gender: 'male', age: '25-34' },
324
+ * device: { ip: '192.168.1.1', country: 'US' },
479
325
  * excludedTopics: ['gambling'],
480
326
  * relevancy: 0.8
481
327
  * });
482
328
  * ```
483
329
  *
484
- * @example Handling the response
330
+ * @example Displaying and tracking
485
331
  * ```typescript
486
- * const response = await client.getAd({
487
- * messages,
488
- * sessionId: '...',
489
- * numAds: 1,
490
- * render_context: { placements: [{ placement: 'below_response' }] }
491
- * });
332
+ * const ads = await client.getAd({ messages, sessionId, placements });
492
333
  *
493
- * if (response) {
494
- * const ad = response.ads[0];
334
+ * if (ads && ads.length > 0) {
335
+ * const ad = ads[0];
495
336
  * // Display the ad
496
- * showAd(ad.adText);
337
+ * showAd(ad.adText, ad.cta);
497
338
  *
498
- * // Track impression
339
+ * // Track impression when ad is displayed
499
340
  * if (ad.impUrl) {
500
341
  * new Image().src = ad.impUrl;
501
342
  * }
343
+ *
344
+ * // Use clickUrl as the href for clicks
345
+ * adLink.href = ad.clickUrl || ad.url;
502
346
  * }
503
347
  * ```
504
348
  */
505
- getAd(params: AdParams): Promise<AdResponse | null>;
506
- /**
507
- * Request summary-based advertisements
508
- *
509
- * @description Fetches ads based on a search/summary query string.
510
- * Returns null if no relevant ad is available or on error.
511
- *
512
- * @param params - Request parameters including queryString
513
- * @returns Promise resolving to AdResponse or null if no ad available
514
- */
515
- summaryAd(params: SummaryAdParams): Promise<AdResponse | null>;
516
- /**
517
- * Request non-contextual advertisements
518
- *
519
- * @description Fetches ads without context matching. Useful for brand awareness placements.
520
- * Returns null if no ad is available or on error.
521
- *
522
- * @param params - Request parameters (sessionId required)
523
- * @returns Promise resolving to AdResponse or null if no ad available
524
- */
525
- nonContextualAd(params: NonContextualAdParams): Promise<AdResponse | null>;
526
- /**
527
- * Request a bid price for contextual ad placement
528
- *
529
- * @description First phase of two-phase ad flow. Returns bid price and bidId.
530
- * Use the bidId with render() to generate the actual ad creative.
531
- * Returns null if no bid is available or on error.
532
- *
533
- * @param params - Request parameters including messages array
534
- * @returns Promise resolving to BidResponse or null if no bid available
535
- */
536
- bid(params: BidParams): Promise<BidResponse | null>;
537
- /**
538
- * Render an ad from a cached bid
539
- *
540
- * @description Second phase of two-phase ad flow. Generates ad creative using cached bid context.
541
- * Returns null if bid expired (404) or on error. Bid expires after 60 seconds.
542
- *
543
- * @param params - Request parameters including bidId and realizedPrice
544
- * @returns Promise resolving to AdResponse or null if bid expired/error
545
- */
546
- render(params: RenderParams): Promise<AdResponse | null>;
349
+ getAd(params: AdParams): Promise<Ad[] | null>;
547
350
  /**
548
351
  * Handle and log API errors
549
352
  *
@@ -558,4 +361,4 @@ declare class Client {
558
361
  private handleError;
559
362
  }
560
363
 
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 };
364
+ export { type Ad, type AdParams, type ApiErrorResponse, Client, type ClientParams, type DeviceObject, type Gender, type MessageObject, type Placement, type PlacementObject, type Role, type UserObject };
package/dist/index.d.ts CHANGED
@@ -27,38 +27,8 @@ type Placement = 'above_response' | 'below_response' | 'inline_response' | 'left
27
27
  interface PlacementObject {
28
28
  /** Position where the ad should appear (required) */
29
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;
30
+ /** Tracking ID for this specific ad slot (required) */
31
+ placement_id: string;
62
32
  }
63
33
  /**
64
34
  * Represents a single message in a conversation
@@ -140,14 +110,10 @@ interface UserObject {
140
110
  * { role: 'assistant', content: 'What is your budget?' }
141
111
  * ],
142
112
  * sessionId: 'session-123',
143
- * numAds: 1,
144
- * render_context: {
145
- * placements: [{ placement: 'below_response' }]
146
- * },
113
+ * placements: [{ placement: 'below_response' }],
147
114
  * userId: 'user-456',
148
- * testAd: true,
149
115
  * user: { gender: 'male', age: '25-34' },
150
- * device: { ip: '1.2.3.4', country: 'US', ua: 'Mozilla/5.0...' },
116
+ * device: { ip: '1.2.3.4', country: 'US' },
151
117
  * excludedTopics: ['politics'],
152
118
  * relevancy: 0.5
153
119
  * };
@@ -158,10 +124,8 @@ interface AdParams {
158
124
  messages: MessageObject[];
159
125
  /** Session identifier for ad relevance (required) */
160
126
  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;
127
+ /** Ad placement specifications (required). Array of 1-10 placements. */
128
+ placements: PlacementObject[];
165
129
  /** Unique user identifier */
166
130
  userId?: string;
167
131
  /** Device and location information */
@@ -172,7 +136,7 @@ interface AdParams {
172
136
  excludedTopics?: string[];
173
137
  /** Minimum relevancy score threshold (0-1). Higher = more relevant but fewer ads */
174
138
  relevancy?: number | null;
175
- /** Returns a test ad when true */
139
+ /** Returns a test ad when true (no billing, for integration testing) */
176
140
  testAd?: boolean;
177
141
  /**
178
142
  * Additional custom fields for publisher-specific targeting
@@ -182,55 +146,37 @@ interface AdParams {
182
146
  }
183
147
  /**
184
148
  * Single ad object in responses.
185
- * @description Contains all ad creative and tracking data.
149
+ * @description Contains ad creative and tracking data. Returned as a flat array from v1 API.
150
+ * @example
151
+ * ```typescript
152
+ * const ad: Ad = {
153
+ * adText: 'Check out our amazing laptops!',
154
+ * title: 'Dell XPS 15',
155
+ * cta: 'Shop Now',
156
+ * brandName: 'Dell',
157
+ * url: 'https://dell.com/xps',
158
+ * impUrl: 'https://tracking.example.com/imp?id=123',
159
+ * clickUrl: 'https://tracking.example.com/click?id=123'
160
+ * };
161
+ * ```
186
162
  */
187
163
  interface Ad {
188
164
  /** The advertisement copy text */
189
165
  adText: string;
190
- /** Unique ad identifier */
191
- adId: string;
192
166
  /** Ad title */
193
167
  title?: string;
168
+ /** Call-to-action text (e.g., 'Learn More', 'Shop Now') */
169
+ cta?: string;
194
170
  /** Brand/advertiser name */
195
171
  brandName?: string;
196
- /** Brand logo image URL */
197
- brandImage?: string;
198
172
  /** Landing page URL */
199
173
  url?: string;
200
174
  /** Favicon URL */
201
175
  favicon?: string;
202
- /** Impression tracking URL */
176
+ /** Impression tracking URL - fire this when ad is displayed */
203
177
  impUrl?: string;
204
- /** Click-through tracking URL */
178
+ /** Click-through tracking URL - use this as href for ad clicks */
205
179
  clickUrl?: string;
206
- /** Payout amount in USD */
207
- payout?: number;
208
- }
209
- /**
210
- * Response from the Gravity API containing ad data
211
- * @description Returned by getAd() when a relevant advertisement is found
212
- * @example
213
- * ```typescript
214
- * const response: AdResponse = {
215
- * ads: [{
216
- * adText: 'Check out our amazing laptops!',
217
- * adId: 'ad-123',
218
- * impUrl: 'https://tracking.example.com/imp?id=123',
219
- * clickUrl: 'https://example.com/laptops',
220
- * payout: 0.50
221
- * }],
222
- * numAds: 1,
223
- * totalPayout: 0.50
224
- * };
225
- * ```
226
- */
227
- interface AdResponse {
228
- /** Array of ad objects */
229
- ads: Ad[];
230
- /** Number of ads returned */
231
- numAds: number;
232
- /** Total payout across all ads */
233
- totalPayout?: number;
234
180
  }
235
181
  /**
236
182
  * Error response structure from the Gravity API
@@ -244,85 +190,6 @@ interface ApiErrorResponse {
244
190
  /** HTTP status code */
245
191
  statusCode?: number;
246
192
  }
247
- /**
248
- * Base fields shared across all ad requests.
249
- */
250
- interface AdRequestBase {
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;
257
- /** Unique user identifier */
258
- userId?: string;
259
- /** Device and location information */
260
- device?: DeviceObject;
261
- /** User demographic and interest data */
262
- user?: UserObject;
263
- /** Topics to exclude from ad matching */
264
- excludedTopics?: string[];
265
- /** Minimum relevancy score threshold (0-1) */
266
- relevancy?: number | null;
267
- /** Returns a test ad when true */
268
- testAd?: boolean;
269
- /** Additional custom fields */
270
- [key: string]: unknown;
271
- }
272
- /**
273
- * POST /api/v1/ad/summary
274
- * @description Requires queryString for summary-based targeting.
275
- */
276
- interface SummaryAdParams extends AdRequestBase {
277
- /** Search/summary query string (required) */
278
- queryString: string;
279
- }
280
- /**
281
- * POST /api/v1/ad/non-contextual
282
- * @description No context required - returns ads without context matching.
283
- */
284
- interface NonContextualAdParams extends AdRequestBase {
285
- }
286
- /**
287
- * POST /api/v1/bid
288
- * @description Two-phase bid request. Returns bid price and bidId.
289
- */
290
- interface BidParams {
291
- /** Array of conversation messages (required) */
292
- messages: MessageObject[];
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;
299
- /** Unique user identifier */
300
- userId?: string;
301
- /** Chat/conversation identifier */
302
- chatId?: string;
303
- /** Device and location information */
304
- device?: DeviceObject;
305
- }
306
- /**
307
- * POST /api/v1/render
308
- * @description Two-phase render request using cached bid context.
309
- */
310
- interface RenderParams {
311
- /** Bid identifier from the bid phase (required) */
312
- bidId: string;
313
- /** Realized price to charge (required) */
314
- realizedPrice: number;
315
- }
316
- /**
317
- * Bid response.
318
- * @description Returned by the bid endpoint.
319
- */
320
- interface BidResponse {
321
- /** Clearing price (CPM) */
322
- bid: number;
323
- /** Bid identifier for the render phase */
324
- bidId: string;
325
- }
326
193
 
327
194
  /**
328
195
  * Configuration options for the Gravity API Client
@@ -367,20 +234,16 @@ interface ClientParams {
367
234
  *
368
235
  * const client = new Client('your-api-key');
369
236
  *
370
- * const response = await client.getAd({
237
+ * const ads = await client.getAd({
371
238
  * messages: [
372
239
  * { role: 'user', content: 'What laptop should I buy?' }
373
240
  * ],
374
241
  * sessionId: 'session-123',
375
- * numAds: 1,
376
- * render_context: {
377
- * placements: [{ placement: 'below_response' }]
378
- * }
242
+ * placements: [{ placement: 'below_response' }]
379
243
  * });
380
244
  *
381
- * if (response) {
382
- * const ad = response.ads[0];
383
- * console.log(ad.adText);
245
+ * if (ads) {
246
+ * console.log(ads[0].adText);
384
247
  * }
385
248
  * ```
386
249
  *
@@ -426,124 +289,64 @@ declare class Client {
426
289
  */
427
290
  constructor(apiKey: string, params?: ClientParams);
428
291
  /**
429
- * Request a contextually relevant advertisement
292
+ * Request contextually relevant advertisements
430
293
  *
431
294
  * @description Fetches ads based on the provided conversation context and targeting parameters.
432
295
  * Returns `null` if no relevant ad is available or if an error occurs.
433
296
  *
434
297
  * @param params - Ad request parameters including conversation messages
435
- * @returns Promise resolving to AdResponse or null if no ad available
298
+ * @returns Promise resolving to Ad array or null if no ads available
436
299
  *
437
300
  * @example Basic request
438
301
  * ```typescript
439
- * const response = await client.getAd({
302
+ * const ads = await client.getAd({
440
303
  * messages: [
441
304
  * { role: 'user', content: 'I need a new laptop for programming' },
442
305
  * { role: 'assistant', content: 'What is your budget range?' }
443
306
  * ],
444
307
  * sessionId: 'session-123',
445
- * numAds: 1,
446
- * render_context: {
447
- * placements: [{ placement: 'below_response' }]
448
- * },
449
- * userId: 'user-456',
308
+ * placements: [{ placement: 'below_response' }]
450
309
  * });
451
310
  *
452
- * if (response) {
453
- * const ad = response.ads[0];
454
- * console.log(ad.adText);
311
+ * if (ads) {
312
+ * console.log(ads[0].adText);
455
313
  * }
456
314
  * ```
457
315
  *
458
- * @example Full request with targeting
316
+ * @example With targeting options
459
317
  * ```typescript
460
- * const response = await client.getAd({
318
+ * const ads = await client.getAd({
461
319
  * messages: [...],
462
320
  * sessionId: 'session-123',
463
- * numAds: 1,
464
- * render_context: {
465
- * placements: [{ placement: 'below_response' }],
466
- * max_ad_length: 200
467
- * },
321
+ * placements: [{ placement: 'below_response' }],
468
322
  * userId: 'user-456',
469
- * user: {
470
- * uid: 'user-123',
471
- * gender: 'male',
472
- * age: '25-34'
473
- * },
474
- * device: {
475
- * ip: '192.168.1.1',
476
- * country: 'US',
477
- * ua: navigator.userAgent
478
- * },
323
+ * user: { gender: 'male', age: '25-34' },
324
+ * device: { ip: '192.168.1.1', country: 'US' },
479
325
  * excludedTopics: ['gambling'],
480
326
  * relevancy: 0.8
481
327
  * });
482
328
  * ```
483
329
  *
484
- * @example Handling the response
330
+ * @example Displaying and tracking
485
331
  * ```typescript
486
- * const response = await client.getAd({
487
- * messages,
488
- * sessionId: '...',
489
- * numAds: 1,
490
- * render_context: { placements: [{ placement: 'below_response' }] }
491
- * });
332
+ * const ads = await client.getAd({ messages, sessionId, placements });
492
333
  *
493
- * if (response) {
494
- * const ad = response.ads[0];
334
+ * if (ads && ads.length > 0) {
335
+ * const ad = ads[0];
495
336
  * // Display the ad
496
- * showAd(ad.adText);
337
+ * showAd(ad.adText, ad.cta);
497
338
  *
498
- * // Track impression
339
+ * // Track impression when ad is displayed
499
340
  * if (ad.impUrl) {
500
341
  * new Image().src = ad.impUrl;
501
342
  * }
343
+ *
344
+ * // Use clickUrl as the href for clicks
345
+ * adLink.href = ad.clickUrl || ad.url;
502
346
  * }
503
347
  * ```
504
348
  */
505
- getAd(params: AdParams): Promise<AdResponse | null>;
506
- /**
507
- * Request summary-based advertisements
508
- *
509
- * @description Fetches ads based on a search/summary query string.
510
- * Returns null if no relevant ad is available or on error.
511
- *
512
- * @param params - Request parameters including queryString
513
- * @returns Promise resolving to AdResponse or null if no ad available
514
- */
515
- summaryAd(params: SummaryAdParams): Promise<AdResponse | null>;
516
- /**
517
- * Request non-contextual advertisements
518
- *
519
- * @description Fetches ads without context matching. Useful for brand awareness placements.
520
- * Returns null if no ad is available or on error.
521
- *
522
- * @param params - Request parameters (sessionId required)
523
- * @returns Promise resolving to AdResponse or null if no ad available
524
- */
525
- nonContextualAd(params: NonContextualAdParams): Promise<AdResponse | null>;
526
- /**
527
- * Request a bid price for contextual ad placement
528
- *
529
- * @description First phase of two-phase ad flow. Returns bid price and bidId.
530
- * Use the bidId with render() to generate the actual ad creative.
531
- * Returns null if no bid is available or on error.
532
- *
533
- * @param params - Request parameters including messages array
534
- * @returns Promise resolving to BidResponse or null if no bid available
535
- */
536
- bid(params: BidParams): Promise<BidResponse | null>;
537
- /**
538
- * Render an ad from a cached bid
539
- *
540
- * @description Second phase of two-phase ad flow. Generates ad creative using cached bid context.
541
- * Returns null if bid expired (404) or on error. Bid expires after 60 seconds.
542
- *
543
- * @param params - Request parameters including bidId and realizedPrice
544
- * @returns Promise resolving to AdResponse or null if bid expired/error
545
- */
546
- render(params: RenderParams): Promise<AdResponse | null>;
349
+ getAd(params: AdParams): Promise<Ad[] | null>;
547
350
  /**
548
351
  * Handle and log API errors
549
352
  *
@@ -558,4 +361,4 @@ declare class Client {
558
361
  private handleError;
559
362
  }
560
363
 
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 };
364
+ export { type Ad, type AdParams, type ApiErrorResponse, Client, type ClientParams, type DeviceObject, type Gender, type MessageObject, type Placement, type PlacementObject, type Role, type UserObject };
package/dist/index.js CHANGED
@@ -74,79 +74,60 @@ var Client = class {
74
74
  });
75
75
  }
76
76
  /**
77
- * Request a contextually relevant advertisement
78
- *
77
+ * Request contextually relevant advertisements
78
+ *
79
79
  * @description Fetches ads based on the provided conversation context and targeting parameters.
80
80
  * Returns `null` if no relevant ad is available or if an error occurs.
81
- *
81
+ *
82
82
  * @param params - Ad request parameters including conversation messages
83
- * @returns Promise resolving to AdResponse or null if no ad available
84
- *
83
+ * @returns Promise resolving to Ad array or null if no ads available
84
+ *
85
85
  * @example Basic request
86
86
  * ```typescript
87
- * const response = await client.getAd({
87
+ * const ads = await client.getAd({
88
88
  * messages: [
89
89
  * { role: 'user', content: 'I need a new laptop for programming' },
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
- * },
97
- * userId: 'user-456',
93
+ * placements: [{ placement: 'below_response' }]
98
94
  * });
99
- *
100
- * if (response) {
101
- * const ad = response.ads[0];
102
- * console.log(ad.adText);
95
+ *
96
+ * if (ads) {
97
+ * console.log(ads[0].adText);
103
98
  * }
104
99
  * ```
105
- *
106
- * @example Full request with targeting
100
+ *
101
+ * @example With targeting options
107
102
  * ```typescript
108
- * const response = await client.getAd({
103
+ * const ads = await client.getAd({
109
104
  * messages: [...],
110
105
  * sessionId: 'session-123',
111
- * numAds: 1,
112
- * render_context: {
113
- * placements: [{ placement: 'below_response' }],
114
- * max_ad_length: 200
115
- * },
106
+ * placements: [{ placement: 'below_response' }],
116
107
  * userId: 'user-456',
117
- * user: {
118
- * uid: 'user-123',
119
- * gender: 'male',
120
- * age: '25-34'
121
- * },
122
- * device: {
123
- * ip: '192.168.1.1',
124
- * country: 'US',
125
- * ua: navigator.userAgent
126
- * },
108
+ * user: { gender: 'male', age: '25-34' },
109
+ * device: { ip: '192.168.1.1', country: 'US' },
127
110
  * excludedTopics: ['gambling'],
128
111
  * relevancy: 0.8
129
112
  * });
130
113
  * ```
131
- *
132
- * @example Handling the response
114
+ *
115
+ * @example Displaying and tracking
133
116
  * ```typescript
134
- * const response = await client.getAd({
135
- * messages,
136
- * sessionId: '...',
137
- * numAds: 1,
138
- * render_context: { placements: [{ placement: 'below_response' }] }
139
- * });
140
- *
141
- * if (response) {
142
- * const ad = response.ads[0];
117
+ * const ads = await client.getAd({ messages, sessionId, placements });
118
+ *
119
+ * if (ads && ads.length > 0) {
120
+ * const ad = ads[0];
143
121
  * // Display the ad
144
- * showAd(ad.adText);
145
- *
146
- * // Track impression
122
+ * showAd(ad.adText, ad.cta);
123
+ *
124
+ * // Track impression when ad is displayed
147
125
  * if (ad.impUrl) {
148
126
  * new Image().src = ad.impUrl;
149
127
  * }
128
+ *
129
+ * // Use clickUrl as the href for clicks
130
+ * adLink.href = ad.clickUrl || ad.url;
150
131
  * }
151
132
  * ```
152
133
  */
@@ -161,7 +142,7 @@ var Client = class {
161
142
  if (response.status === 204) {
162
143
  return null;
163
144
  }
164
- if (response.data && response.data.ads && response.data.ads.length > 0) {
145
+ if (response.data && Array.isArray(response.data) && response.data.length > 0) {
165
146
  return response.data;
166
147
  }
167
148
  return null;
@@ -170,121 +151,6 @@ var Client = class {
170
151
  return null;
171
152
  }
172
153
  }
173
- // ===========================================================================
174
- // Alternative Ad Methods (for advanced use cases)
175
- // ===========================================================================
176
- /**
177
- * Request summary-based advertisements
178
- *
179
- * @description Fetches ads based on a search/summary query string.
180
- * Returns null if no relevant ad is available or on error.
181
- *
182
- * @param params - Request parameters including queryString
183
- * @returns Promise resolving to AdResponse or null if no ad available
184
- */
185
- async summaryAd(params) {
186
- try {
187
- const body = {
188
- ...params,
189
- excludedTopics: params.excludedTopics ?? this.excludedTopics,
190
- relevancy: params.relevancy ?? this.relevancy
191
- };
192
- const response = await this.axios.post("/api/v1/ad/summary", body);
193
- if (response.status === 204) {
194
- return null;
195
- }
196
- if (response.data && response.data.ads && response.data.ads.length > 0) {
197
- return response.data;
198
- }
199
- return null;
200
- } catch (error) {
201
- this.handleError(error, "summaryAd");
202
- return null;
203
- }
204
- }
205
- /**
206
- * Request non-contextual advertisements
207
- *
208
- * @description Fetches ads without context matching. Useful for brand awareness placements.
209
- * Returns null if no ad is available or on error.
210
- *
211
- * @param params - Request parameters (sessionId required)
212
- * @returns Promise resolving to AdResponse or null if no ad available
213
- */
214
- async nonContextualAd(params) {
215
- try {
216
- const body = {
217
- ...params,
218
- excludedTopics: params.excludedTopics ?? this.excludedTopics
219
- };
220
- const response = await this.axios.post("/api/v1/ad/non-contextual", body);
221
- if (response.status === 204) {
222
- return null;
223
- }
224
- if (response.data && response.data.ads && response.data.ads.length > 0) {
225
- return response.data;
226
- }
227
- return null;
228
- } catch (error) {
229
- this.handleError(error, "nonContextualAd");
230
- return null;
231
- }
232
- }
233
- /**
234
- * Request a bid price for contextual ad placement
235
- *
236
- * @description First phase of two-phase ad flow. Returns bid price and bidId.
237
- * Use the bidId with render() to generate the actual ad creative.
238
- * Returns null if no bid is available or on error.
239
- *
240
- * @param params - Request parameters including messages array
241
- * @returns Promise resolving to BidResponse or null if no bid available
242
- */
243
- async bid(params) {
244
- try {
245
- const response = await this.axios.post("/api/v1/bid", params);
246
- if (response.status === 204) {
247
- return null;
248
- }
249
- if (response.data && response.data.data) {
250
- return {
251
- bid: response.data.data.bid,
252
- bidId: response.data.data.bidId
253
- };
254
- }
255
- return null;
256
- } catch (error) {
257
- this.handleError(error, "bid");
258
- return null;
259
- }
260
- }
261
- /**
262
- * Render an ad from a cached bid
263
- *
264
- * @description Second phase of two-phase ad flow. Generates ad creative using cached bid context.
265
- * Returns null if bid expired (404) or on error. Bid expires after 60 seconds.
266
- *
267
- * @param params - Request parameters including bidId and realizedPrice
268
- * @returns Promise resolving to AdResponse or null if bid expired/error
269
- */
270
- async render(params) {
271
- try {
272
- const response = await this.axios.post("/api/v1/render", params);
273
- if (response.status === 204) {
274
- return null;
275
- }
276
- if (response.data && response.data.ads && response.data.ads.length > 0) {
277
- return response.data;
278
- }
279
- return null;
280
- } catch (error) {
281
- if (import_axios.default.isAxiosError(error) && error.response?.status === 404) {
282
- return null;
283
- }
284
- this.handleError(error, "render");
285
- return null;
286
- }
287
- }
288
154
  /**
289
155
  * Handle and log API errors
290
156
  *
package/dist/index.mjs CHANGED
@@ -38,79 +38,60 @@ var Client = class {
38
38
  });
39
39
  }
40
40
  /**
41
- * Request a contextually relevant advertisement
42
- *
41
+ * Request contextually relevant advertisements
42
+ *
43
43
  * @description Fetches ads based on the provided conversation context and targeting parameters.
44
44
  * Returns `null` if no relevant ad is available or if an error occurs.
45
- *
45
+ *
46
46
  * @param params - Ad request parameters including conversation messages
47
- * @returns Promise resolving to AdResponse or null if no ad available
48
- *
47
+ * @returns Promise resolving to Ad array or null if no ads available
48
+ *
49
49
  * @example Basic request
50
50
  * ```typescript
51
- * const response = await client.getAd({
51
+ * const ads = await client.getAd({
52
52
  * messages: [
53
53
  * { role: 'user', content: 'I need a new laptop for programming' },
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
- * },
61
- * userId: 'user-456',
57
+ * placements: [{ placement: 'below_response' }]
62
58
  * });
63
- *
64
- * if (response) {
65
- * const ad = response.ads[0];
66
- * console.log(ad.adText);
59
+ *
60
+ * if (ads) {
61
+ * console.log(ads[0].adText);
67
62
  * }
68
63
  * ```
69
- *
70
- * @example Full request with targeting
64
+ *
65
+ * @example With targeting options
71
66
  * ```typescript
72
- * const response = await client.getAd({
67
+ * const ads = await client.getAd({
73
68
  * messages: [...],
74
69
  * sessionId: 'session-123',
75
- * numAds: 1,
76
- * render_context: {
77
- * placements: [{ placement: 'below_response' }],
78
- * max_ad_length: 200
79
- * },
70
+ * placements: [{ placement: 'below_response' }],
80
71
  * userId: 'user-456',
81
- * user: {
82
- * uid: 'user-123',
83
- * gender: 'male',
84
- * age: '25-34'
85
- * },
86
- * device: {
87
- * ip: '192.168.1.1',
88
- * country: 'US',
89
- * ua: navigator.userAgent
90
- * },
72
+ * user: { gender: 'male', age: '25-34' },
73
+ * device: { ip: '192.168.1.1', country: 'US' },
91
74
  * excludedTopics: ['gambling'],
92
75
  * relevancy: 0.8
93
76
  * });
94
77
  * ```
95
- *
96
- * @example Handling the response
78
+ *
79
+ * @example Displaying and tracking
97
80
  * ```typescript
98
- * const response = await client.getAd({
99
- * messages,
100
- * sessionId: '...',
101
- * numAds: 1,
102
- * render_context: { placements: [{ placement: 'below_response' }] }
103
- * });
104
- *
105
- * if (response) {
106
- * const ad = response.ads[0];
81
+ * const ads = await client.getAd({ messages, sessionId, placements });
82
+ *
83
+ * if (ads && ads.length > 0) {
84
+ * const ad = ads[0];
107
85
  * // Display the ad
108
- * showAd(ad.adText);
109
- *
110
- * // Track impression
86
+ * showAd(ad.adText, ad.cta);
87
+ *
88
+ * // Track impression when ad is displayed
111
89
  * if (ad.impUrl) {
112
90
  * new Image().src = ad.impUrl;
113
91
  * }
92
+ *
93
+ * // Use clickUrl as the href for clicks
94
+ * adLink.href = ad.clickUrl || ad.url;
114
95
  * }
115
96
  * ```
116
97
  */
@@ -125,7 +106,7 @@ var Client = class {
125
106
  if (response.status === 204) {
126
107
  return null;
127
108
  }
128
- if (response.data && response.data.ads && response.data.ads.length > 0) {
109
+ if (response.data && Array.isArray(response.data) && response.data.length > 0) {
129
110
  return response.data;
130
111
  }
131
112
  return null;
@@ -134,121 +115,6 @@ var Client = class {
134
115
  return null;
135
116
  }
136
117
  }
137
- // ===========================================================================
138
- // Alternative Ad Methods (for advanced use cases)
139
- // ===========================================================================
140
- /**
141
- * Request summary-based advertisements
142
- *
143
- * @description Fetches ads based on a search/summary query string.
144
- * Returns null if no relevant ad is available or on error.
145
- *
146
- * @param params - Request parameters including queryString
147
- * @returns Promise resolving to AdResponse or null if no ad available
148
- */
149
- async summaryAd(params) {
150
- try {
151
- const body = {
152
- ...params,
153
- excludedTopics: params.excludedTopics ?? this.excludedTopics,
154
- relevancy: params.relevancy ?? this.relevancy
155
- };
156
- const response = await this.axios.post("/api/v1/ad/summary", body);
157
- if (response.status === 204) {
158
- return null;
159
- }
160
- if (response.data && response.data.ads && response.data.ads.length > 0) {
161
- return response.data;
162
- }
163
- return null;
164
- } catch (error) {
165
- this.handleError(error, "summaryAd");
166
- return null;
167
- }
168
- }
169
- /**
170
- * Request non-contextual advertisements
171
- *
172
- * @description Fetches ads without context matching. Useful for brand awareness placements.
173
- * Returns null if no ad is available or on error.
174
- *
175
- * @param params - Request parameters (sessionId required)
176
- * @returns Promise resolving to AdResponse or null if no ad available
177
- */
178
- async nonContextualAd(params) {
179
- try {
180
- const body = {
181
- ...params,
182
- excludedTopics: params.excludedTopics ?? this.excludedTopics
183
- };
184
- const response = await this.axios.post("/api/v1/ad/non-contextual", body);
185
- if (response.status === 204) {
186
- return null;
187
- }
188
- if (response.data && response.data.ads && response.data.ads.length > 0) {
189
- return response.data;
190
- }
191
- return null;
192
- } catch (error) {
193
- this.handleError(error, "nonContextualAd");
194
- return null;
195
- }
196
- }
197
- /**
198
- * Request a bid price for contextual ad placement
199
- *
200
- * @description First phase of two-phase ad flow. Returns bid price and bidId.
201
- * Use the bidId with render() to generate the actual ad creative.
202
- * Returns null if no bid is available or on error.
203
- *
204
- * @param params - Request parameters including messages array
205
- * @returns Promise resolving to BidResponse or null if no bid available
206
- */
207
- async bid(params) {
208
- try {
209
- const response = await this.axios.post("/api/v1/bid", params);
210
- if (response.status === 204) {
211
- return null;
212
- }
213
- if (response.data && response.data.data) {
214
- return {
215
- bid: response.data.data.bid,
216
- bidId: response.data.data.bidId
217
- };
218
- }
219
- return null;
220
- } catch (error) {
221
- this.handleError(error, "bid");
222
- return null;
223
- }
224
- }
225
- /**
226
- * Render an ad from a cached bid
227
- *
228
- * @description Second phase of two-phase ad flow. Generates ad creative using cached bid context.
229
- * Returns null if bid expired (404) or on error. Bid expires after 60 seconds.
230
- *
231
- * @param params - Request parameters including bidId and realizedPrice
232
- * @returns Promise resolving to AdResponse or null if bid expired/error
233
- */
234
- async render(params) {
235
- try {
236
- const response = await this.axios.post("/api/v1/render", params);
237
- if (response.status === 204) {
238
- return null;
239
- }
240
- if (response.data && response.data.ads && response.data.ads.length > 0) {
241
- return response.data;
242
- }
243
- return null;
244
- } catch (error) {
245
- if (axios.isAxiosError(error) && error.response?.status === 404) {
246
- return null;
247
- }
248
- this.handleError(error, "render");
249
- return null;
250
- }
251
- }
252
118
  /**
253
119
  * Handle and log API errors
254
120
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ai/api",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "Gravity JS SDK for retrieving targeted advertisements",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",