@cshah18/sdk 4.7.0 → 4.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,17 +6,18 @@ import { SocketManager } from "./socket";
6
6
  * Main CoBuy SDK implementation
7
7
  */
8
8
  export declare class CoBuy implements CoBuySDK {
9
- private configManager;
10
- private logger;
9
+ private readonly configManager;
10
+ private readonly logger;
11
11
  private apiClient;
12
12
  private analyticsClient;
13
13
  private sessionId;
14
+ private botdScore;
14
15
  private readonly SESSION_STORAGE_KEY;
15
16
  private readonly CHECKOUT_REF_PREFIX;
16
17
  private lobbyModal;
17
- private modals;
18
+ private readonly modals;
18
19
  private socketManager;
19
- private widgets;
20
+ private readonly widgets;
20
21
  constructor();
21
22
  /**
22
23
  * Initialize or retrieve existing session ID from storage
@@ -45,25 +46,175 @@ export declare class CoBuy implements CoBuySDK {
45
46
  * Get the current session ID (core SDK concept)
46
47
  */
47
48
  getSessionId(): string;
49
+ /**
50
+ * Initialize BotD detection and store score for API requests
51
+ */
52
+ private initializeBotd;
53
+ private handleFraudError;
48
54
  /**
49
55
  * Prepare checkout for a group if not already prepared
50
56
  * Checks localStorage to prevent duplicate calls for the same product/group/session
51
57
  */
52
58
  private prepareCheckoutIfNotDone;
53
59
  /**
54
- * Initialize the SDK with configuration
60
+ * Initialize the CoBuy SDK with configuration
61
+ *
62
+ * Must be called before rendering widgets or opening modals.
63
+ *
64
+ * @param {CoBuyInitOptions} options - SDK configuration options
65
+ * @param {"public" | "token"} options.authMode - Authentication mode (public key or session token)
66
+ * @param {string} [options.merchantKey] - Merchant public key (required for public mode)
67
+ * @param {string | (() => string | Promise<string>)} [options.sessionToken] - Session token (required for token mode)
68
+ * @param {"dev" | "prod"} [options.env] - Environment (dev or prod, defaults to prod)
69
+ * @param {boolean} [options.debug] - Enable debug logging
70
+ * @param {Object} [options.auth] - Optional auth callbacks (onAuthError, onTokenExpired)
71
+ * @param {Object} [options.events] - Optional event handlers (onGroupFulfilled, onGroupCreated, onGroupMemberJoined, onModalOpen, onModalClose)
72
+ * @param {Object} [options.customHeaders] - Optional custom headers to include in API requests
73
+ *
74
+ * @throws {Error} If required configuration is missing or invalid
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * // Initialize with public key authentication
79
+ * CoBuy.init({
80
+ * authMode: 'public',
81
+ * merchantKey: 'pk_live_abc123xyz',
82
+ * env: 'prod',
83
+ * debug: false
84
+ * });
85
+ *
86
+ * // Initialize with session token
87
+ * CoBuy.init({
88
+ * authMode: 'token',
89
+ * sessionToken: 'token_abc123xyz',
90
+ * env: 'prod'
91
+ * });
92
+ *
93
+ * // Initialize with async token provider
94
+ * CoBuy.init({
95
+ * authMode: 'token',
96
+ * sessionToken: async () => {
97
+ * const response = await fetch('/api/token');
98
+ * return response.json().token;
99
+ * },
100
+ * env: 'prod'
101
+ * });
102
+ * ```
55
103
  */
56
104
  init(options: CoBuyInitOptions): void;
57
105
  /**
58
106
  * Render the CoBuy widget into a DOM container
107
+ *
108
+ * Creates and renders a collaborative buying widget for a specific product.
109
+ * The widget displays group status, members, and allows users to join groups.
110
+ *
111
+ * @param {RenderWidgetOptions} options - Widget rendering options
112
+ * @param {string} options.productId - Product ID to render widget for (required)
113
+ * @param {string | HTMLElement} options.container - DOM selector or element to render into (required)
114
+ * @param {Object} [options.theme] - Optional theme configuration (colors, fonts, animations)
115
+ * @param {Function} [options.onGroupSelect] - Callback when user selects a group
116
+ * @param {Function} [options.onError] - Callback for rendering errors (optional, errors also throw)
117
+ *
118
+ * @returns {Promise<void>} Resolves when widget is rendered, rejects if rendering fails
119
+ *
120
+ * @throws {CoBuyNotInitializedError} If SDK not initialized before calling
121
+ * @throws {CoBuyRenderError} If container not found or rendering fails
122
+ * @throws {CoBuyValidationError} If productId validation fails
123
+ *
124
+ * @description
125
+ * Error Handling:
126
+ * - Synchronous errors (not initialized, missing productId) are thrown immediately
127
+ * - Asynchronous errors (network, container not found) cause Promise rejection
128
+ * - onError callback is called with error details (for backwards compatibility)
129
+ * - Always handle Promise rejection OR use try/catch for synchronous errors
130
+ *
131
+ * @example
132
+ * ```typescript
133
+ * // Option 1: Using try/catch (recommended)
134
+ * try {
135
+ * await CoBuy.renderWidget({
136
+ * productId: 'prod_abc123',
137
+ * container: '#cobuy-widget-container'
138
+ * });
139
+ * } catch (error) {
140
+ * if (error instanceof CoBuyNotInitializedError) {
141
+ * console.error('SDK not initialized');
142
+ * } else if (error instanceof CoBuyRenderError) {
143
+ * console.error('Widget render failed:', error.message);
144
+ * }
145
+ * }
146
+ *
147
+ * // Option 2: Using .catch() (backwards compatible)
148
+ * CoBuy.renderWidget({
149
+ * productId: 'prod_abc123',
150
+ * container: '#widget'
151
+ * }).catch(error => {
152
+ * console.error('Widget error:', error);
153
+ * });
154
+ *
155
+ * // Option 3: Using onError callback + error throwing
156
+ * CoBuy.renderWidget({
157
+ * productId: 'prod_abc123',
158
+ * container: '#widget',
159
+ * onError: (error) => console.error('Async error:', error)
160
+ * }).catch(error => console.error('Promise rejected:', error));
161
+ * ```
59
162
  */
60
- renderWidget(options: RenderWidgetOptions): void;
163
+ renderWidget(options: RenderWidgetOptions): Promise<void>;
61
164
  /**
62
- * Open modal for product details
165
+ * Open a lobby modal for a group
166
+ *
167
+ * Displays a modal with group details, members, progress, and actions.
168
+ * Only one modal is open at a time (others are automatically closed).
169
+ *
170
+ * @param {ModalOptions} options - Modal configuration
171
+ * @param {string} options.productId - Product ID for the modal
172
+ * @param {string} [options.groupId] - Group ID to display
173
+ * @param {number} [options.groupNumber] - Group number for display
174
+ * @param {string} [options.status] - Group status (e.g., 'pending', 'complete')
175
+ * @param {number} [options.progress] - Group progress percentage (0-100)
176
+ * @param {number} [options.currentMembers] - Current number of members
177
+ * @param {number} [options.totalMembers] - Total members needed
178
+ * @param {number} [options.timeLeft] - Seconds remaining before group closes
179
+ * @param {number} [options.discount] - Discount percentage
180
+ * @param {string} [options.groupLink] - Share link for the group
181
+ * @param {Array} [options.activities] - Group activity feed
182
+ * @param {boolean} [options.isLocked] - Whether group is locked
183
+ * @param {Function} [options.onOpen] - Callback when modal opens
184
+ * @param {Function} [options.onClose] - Callback when modal closes
185
+ * @param {Function} [options.onCopyLink] - Callback when share link is copied
186
+ * @param {Function} [options.onShare] - Callback when share action triggered
187
+ *
188
+ * @returns {void}
189
+ *
190
+ * @example
191
+ * ```typescript
192
+ * CoBuy.openModal({
193
+ * productId: 'prod_abc123',
194
+ * groupId: 'grp_xyz789',
195
+ * status: 'pending',
196
+ * progress: 75,
197
+ * currentMembers: 3,
198
+ * totalMembers: 4,
199
+ * discount: 20,
200
+ * onOpen: () => console.log('Modal opened'),
201
+ * onClose: () => console.log('Modal closed')
202
+ * });
203
+ * ```
63
204
  */
64
205
  openModal(options: ModalOptions): void;
65
206
  /**
66
- * Close the modal
207
+ * Close the currently open modal
208
+ *
209
+ * Closes and cleans up the active lobby modal if one is open.
210
+ * Safe to call even if no modal is currently open.
211
+ *
212
+ * @returns {void}
213
+ *
214
+ * @example
215
+ * ```typescript
216
+ * CoBuy.closeModal();
217
+ * ```
67
218
  */
68
219
  closeModal(): void;
69
220
  /**
@@ -146,22 +297,83 @@ export declare class CoBuy implements CoBuySDK {
146
297
  confirmCheckout(groupId: string, checkoutRef: string, data?: CheckoutConfirmData): Promise<void>;
147
298
  /**
148
299
  * Get the initialized API client instance
300
+ *
301
+ * Returns the API client used for making requests to the CoBuy backend.
302
+ * Useful for advanced integrations or direct API calls.
303
+ *
304
+ * @returns {ApiClient | null} The API client instance, or null if SDK not initialized
305
+ *
306
+ * @example
307
+ * ```typescript
308
+ * const apiClient = CoBuy.getApiClient();
309
+ * if (apiClient) {
310
+ * const product = await apiClient.getProductReward('prod_abc123');
311
+ * }
312
+ * ```
149
313
  */
150
314
  getApiClient(): ApiClient | null;
151
315
  /**
152
316
  * Get the initialized Analytics client instance
317
+ *
318
+ * Returns the analytics client used for tracking user interactions.
319
+ * Useful for advanced event tracking or integration with analytics systems.
320
+ *
321
+ * @returns {AnalyticsClient | null} The analytics client instance, or null if SDK not initialized
322
+ *
323
+ * @example
324
+ * ```typescript
325
+ * const analytics = CoBuy.getAnalyticsClient();
326
+ * if (analytics) {
327
+ * await analytics.trackCustomEvent('user_action', { details: 'data' });
328
+ * }
329
+ * ```
153
330
  */
154
331
  getAnalyticsClient(): AnalyticsClient | null;
155
332
  /**
156
333
  * Get the initialized Socket manager instance
334
+ *
335
+ * Returns the socket manager used for real-time group updates.
336
+ * Only available in public authentication mode.
337
+ *
338
+ * @returns {SocketManager | null} The socket manager instance, or null if not initialized (token mode doesn't use sockets)
339
+ *
340
+ * @example
341
+ * ```typescript
342
+ * const socketManager = CoBuy.getSocketManager();
343
+ * if (socketManager) {
344
+ * socketManager.bindHandlers({
345
+ * onGroupCreated: (event) => console.log('New group:', event)
346
+ * });
347
+ * }
348
+ * ```
157
349
  */
158
350
  getSocketManager(): SocketManager | null;
159
351
  /**
160
- * Get SDK version
352
+ * Get the SDK version
353
+ *
354
+ * Returns the current version of the CoBuy SDK.
355
+ *
356
+ * @returns {string} SDK version in semver format (e.g., "1.0.0")
357
+ *
358
+ * @example
359
+ * ```typescript
360
+ * console.log(`CoBuy SDK v${CoBuy.version}`);
361
+ * ```
161
362
  */
162
363
  get version(): string;
163
364
  /**
164
- * Clean up resources (sockets etc.) if needed by host app
365
+ * Destroy the SDK and clean up resources
366
+ *
367
+ * Closes websocket connections, unbinds event handlers, and releases resources.
368
+ * Call this when unloading the page or removing the SDK from use.
369
+ *
370
+ * @returns {void}
371
+ *
372
+ * @example
373
+ * ```typescript
374
+ * // When unmounting the SDK (e.g., React cleanup)
375
+ * CoBuy.destroy();
376
+ * ```
165
377
  */
166
378
  destroy(): void;
167
379
  }
@@ -8,13 +8,20 @@ export declare class ConfigManager {
8
8
  * Default API base URLs for each environment
9
9
  */
10
10
  private static readonly DEFAULT_API_URLS;
11
+ /**
12
+ * Get API base URL override from environment (if provided)
13
+ * Supports both browser global and build-time env injection
14
+ */
15
+ private static getApiBaseUrlOverride;
11
16
  /**
12
17
  * Set and validate SDK configuration
18
+ *
19
+ * @throws {CoBuyInvalidConfigError} If authMode, merchantKey, or sessionToken validation fails
13
20
  */
14
21
  setConfig(options: CoBuyInitOptions): InternalConfig;
15
22
  /**
16
23
  * Get current configuration
17
- * @throws CoBuyNotInitializedError if SDK has not been initialized
24
+ * @throws {CoBuyNotInitializedError} if SDK has not been initialized
18
25
  */
19
26
  getConfig(): InternalConfig;
20
27
  /**
@@ -1,12 +1,116 @@
1
+ /**
2
+ * Base class for all CoBuy SDK errors
3
+ * Provides consistent error structure across the SDK
4
+ */
5
+ export declare class CoBuyError extends Error {
6
+ /**
7
+ * Error code for programmatic handling
8
+ * @example 'INVALID_CONFIG', 'NOT_INITIALIZED', 'RENDER_FAILED'
9
+ */
10
+ readonly code: string;
11
+ /**
12
+ * Additional error details (API response, validation info, etc.)
13
+ */
14
+ readonly details?: unknown;
15
+ constructor(message: string, code: string, details?: unknown);
16
+ }
1
17
  /**
2
18
  * Thrown when the SDK is used before initialization
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * try {
23
+ * CoBuy.renderWidget({...});
24
+ * } catch (error) {
25
+ * if (error instanceof CoBuyNotInitializedError) {
26
+ * console.log('SDK not initialized, call CoBuy.init() first');
27
+ * }
28
+ * }
29
+ * ```
3
30
  */
4
- export declare class CoBuyNotInitializedError extends Error {
31
+ export declare class CoBuyNotInitializedError extends CoBuyError {
5
32
  constructor();
6
33
  }
7
34
  /**
8
- * Thrown when invalid configuration is provided
35
+ * Thrown when invalid configuration is provided during initialization
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * try {
40
+ * CoBuy.init({
41
+ * authMode: 'public'
42
+ * // Missing merchantKey
43
+ * });
44
+ * } catch (error) {
45
+ * if (error instanceof CoBuyInvalidConfigError) {
46
+ * console.log('Config validation failed:', error.message);
47
+ * }
48
+ * }
49
+ * ```
50
+ */
51
+ export declare class CoBuyInvalidConfigError extends CoBuyError {
52
+ constructor(message: string, details?: unknown);
53
+ }
54
+ /**
55
+ * Thrown when widget rendering fails
56
+ * This includes container resolution, DOM manipulation, or state errors
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * try {
61
+ * await CoBuy.renderWidget({
62
+ * productId: 'prod_123',
63
+ * container: '#nonexistent'
64
+ * });
65
+ * } catch (error) {
66
+ * if (error instanceof CoBuyRenderError) {
67
+ * console.log('Widget render failed:', error.message);
68
+ * }
69
+ * }
70
+ * ```
71
+ */
72
+ export declare class CoBuyRenderError extends CoBuyError {
73
+ constructor(message: string, details?: unknown);
74
+ }
75
+ /**
76
+ * Thrown when API communication fails
77
+ * This includes network errors, CORS issues, timeouts, and server errors
78
+ *
79
+ * @example
80
+ * ```typescript
81
+ * try {
82
+ * await CoBuy.joinGroup('grp_123', {type: 'email', value: 'user@example.com'});
83
+ * } catch (error) {
84
+ * if (error instanceof CoBuyApiError) {
85
+ * console.log('API request failed:', error.code, error.message);
86
+ * if (error.details?.statusCode === 429) {
87
+ * console.log('Rate limited - retry later');
88
+ * }
89
+ * }
90
+ * }
91
+ * ```
92
+ */
93
+ export declare class CoBuyApiError extends CoBuyError {
94
+ constructor(message: string, code?: string, details?: unknown);
95
+ }
96
+ /**
97
+ * Thrown when input validation fails
98
+ * This includes invalid product IDs, container selectors, or option values
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * try {
103
+ * await CoBuy.renderWidget({
104
+ * productId: '', // Invalid: empty string
105
+ * container: '#widget'
106
+ * });
107
+ * } catch (error) {
108
+ * if (error instanceof CoBuyValidationError) {
109
+ * console.log('Invalid input:', error.message);
110
+ * }
111
+ * }
112
+ * ```
9
113
  */
10
- export declare class CoBuyInvalidConfigError extends Error {
11
- constructor(message: string);
114
+ export declare class CoBuyValidationError extends CoBuyError {
115
+ constructor(message: string, details?: unknown);
12
116
  }
@@ -73,6 +73,56 @@ export interface AuthCallbacks {
73
73
  */
74
74
  onTokenExpired?: () => void | Promise<void>;
75
75
  }
76
+ /**
77
+ * Performance tuning options for SDK
78
+ *
79
+ * Use to optimize for your specific environment:
80
+ * - Slow networks: increase requestTimeout, maxRetries
81
+ * - Fast networks: decrease requestTimeout
82
+ * - Snappy UI: use 'fast' animationSpeed
83
+ * - Smooth UX: use 'normal' or 'smooth' animationSpeed
84
+ */
85
+ export interface PerformanceConfig {
86
+ /**
87
+ * HTTP request timeout in milliseconds (default: 30000)
88
+ *
89
+ * Adjust based on your network conditions:
90
+ * - 10000 (10s): Fast networks, aggressively fail slow requests
91
+ * - 30000 (30s): Standard, most reliable networks
92
+ * - 60000 (60s): Slow/intermittent networks, flaky connectivity
93
+ *
94
+ * @example
95
+ * requestTimeout: 15000 // 15 second timeout
96
+ */
97
+ requestTimeout?: number;
98
+ /**
99
+ * Maximum number of retry attempts for transient errors (default: 2)
100
+ *
101
+ * Applies to timeout, 502, 503, 504 errors only
102
+ * Does not retry on permanent errors (400, 401, 403, 404, etc)
103
+ *
104
+ * Adjust based on reliability needs:
105
+ * - 1: Fast-fail, minimize latency (single attempt + 1 retry)
106
+ * - 2: Balanced approach (recommended)
107
+ * - 3+: Flaky networks, maximize reliability at cost of latency
108
+ *
109
+ * @example
110
+ * maxRetries: 3 // Up to 3 retry attempts (4 total attempts)
111
+ */
112
+ maxRetries?: number;
113
+ /**
114
+ * Animation speed for widget transitions (default: "normal")
115
+ *
116
+ * Affects all animations in the collaborative buying widget:
117
+ * - 'fast': 0.75x speed, snappy feel, 375ms-750ms transitions
118
+ * - 'normal': 1x speed, balanced, 500ms-1000ms transitions (default)
119
+ * - 'slow': 1.5x speed, smooth, 750ms-1500ms transitions
120
+ *
121
+ * @example
122
+ * animationSpeed: 'fast' // For high-energy brand feel
123
+ */
124
+ animationSpeed?: "fast" | "normal" | "slow";
125
+ }
76
126
  /**
77
127
  * Options for initializing the CoBuy SDK
78
128
  */
@@ -138,6 +188,25 @@ export interface CoBuyInitOptions {
138
188
  */
139
189
  theme?: CoBuyThemeOptions;
140
190
  };
191
+ /**
192
+ * Optional performance tuning for SDK
193
+ *
194
+ * Fine-tune SDK behavior for your specific network conditions and UX preferences.
195
+ * All values have safe defaults optimized for most use cases.
196
+ *
197
+ * @example
198
+ * ```typescript
199
+ * CoBuy.init({
200
+ * merchantKey: 'pk_live_123',
201
+ * performance: {
202
+ * requestTimeout: 15000, // 15s timeout for fast networks
203
+ * maxRetries: 3, // 3 retries for flaky networks
204
+ * animationSpeed: 'fast' // Snappy animations
205
+ * }
206
+ * });
207
+ * ```
208
+ */
209
+ performance?: PerformanceConfig;
141
210
  }
142
211
  /**
143
212
  * Callback data structure for checkout events
@@ -259,6 +328,15 @@ export interface CheckoutRequestedEvent {
259
328
  groupId: string;
260
329
  productId: string;
261
330
  }
331
+ /**
332
+ * Fraud detection error details
333
+ */
334
+ export interface FraudDetectionError {
335
+ code: string;
336
+ message: string;
337
+ statusCode?: number;
338
+ context?: string;
339
+ }
262
340
  /**
263
341
  * Widget event callbacks for lifecycle events
264
342
  */
@@ -275,6 +353,10 @@ export interface WidgetEvents {
275
353
  * Called when widget encounters an error loading reward data
276
354
  */
277
355
  onError?: (_productId: string, _error: Error) => void;
356
+ /**
357
+ * Called when a request is blocked by fraud detection
358
+ */
359
+ onFraudDetected?: (_error: FraudDetectionError) => void;
278
360
  /**
279
361
  * Called when user clicks "Buy with CoBuy" button
280
362
  */
@@ -639,6 +721,148 @@ export interface InternalConfig {
639
721
  theme: CoBuyThemeOptions;
640
722
  debug: boolean;
641
723
  events?: WidgetEvents;
724
+ performance: {
725
+ requestTimeout: number;
726
+ maxRetries: number;
727
+ animationSpeed: "fast" | "normal" | "slow";
728
+ };
729
+ }
730
+ /**
731
+ * Group status enumeration
732
+ * Represents the current state of a collaborative buying group
733
+ */
734
+ export type GroupStatus = "active" | "pending" | "fulfilled" | "expired" | "cancelled";
735
+ /**
736
+ * Group member information
737
+ * Represents a participant in a collaborative buying group
738
+ */
739
+ export interface GroupMember {
740
+ /**
741
+ * Unique identifier for the member
742
+ */
743
+ id: string;
744
+ /**
745
+ * Session ID of the member
746
+ */
747
+ session_id: string;
748
+ /**
749
+ * Member's display name (if available)
750
+ */
751
+ name?: string;
752
+ /**
753
+ * Member's email (if available)
754
+ */
755
+ email?: string;
756
+ /**
757
+ * Member's phone (if available)
758
+ */
759
+ phone?: string;
760
+ /**
761
+ * Timestamp when member joined (ISO 8601)
762
+ */
763
+ joined_at: string;
764
+ /**
765
+ * Whether this member is the group creator
766
+ */
767
+ is_creator?: boolean;
768
+ /**
769
+ * Member's share/referral link (if applicable)
770
+ */
771
+ share_link?: string;
772
+ }
773
+ /**
774
+ * Group timeline/countdown information
775
+ * Tracks time-based milestones for a group
776
+ */
777
+ export interface GroupTimeline {
778
+ /**
779
+ * Current Unix timestamp in milliseconds
780
+ */
781
+ now: number;
782
+ /**
783
+ * Group expiry timestamp (ISO 8601)
784
+ */
785
+ expiry_at: string;
786
+ /**
787
+ * Seconds remaining until group expires
788
+ */
789
+ timeLeftSeconds: number;
790
+ /**
791
+ * Percentage of time remaining (0-100)
792
+ */
793
+ timeLeftPercent: number;
794
+ /**
795
+ * Whether the group has expired
796
+ */
797
+ isExpired: boolean;
798
+ /**
799
+ * Whether the group is about to expire (< 5 minutes)
800
+ */
801
+ isExpiring: boolean;
802
+ }
803
+ /**
804
+ * Group activity entry
805
+ * Represents an action taken within a group
806
+ */
807
+ export interface GroupActivity {
808
+ /**
809
+ * Activity type (join, share, fulfill, expire, etc)
810
+ */
811
+ type: "joined" | "shared" | "fulfilled" | "expired" | "cancelled" | "invited";
812
+ /**
813
+ * Human-readable description
814
+ */
815
+ description: string;
816
+ /**
817
+ * Timestamp of activity (ISO 8601)
818
+ */
819
+ timestamp: string;
820
+ /**
821
+ * Member ID who triggered the activity
822
+ */
823
+ actor_id?: string;
824
+ /**
825
+ * Additional metadata for the activity
826
+ */
827
+ metadata?: Record<string, unknown>;
828
+ }
829
+ /**
830
+ * Complete group information
831
+ * Represents all data about a collaborative buying group
832
+ */
833
+ export interface GroupInfo {
834
+ /**
835
+ * Group basic information
836
+ */
837
+ id: string;
838
+ name: string;
839
+ description?: string;
840
+ status: GroupStatus;
841
+ /**
842
+ * Participation tracking
843
+ */
844
+ participants_count: number;
845
+ max_participants: number;
846
+ members?: GroupMember[];
847
+ /**
848
+ * Campaign information
849
+ */
850
+ campaign_id: string;
851
+ campaign_name: string;
852
+ campaign_status?: string;
853
+ campaign_creative_name?: string;
854
+ /**
855
+ * Timeline and expiry
856
+ */
857
+ timeline: GroupTimeline;
858
+ /**
859
+ * Activity history
860
+ */
861
+ activities?: GroupActivity[];
862
+ /**
863
+ * Offline redemption details (if group is fulfilled)
864
+ */
865
+ offline_redemption?: OfflineRedemption;
642
866
  }
643
867
  /**
644
868
  * HTTP methods supported by the API client
@@ -665,6 +889,9 @@ export interface ApiResponse<T = unknown> {
665
889
  };
666
890
  success: boolean;
667
891
  }
892
+ /**
893
+ * API client configuration
894
+ */
668
895
  /**
669
896
  * API client configuration
670
897
  */
@@ -672,8 +899,10 @@ export interface ApiClientConfig {
672
899
  baseUrl: string;
673
900
  authStrategy: AuthStrategy;
674
901
  sessionId: string;
902
+ botdScore?: number;
675
903
  debug?: boolean;
676
904
  timeout?: number;
905
+ maxRetries?: number;
677
906
  }
678
907
  /**
679
908
  * Authentication strategy interface (imported from auth-strategy.ts)