@stackbe/sdk 0.9.4 → 0.10.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/dist/index.d.mts CHANGED
@@ -194,6 +194,12 @@ interface Subscription {
194
194
  pausedAt?: string | null;
195
195
  /** When the subscription will auto-resume (null = indefinite pause) */
196
196
  resumesAt?: string | null;
197
+ /** Number of consecutive failed payment attempts */
198
+ failedPaymentCount?: number;
199
+ /** Timestamp of most recent failed payment */
200
+ lastPaymentFailedAt?: string | null;
201
+ /** When access will be revoked if payment not recovered */
202
+ gracePeriodEndsAt?: string | null;
197
203
  createdAt: string;
198
204
  }
199
205
  interface TrialStatus {
@@ -210,6 +216,28 @@ interface TrialStatus {
210
216
  /** Whether the trial has converted to paid */
211
217
  hasConverted: boolean;
212
218
  }
219
+ interface DunningStatus {
220
+ /** Whether the subscription is past due */
221
+ isPastDue: boolean;
222
+ /** Whether the subscription is in grace period (past due but still has access) */
223
+ isInGracePeriod: boolean;
224
+ /** Number of consecutive failed payment attempts */
225
+ failedPaymentCount: number;
226
+ /** Timestamp of most recent failed payment */
227
+ lastPaymentFailedAt: string | null;
228
+ /** When access will be revoked if payment not recovered */
229
+ gracePeriodEndsAt: string | null;
230
+ /** Days until access is revoked (null if not in grace period) */
231
+ daysUntilAccessRevoked: number | null;
232
+ /** Days since payment failed */
233
+ daysSinceFailure: number | null;
234
+ /** Configured dunning email schedule (days after failure) */
235
+ dunningEmailSchedule: number[];
236
+ /** Which dunning emails have been sent (days) */
237
+ emailsSent: number[];
238
+ /** Whether the customer still has access (considering grace period) */
239
+ hasAccess: boolean;
240
+ }
213
241
  interface CustomerWithSubscription extends Customer {
214
242
  subscription?: Subscription;
215
243
  }
@@ -1240,6 +1268,72 @@ declare class SubscriptionsClient {
1240
1268
  * ```
1241
1269
  */
1242
1270
  endTrial(subscriptionId: string): Promise<Subscription>;
1271
+ /**
1272
+ * Get dunning/payment recovery status for a subscription.
1273
+ *
1274
+ * Shows if the subscription is past due, in grace period, and when access
1275
+ * will be revoked if payment isn't recovered.
1276
+ *
1277
+ * @example
1278
+ * ```typescript
1279
+ * const dunning = await stackbe.subscriptions.getDunningStatus('sub_123');
1280
+ *
1281
+ * if (dunning.isPastDue) {
1282
+ * console.log(`Payment failed ${dunning.daysSinceFailure} days ago`);
1283
+ *
1284
+ * if (dunning.isInGracePeriod) {
1285
+ * console.log(`Access ends in ${dunning.daysUntilAccessRevoked} days`);
1286
+ * }
1287
+ * }
1288
+ *
1289
+ * // Check if customer still has access
1290
+ * if (dunning.hasAccess) {
1291
+ * // Allow access
1292
+ * }
1293
+ * ```
1294
+ */
1295
+ getDunningStatus(subscriptionId: string): Promise<DunningStatus>;
1296
+ /**
1297
+ * List all past-due subscriptions.
1298
+ *
1299
+ * Useful for monitoring and recovery efforts.
1300
+ *
1301
+ * @example
1302
+ * ```typescript
1303
+ * // List all past-due subscriptions
1304
+ * const pastDue = await stackbe.subscriptions.listPastDue();
1305
+ *
1306
+ * // List subscriptions losing access within 3 days
1307
+ * const urgent = await stackbe.subscriptions.listPastDue({ gracePeriodExpiringSoon: 3 });
1308
+ *
1309
+ * for (const sub of urgent) {
1310
+ * console.log(`${sub.customer.email} loses access in ${sub.gracePeriodEndsAt}`);
1311
+ * }
1312
+ * ```
1313
+ */
1314
+ listPastDue(options?: {
1315
+ appId?: string;
1316
+ gracePeriodExpiringSoon?: number;
1317
+ }): Promise<Subscription[]>;
1318
+ /**
1319
+ * Check if a subscription still has access (considering grace period).
1320
+ *
1321
+ * Returns true if:
1322
+ * - Subscription is active
1323
+ * - Subscription is trialing
1324
+ * - Subscription is past_due but within grace period
1325
+ *
1326
+ * @example
1327
+ * ```typescript
1328
+ * const { hasAccess } = await stackbe.subscriptions.checkAccess('sub_123');
1329
+ * if (!hasAccess) {
1330
+ * // Show upgrade prompt or block feature
1331
+ * }
1332
+ * ```
1333
+ */
1334
+ checkAccess(subscriptionId: string): Promise<{
1335
+ hasAccess: boolean;
1336
+ }>;
1243
1337
  }
1244
1338
 
1245
1339
  interface AuthClientOptions {
@@ -2302,6 +2396,195 @@ declare class CouponsClient {
2302
2396
  delete(couponId: string): Promise<void>;
2303
2397
  }
2304
2398
 
2399
+ interface DashboardMetrics {
2400
+ revenue: {
2401
+ mrr: number;
2402
+ arpu: number;
2403
+ };
2404
+ subscriptions: {
2405
+ active: number;
2406
+ churnRate: number;
2407
+ };
2408
+ trials: {
2409
+ active: number;
2410
+ conversionRate: number;
2411
+ avgDays: number;
2412
+ };
2413
+ growth: {
2414
+ newSubscribers: number;
2415
+ churnedSubscribers: number;
2416
+ netGrowth: number;
2417
+ growthRate: number;
2418
+ };
2419
+ conversion: {
2420
+ rate: number;
2421
+ };
2422
+ api: {
2423
+ errorRate: number;
2424
+ avgResponseTime: number;
2425
+ };
2426
+ }
2427
+ interface MRRHistoryPoint {
2428
+ date: string;
2429
+ mrr: number;
2430
+ }
2431
+ interface RevenueByPlan {
2432
+ planId: string;
2433
+ planName: string;
2434
+ mrr: number;
2435
+ subscriberCount: number;
2436
+ percentage: number;
2437
+ }
2438
+ interface TrialMetrics {
2439
+ trialStarts: number;
2440
+ trialConversions: number;
2441
+ trialConversionRate: number;
2442
+ avgTrialDays: number;
2443
+ activeTrials: number;
2444
+ }
2445
+ interface GrowthMetrics {
2446
+ newSubscribers: number;
2447
+ churnedSubscribers: number;
2448
+ netGrowth: number;
2449
+ growthRate: number;
2450
+ }
2451
+ interface GrowthChartPoint {
2452
+ date: string;
2453
+ new: number;
2454
+ churned: number;
2455
+ net: number;
2456
+ }
2457
+ interface PlanMetrics {
2458
+ planId: string;
2459
+ planName: string;
2460
+ subscriberCount: number;
2461
+ percentage: number;
2462
+ priceCents: number;
2463
+ interval: string;
2464
+ }
2465
+ interface RequestCountPoint {
2466
+ date: string;
2467
+ count: number;
2468
+ }
2469
+ interface PopularEndpoint {
2470
+ endpoint: string;
2471
+ count: number;
2472
+ }
2473
+ interface PerformanceMetrics {
2474
+ errorRate: number;
2475
+ avgResponseTime: number;
2476
+ }
2477
+ interface FeatureUsagePoint {
2478
+ date: string;
2479
+ count: number;
2480
+ }
2481
+ interface AnalyticsFilterOptions {
2482
+ appId?: string;
2483
+ }
2484
+ interface TimeRangeOptions extends AnalyticsFilterOptions {
2485
+ days?: number;
2486
+ }
2487
+ /**
2488
+ * Analytics client for accessing business metrics
2489
+ *
2490
+ * @example
2491
+ * ```typescript
2492
+ * const stackbe = new StackBE({ apiKey: '...', appId: '...' });
2493
+ *
2494
+ * // Get full dashboard
2495
+ * const dashboard = await stackbe.analytics.getDashboard();
2496
+ *
2497
+ * // Get MRR history
2498
+ * const mrrHistory = await stackbe.analytics.getMRRHistory({ days: 30 });
2499
+ *
2500
+ * // Get revenue by plan
2501
+ * const revenueByPlan = await stackbe.analytics.getRevenueByPlan();
2502
+ *
2503
+ * // Get trial metrics
2504
+ * const trials = await stackbe.analytics.getTrialMetrics({ days: 30 });
2505
+ *
2506
+ * // Get growth chart
2507
+ * const growth = await stackbe.analytics.getGrowthChart({ days: 30 });
2508
+ * ```
2509
+ */
2510
+ declare class AnalyticsClient {
2511
+ private readonly http;
2512
+ constructor(http: HttpClient);
2513
+ /**
2514
+ * Get the full analytics dashboard with all key metrics
2515
+ */
2516
+ getDashboard(options?: AnalyticsFilterOptions): Promise<DashboardMetrics>;
2517
+ /**
2518
+ * Get current Monthly Recurring Revenue
2519
+ */
2520
+ getMRR(options?: AnalyticsFilterOptions): Promise<{
2521
+ mrr: number;
2522
+ }>;
2523
+ /**
2524
+ * Get MRR history over time for trend analysis
2525
+ */
2526
+ getMRRHistory(options?: TimeRangeOptions): Promise<MRRHistoryPoint[]>;
2527
+ /**
2528
+ * Get revenue breakdown by plan
2529
+ */
2530
+ getRevenueByPlan(options?: AnalyticsFilterOptions): Promise<RevenueByPlan[]>;
2531
+ /**
2532
+ * Get Average Revenue Per User
2533
+ */
2534
+ getARPU(options?: AnalyticsFilterOptions): Promise<{
2535
+ arpu: number;
2536
+ }>;
2537
+ /**
2538
+ * Get subscription metrics (active count, churn rate)
2539
+ */
2540
+ getSubscriptionMetrics(options?: TimeRangeOptions): Promise<{
2541
+ active: number;
2542
+ churnRate: number;
2543
+ }>;
2544
+ /**
2545
+ * Get subscriber distribution by plan
2546
+ */
2547
+ getSubscribersByPlan(options?: AnalyticsFilterOptions): Promise<PlanMetrics[]>;
2548
+ /**
2549
+ * Get trial metrics (starts, conversions, conversion rate)
2550
+ * Useful for freemium and trial-based pricing models
2551
+ */
2552
+ getTrialMetrics(options?: TimeRangeOptions): Promise<TrialMetrics>;
2553
+ /**
2554
+ * Get growth metrics (new vs churned subscribers)
2555
+ */
2556
+ getGrowthMetrics(options?: TimeRangeOptions): Promise<GrowthMetrics>;
2557
+ /**
2558
+ * Get growth chart data (daily new vs churned for charting)
2559
+ */
2560
+ getGrowthChart(options?: TimeRangeOptions): Promise<GrowthChartPoint[]>;
2561
+ /**
2562
+ * Get checkout conversion rate
2563
+ */
2564
+ getConversionRate(options?: TimeRangeOptions): Promise<{
2565
+ rate: number;
2566
+ period: number;
2567
+ }>;
2568
+ /**
2569
+ * Get API request counts over time
2570
+ */
2571
+ getRequestCounts(options?: TimeRangeOptions): Promise<RequestCountPoint[]>;
2572
+ /**
2573
+ * Get most popular API endpoints
2574
+ */
2575
+ getPopularEndpoints(options?: AnalyticsFilterOptions & {
2576
+ limit?: number;
2577
+ }): Promise<PopularEndpoint[]>;
2578
+ /**
2579
+ * Get API performance metrics (error rate, response time)
2580
+ */
2581
+ getPerformance(options?: TimeRangeOptions): Promise<PerformanceMetrics>;
2582
+ /**
2583
+ * Get feature usage over time (entitlement checks)
2584
+ */
2585
+ getFeatureUsage(options?: TimeRangeOptions): Promise<FeatureUsagePoint[]>;
2586
+ }
2587
+
2305
2588
  declare class StackBE {
2306
2589
  private http;
2307
2590
  private appId;
@@ -2331,6 +2614,8 @@ declare class StackBE {
2331
2614
  readonly earlyAccess: EarlyAccessClient;
2332
2615
  /** Coupon/promo code management */
2333
2616
  readonly coupons: CouponsClient;
2617
+ /** Analytics and business metrics */
2618
+ readonly analytics: AnalyticsClient;
2334
2619
  /**
2335
2620
  * Create a new StackBE client.
2336
2621
  *
@@ -2431,4 +2716,4 @@ declare class StackBE {
2431
2716
  }): (req: any, res: any, next: any) => Promise<any>;
2432
2717
  }
2433
2718
 
2434
- export { type AddMemberOptions, type AffiliateCommission, type AffiliateCommissionsResponse, type AffiliateEnrollment, type AffiliateInfo, type AffiliateStats, AffiliatesClient, type AnyWebhookEvent, AuthClient, type BillingPortalSession, type CancelSubscriptionOptions, type CancelSubscriptionResponse, type CheckEntitlementResponse, type CheckUsageResponse, CheckoutClient, type CheckoutSessionResponse, type Coupon, type CouponDiscountType, type CouponDuration, CouponsClient, type CreateCheckoutOptions, type CreateCouponOptions, type CreateCustomerOptions, type CreateEarlyAccessSignupOptions, type CreateFeatureRequestOptions, type CreateOrganizationOptions, type Customer, type CustomerCreatedEvent, type CustomerFeatureActivity, type CustomerInvoice, type CustomerInvoicesResponse, type CustomerPaymentMethod, type CustomerSubscriptionHistory, type CustomerSubscriptionHistoryResponse, type CustomerUpdatedEvent, type CustomerUsageResponse, type CustomerWebhookPayload, type CustomerWithSubscription, CustomersClient, EarlyAccessClient, type EarlyAccessSignup, type EarlyAccessSignupListResponse, type EnrollOptions, EntitlementsClient, type EntitlementsResponse, type FeatureRequest, type FeatureRequestComment, type FeatureRequestImage, type FeatureRequestListResponse, FeatureRequestsClient, type GetSubscriptionOptions, type InterestedCustomer, type InterestedCustomersResponse, type InviteMemberOptions, type ListEarlyAccessOptions, type ListFeatureRequestsOptions, type ListPlansOptions, type ListProductsOptions, type MagicLinkOptions, type MagicLinkResponse, type Organization, type OrganizationInvite, type OrganizationMember, OrganizationsClient, type PaymentFailedEvent, type PaymentSucceededEvent, type PaymentWebhookPayload, type Plan, PlansClient, type Product, ProductsClient, type SessionResponse, StackBE, type StackBEConfig, StackBEError, type StackBEErrorCode, type StackBEErrorResponse, type Subscription, type SubscriptionCancelledEvent, type SubscriptionCreatedEvent, type SubscriptionPlan, type SubscriptionRenewedEvent, type SubscriptionUpdatedEvent, type SubscriptionWebhookPayload, type SubscriptionWithPlan, SubscriptionsClient, type TrackReferralResponse, type TrackUsageOptions, type TrackUsageResponse, type TrialEndedEvent, type TrialStartedEvent, type TrialStatus, type UpcomingInvoice, type UpdateCouponOptions, type UpdateCustomerOptions, type UpdateOrganizationOptions, type UpdateSubscriptionOptions, UsageClient, type UsageMetric, type ValidateCouponResult, type VerifyTokenResponse, type WebhookEvent, type WebhookEventType };
2719
+ export { type AddMemberOptions, type AffiliateCommission, type AffiliateCommissionsResponse, type AffiliateEnrollment, type AffiliateInfo, type AffiliateStats, AffiliatesClient, AnalyticsClient, type AnalyticsFilterOptions, type AnyWebhookEvent, AuthClient, type BillingPortalSession, type CancelSubscriptionOptions, type CancelSubscriptionResponse, type CheckEntitlementResponse, type CheckUsageResponse, CheckoutClient, type CheckoutSessionResponse, type Coupon, type CouponDiscountType, type CouponDuration, CouponsClient, type CreateCheckoutOptions, type CreateCouponOptions, type CreateCustomerOptions, type CreateEarlyAccessSignupOptions, type CreateFeatureRequestOptions, type CreateOrganizationOptions, type Customer, type CustomerCreatedEvent, type CustomerFeatureActivity, type CustomerInvoice, type CustomerInvoicesResponse, type CustomerPaymentMethod, type CustomerSubscriptionHistory, type CustomerSubscriptionHistoryResponse, type CustomerUpdatedEvent, type CustomerUsageResponse, type CustomerWebhookPayload, type CustomerWithSubscription, CustomersClient, type DashboardMetrics, type DunningStatus, EarlyAccessClient, type EarlyAccessSignup, type EarlyAccessSignupListResponse, type EnrollOptions, EntitlementsClient, type EntitlementsResponse, type FeatureRequest, type FeatureRequestComment, type FeatureRequestImage, type FeatureRequestListResponse, FeatureRequestsClient, type FeatureUsagePoint, type GetSubscriptionOptions, type GrowthChartPoint, type GrowthMetrics, type InterestedCustomer, type InterestedCustomersResponse, type InviteMemberOptions, type ListEarlyAccessOptions, type ListFeatureRequestsOptions, type ListPlansOptions, type ListProductsOptions, type MRRHistoryPoint, type MagicLinkOptions, type MagicLinkResponse, type Organization, type OrganizationInvite, type OrganizationMember, OrganizationsClient, type PaymentFailedEvent, type PaymentSucceededEvent, type PaymentWebhookPayload, type PerformanceMetrics, type Plan, type PlanMetrics, PlansClient, type PopularEndpoint, type Product, ProductsClient, type RequestCountPoint, type RevenueByPlan, type SessionResponse, StackBE, type StackBEConfig, StackBEError, type StackBEErrorCode, type StackBEErrorResponse, type Subscription, type SubscriptionCancelledEvent, type SubscriptionCreatedEvent, type SubscriptionPlan, type SubscriptionRenewedEvent, type SubscriptionUpdatedEvent, type SubscriptionWebhookPayload, type SubscriptionWithPlan, SubscriptionsClient, type TimeRangeOptions, type TrackReferralResponse, type TrackUsageOptions, type TrackUsageResponse, type TrialEndedEvent, type TrialMetrics, type TrialStartedEvent, type TrialStatus, type UpcomingInvoice, type UpdateCouponOptions, type UpdateCustomerOptions, type UpdateOrganizationOptions, type UpdateSubscriptionOptions, UsageClient, type UsageMetric, type ValidateCouponResult, type VerifyTokenResponse, type WebhookEvent, type WebhookEventType };
package/dist/index.d.ts CHANGED
@@ -194,6 +194,12 @@ interface Subscription {
194
194
  pausedAt?: string | null;
195
195
  /** When the subscription will auto-resume (null = indefinite pause) */
196
196
  resumesAt?: string | null;
197
+ /** Number of consecutive failed payment attempts */
198
+ failedPaymentCount?: number;
199
+ /** Timestamp of most recent failed payment */
200
+ lastPaymentFailedAt?: string | null;
201
+ /** When access will be revoked if payment not recovered */
202
+ gracePeriodEndsAt?: string | null;
197
203
  createdAt: string;
198
204
  }
199
205
  interface TrialStatus {
@@ -210,6 +216,28 @@ interface TrialStatus {
210
216
  /** Whether the trial has converted to paid */
211
217
  hasConverted: boolean;
212
218
  }
219
+ interface DunningStatus {
220
+ /** Whether the subscription is past due */
221
+ isPastDue: boolean;
222
+ /** Whether the subscription is in grace period (past due but still has access) */
223
+ isInGracePeriod: boolean;
224
+ /** Number of consecutive failed payment attempts */
225
+ failedPaymentCount: number;
226
+ /** Timestamp of most recent failed payment */
227
+ lastPaymentFailedAt: string | null;
228
+ /** When access will be revoked if payment not recovered */
229
+ gracePeriodEndsAt: string | null;
230
+ /** Days until access is revoked (null if not in grace period) */
231
+ daysUntilAccessRevoked: number | null;
232
+ /** Days since payment failed */
233
+ daysSinceFailure: number | null;
234
+ /** Configured dunning email schedule (days after failure) */
235
+ dunningEmailSchedule: number[];
236
+ /** Which dunning emails have been sent (days) */
237
+ emailsSent: number[];
238
+ /** Whether the customer still has access (considering grace period) */
239
+ hasAccess: boolean;
240
+ }
213
241
  interface CustomerWithSubscription extends Customer {
214
242
  subscription?: Subscription;
215
243
  }
@@ -1240,6 +1268,72 @@ declare class SubscriptionsClient {
1240
1268
  * ```
1241
1269
  */
1242
1270
  endTrial(subscriptionId: string): Promise<Subscription>;
1271
+ /**
1272
+ * Get dunning/payment recovery status for a subscription.
1273
+ *
1274
+ * Shows if the subscription is past due, in grace period, and when access
1275
+ * will be revoked if payment isn't recovered.
1276
+ *
1277
+ * @example
1278
+ * ```typescript
1279
+ * const dunning = await stackbe.subscriptions.getDunningStatus('sub_123');
1280
+ *
1281
+ * if (dunning.isPastDue) {
1282
+ * console.log(`Payment failed ${dunning.daysSinceFailure} days ago`);
1283
+ *
1284
+ * if (dunning.isInGracePeriod) {
1285
+ * console.log(`Access ends in ${dunning.daysUntilAccessRevoked} days`);
1286
+ * }
1287
+ * }
1288
+ *
1289
+ * // Check if customer still has access
1290
+ * if (dunning.hasAccess) {
1291
+ * // Allow access
1292
+ * }
1293
+ * ```
1294
+ */
1295
+ getDunningStatus(subscriptionId: string): Promise<DunningStatus>;
1296
+ /**
1297
+ * List all past-due subscriptions.
1298
+ *
1299
+ * Useful for monitoring and recovery efforts.
1300
+ *
1301
+ * @example
1302
+ * ```typescript
1303
+ * // List all past-due subscriptions
1304
+ * const pastDue = await stackbe.subscriptions.listPastDue();
1305
+ *
1306
+ * // List subscriptions losing access within 3 days
1307
+ * const urgent = await stackbe.subscriptions.listPastDue({ gracePeriodExpiringSoon: 3 });
1308
+ *
1309
+ * for (const sub of urgent) {
1310
+ * console.log(`${sub.customer.email} loses access in ${sub.gracePeriodEndsAt}`);
1311
+ * }
1312
+ * ```
1313
+ */
1314
+ listPastDue(options?: {
1315
+ appId?: string;
1316
+ gracePeriodExpiringSoon?: number;
1317
+ }): Promise<Subscription[]>;
1318
+ /**
1319
+ * Check if a subscription still has access (considering grace period).
1320
+ *
1321
+ * Returns true if:
1322
+ * - Subscription is active
1323
+ * - Subscription is trialing
1324
+ * - Subscription is past_due but within grace period
1325
+ *
1326
+ * @example
1327
+ * ```typescript
1328
+ * const { hasAccess } = await stackbe.subscriptions.checkAccess('sub_123');
1329
+ * if (!hasAccess) {
1330
+ * // Show upgrade prompt or block feature
1331
+ * }
1332
+ * ```
1333
+ */
1334
+ checkAccess(subscriptionId: string): Promise<{
1335
+ hasAccess: boolean;
1336
+ }>;
1243
1337
  }
1244
1338
 
1245
1339
  interface AuthClientOptions {
@@ -2302,6 +2396,195 @@ declare class CouponsClient {
2302
2396
  delete(couponId: string): Promise<void>;
2303
2397
  }
2304
2398
 
2399
+ interface DashboardMetrics {
2400
+ revenue: {
2401
+ mrr: number;
2402
+ arpu: number;
2403
+ };
2404
+ subscriptions: {
2405
+ active: number;
2406
+ churnRate: number;
2407
+ };
2408
+ trials: {
2409
+ active: number;
2410
+ conversionRate: number;
2411
+ avgDays: number;
2412
+ };
2413
+ growth: {
2414
+ newSubscribers: number;
2415
+ churnedSubscribers: number;
2416
+ netGrowth: number;
2417
+ growthRate: number;
2418
+ };
2419
+ conversion: {
2420
+ rate: number;
2421
+ };
2422
+ api: {
2423
+ errorRate: number;
2424
+ avgResponseTime: number;
2425
+ };
2426
+ }
2427
+ interface MRRHistoryPoint {
2428
+ date: string;
2429
+ mrr: number;
2430
+ }
2431
+ interface RevenueByPlan {
2432
+ planId: string;
2433
+ planName: string;
2434
+ mrr: number;
2435
+ subscriberCount: number;
2436
+ percentage: number;
2437
+ }
2438
+ interface TrialMetrics {
2439
+ trialStarts: number;
2440
+ trialConversions: number;
2441
+ trialConversionRate: number;
2442
+ avgTrialDays: number;
2443
+ activeTrials: number;
2444
+ }
2445
+ interface GrowthMetrics {
2446
+ newSubscribers: number;
2447
+ churnedSubscribers: number;
2448
+ netGrowth: number;
2449
+ growthRate: number;
2450
+ }
2451
+ interface GrowthChartPoint {
2452
+ date: string;
2453
+ new: number;
2454
+ churned: number;
2455
+ net: number;
2456
+ }
2457
+ interface PlanMetrics {
2458
+ planId: string;
2459
+ planName: string;
2460
+ subscriberCount: number;
2461
+ percentage: number;
2462
+ priceCents: number;
2463
+ interval: string;
2464
+ }
2465
+ interface RequestCountPoint {
2466
+ date: string;
2467
+ count: number;
2468
+ }
2469
+ interface PopularEndpoint {
2470
+ endpoint: string;
2471
+ count: number;
2472
+ }
2473
+ interface PerformanceMetrics {
2474
+ errorRate: number;
2475
+ avgResponseTime: number;
2476
+ }
2477
+ interface FeatureUsagePoint {
2478
+ date: string;
2479
+ count: number;
2480
+ }
2481
+ interface AnalyticsFilterOptions {
2482
+ appId?: string;
2483
+ }
2484
+ interface TimeRangeOptions extends AnalyticsFilterOptions {
2485
+ days?: number;
2486
+ }
2487
+ /**
2488
+ * Analytics client for accessing business metrics
2489
+ *
2490
+ * @example
2491
+ * ```typescript
2492
+ * const stackbe = new StackBE({ apiKey: '...', appId: '...' });
2493
+ *
2494
+ * // Get full dashboard
2495
+ * const dashboard = await stackbe.analytics.getDashboard();
2496
+ *
2497
+ * // Get MRR history
2498
+ * const mrrHistory = await stackbe.analytics.getMRRHistory({ days: 30 });
2499
+ *
2500
+ * // Get revenue by plan
2501
+ * const revenueByPlan = await stackbe.analytics.getRevenueByPlan();
2502
+ *
2503
+ * // Get trial metrics
2504
+ * const trials = await stackbe.analytics.getTrialMetrics({ days: 30 });
2505
+ *
2506
+ * // Get growth chart
2507
+ * const growth = await stackbe.analytics.getGrowthChart({ days: 30 });
2508
+ * ```
2509
+ */
2510
+ declare class AnalyticsClient {
2511
+ private readonly http;
2512
+ constructor(http: HttpClient);
2513
+ /**
2514
+ * Get the full analytics dashboard with all key metrics
2515
+ */
2516
+ getDashboard(options?: AnalyticsFilterOptions): Promise<DashboardMetrics>;
2517
+ /**
2518
+ * Get current Monthly Recurring Revenue
2519
+ */
2520
+ getMRR(options?: AnalyticsFilterOptions): Promise<{
2521
+ mrr: number;
2522
+ }>;
2523
+ /**
2524
+ * Get MRR history over time for trend analysis
2525
+ */
2526
+ getMRRHistory(options?: TimeRangeOptions): Promise<MRRHistoryPoint[]>;
2527
+ /**
2528
+ * Get revenue breakdown by plan
2529
+ */
2530
+ getRevenueByPlan(options?: AnalyticsFilterOptions): Promise<RevenueByPlan[]>;
2531
+ /**
2532
+ * Get Average Revenue Per User
2533
+ */
2534
+ getARPU(options?: AnalyticsFilterOptions): Promise<{
2535
+ arpu: number;
2536
+ }>;
2537
+ /**
2538
+ * Get subscription metrics (active count, churn rate)
2539
+ */
2540
+ getSubscriptionMetrics(options?: TimeRangeOptions): Promise<{
2541
+ active: number;
2542
+ churnRate: number;
2543
+ }>;
2544
+ /**
2545
+ * Get subscriber distribution by plan
2546
+ */
2547
+ getSubscribersByPlan(options?: AnalyticsFilterOptions): Promise<PlanMetrics[]>;
2548
+ /**
2549
+ * Get trial metrics (starts, conversions, conversion rate)
2550
+ * Useful for freemium and trial-based pricing models
2551
+ */
2552
+ getTrialMetrics(options?: TimeRangeOptions): Promise<TrialMetrics>;
2553
+ /**
2554
+ * Get growth metrics (new vs churned subscribers)
2555
+ */
2556
+ getGrowthMetrics(options?: TimeRangeOptions): Promise<GrowthMetrics>;
2557
+ /**
2558
+ * Get growth chart data (daily new vs churned for charting)
2559
+ */
2560
+ getGrowthChart(options?: TimeRangeOptions): Promise<GrowthChartPoint[]>;
2561
+ /**
2562
+ * Get checkout conversion rate
2563
+ */
2564
+ getConversionRate(options?: TimeRangeOptions): Promise<{
2565
+ rate: number;
2566
+ period: number;
2567
+ }>;
2568
+ /**
2569
+ * Get API request counts over time
2570
+ */
2571
+ getRequestCounts(options?: TimeRangeOptions): Promise<RequestCountPoint[]>;
2572
+ /**
2573
+ * Get most popular API endpoints
2574
+ */
2575
+ getPopularEndpoints(options?: AnalyticsFilterOptions & {
2576
+ limit?: number;
2577
+ }): Promise<PopularEndpoint[]>;
2578
+ /**
2579
+ * Get API performance metrics (error rate, response time)
2580
+ */
2581
+ getPerformance(options?: TimeRangeOptions): Promise<PerformanceMetrics>;
2582
+ /**
2583
+ * Get feature usage over time (entitlement checks)
2584
+ */
2585
+ getFeatureUsage(options?: TimeRangeOptions): Promise<FeatureUsagePoint[]>;
2586
+ }
2587
+
2305
2588
  declare class StackBE {
2306
2589
  private http;
2307
2590
  private appId;
@@ -2331,6 +2614,8 @@ declare class StackBE {
2331
2614
  readonly earlyAccess: EarlyAccessClient;
2332
2615
  /** Coupon/promo code management */
2333
2616
  readonly coupons: CouponsClient;
2617
+ /** Analytics and business metrics */
2618
+ readonly analytics: AnalyticsClient;
2334
2619
  /**
2335
2620
  * Create a new StackBE client.
2336
2621
  *
@@ -2431,4 +2716,4 @@ declare class StackBE {
2431
2716
  }): (req: any, res: any, next: any) => Promise<any>;
2432
2717
  }
2433
2718
 
2434
- export { type AddMemberOptions, type AffiliateCommission, type AffiliateCommissionsResponse, type AffiliateEnrollment, type AffiliateInfo, type AffiliateStats, AffiliatesClient, type AnyWebhookEvent, AuthClient, type BillingPortalSession, type CancelSubscriptionOptions, type CancelSubscriptionResponse, type CheckEntitlementResponse, type CheckUsageResponse, CheckoutClient, type CheckoutSessionResponse, type Coupon, type CouponDiscountType, type CouponDuration, CouponsClient, type CreateCheckoutOptions, type CreateCouponOptions, type CreateCustomerOptions, type CreateEarlyAccessSignupOptions, type CreateFeatureRequestOptions, type CreateOrganizationOptions, type Customer, type CustomerCreatedEvent, type CustomerFeatureActivity, type CustomerInvoice, type CustomerInvoicesResponse, type CustomerPaymentMethod, type CustomerSubscriptionHistory, type CustomerSubscriptionHistoryResponse, type CustomerUpdatedEvent, type CustomerUsageResponse, type CustomerWebhookPayload, type CustomerWithSubscription, CustomersClient, EarlyAccessClient, type EarlyAccessSignup, type EarlyAccessSignupListResponse, type EnrollOptions, EntitlementsClient, type EntitlementsResponse, type FeatureRequest, type FeatureRequestComment, type FeatureRequestImage, type FeatureRequestListResponse, FeatureRequestsClient, type GetSubscriptionOptions, type InterestedCustomer, type InterestedCustomersResponse, type InviteMemberOptions, type ListEarlyAccessOptions, type ListFeatureRequestsOptions, type ListPlansOptions, type ListProductsOptions, type MagicLinkOptions, type MagicLinkResponse, type Organization, type OrganizationInvite, type OrganizationMember, OrganizationsClient, type PaymentFailedEvent, type PaymentSucceededEvent, type PaymentWebhookPayload, type Plan, PlansClient, type Product, ProductsClient, type SessionResponse, StackBE, type StackBEConfig, StackBEError, type StackBEErrorCode, type StackBEErrorResponse, type Subscription, type SubscriptionCancelledEvent, type SubscriptionCreatedEvent, type SubscriptionPlan, type SubscriptionRenewedEvent, type SubscriptionUpdatedEvent, type SubscriptionWebhookPayload, type SubscriptionWithPlan, SubscriptionsClient, type TrackReferralResponse, type TrackUsageOptions, type TrackUsageResponse, type TrialEndedEvent, type TrialStartedEvent, type TrialStatus, type UpcomingInvoice, type UpdateCouponOptions, type UpdateCustomerOptions, type UpdateOrganizationOptions, type UpdateSubscriptionOptions, UsageClient, type UsageMetric, type ValidateCouponResult, type VerifyTokenResponse, type WebhookEvent, type WebhookEventType };
2719
+ export { type AddMemberOptions, type AffiliateCommission, type AffiliateCommissionsResponse, type AffiliateEnrollment, type AffiliateInfo, type AffiliateStats, AffiliatesClient, AnalyticsClient, type AnalyticsFilterOptions, type AnyWebhookEvent, AuthClient, type BillingPortalSession, type CancelSubscriptionOptions, type CancelSubscriptionResponse, type CheckEntitlementResponse, type CheckUsageResponse, CheckoutClient, type CheckoutSessionResponse, type Coupon, type CouponDiscountType, type CouponDuration, CouponsClient, type CreateCheckoutOptions, type CreateCouponOptions, type CreateCustomerOptions, type CreateEarlyAccessSignupOptions, type CreateFeatureRequestOptions, type CreateOrganizationOptions, type Customer, type CustomerCreatedEvent, type CustomerFeatureActivity, type CustomerInvoice, type CustomerInvoicesResponse, type CustomerPaymentMethod, type CustomerSubscriptionHistory, type CustomerSubscriptionHistoryResponse, type CustomerUpdatedEvent, type CustomerUsageResponse, type CustomerWebhookPayload, type CustomerWithSubscription, CustomersClient, type DashboardMetrics, type DunningStatus, EarlyAccessClient, type EarlyAccessSignup, type EarlyAccessSignupListResponse, type EnrollOptions, EntitlementsClient, type EntitlementsResponse, type FeatureRequest, type FeatureRequestComment, type FeatureRequestImage, type FeatureRequestListResponse, FeatureRequestsClient, type FeatureUsagePoint, type GetSubscriptionOptions, type GrowthChartPoint, type GrowthMetrics, type InterestedCustomer, type InterestedCustomersResponse, type InviteMemberOptions, type ListEarlyAccessOptions, type ListFeatureRequestsOptions, type ListPlansOptions, type ListProductsOptions, type MRRHistoryPoint, type MagicLinkOptions, type MagicLinkResponse, type Organization, type OrganizationInvite, type OrganizationMember, OrganizationsClient, type PaymentFailedEvent, type PaymentSucceededEvent, type PaymentWebhookPayload, type PerformanceMetrics, type Plan, type PlanMetrics, PlansClient, type PopularEndpoint, type Product, ProductsClient, type RequestCountPoint, type RevenueByPlan, type SessionResponse, StackBE, type StackBEConfig, StackBEError, type StackBEErrorCode, type StackBEErrorResponse, type Subscription, type SubscriptionCancelledEvent, type SubscriptionCreatedEvent, type SubscriptionPlan, type SubscriptionRenewedEvent, type SubscriptionUpdatedEvent, type SubscriptionWebhookPayload, type SubscriptionWithPlan, SubscriptionsClient, type TimeRangeOptions, type TrackReferralResponse, type TrackUsageOptions, type TrackUsageResponse, type TrialEndedEvent, type TrialMetrics, type TrialStartedEvent, type TrialStatus, type UpcomingInvoice, type UpdateCouponOptions, type UpdateCustomerOptions, type UpdateOrganizationOptions, type UpdateSubscriptionOptions, UsageClient, type UsageMetric, type ValidateCouponResult, type VerifyTokenResponse, type WebhookEvent, type WebhookEventType };
package/dist/index.js CHANGED
@@ -21,6 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
23
  AffiliatesClient: () => AffiliatesClient,
24
+ AnalyticsClient: () => AnalyticsClient,
24
25
  AuthClient: () => AuthClient,
25
26
  CheckoutClient: () => CheckoutClient,
26
27
  CouponsClient: () => CouponsClient,
@@ -1086,6 +1087,87 @@ var SubscriptionsClient = class {
1086
1087
  `/v1/subscriptions/${subscriptionId}/trial/end`
1087
1088
  );
1088
1089
  }
1090
+ // ============================================
1091
+ // Dunning / Payment Recovery Methods
1092
+ // ============================================
1093
+ /**
1094
+ * Get dunning/payment recovery status for a subscription.
1095
+ *
1096
+ * Shows if the subscription is past due, in grace period, and when access
1097
+ * will be revoked if payment isn't recovered.
1098
+ *
1099
+ * @example
1100
+ * ```typescript
1101
+ * const dunning = await stackbe.subscriptions.getDunningStatus('sub_123');
1102
+ *
1103
+ * if (dunning.isPastDue) {
1104
+ * console.log(`Payment failed ${dunning.daysSinceFailure} days ago`);
1105
+ *
1106
+ * if (dunning.isInGracePeriod) {
1107
+ * console.log(`Access ends in ${dunning.daysUntilAccessRevoked} days`);
1108
+ * }
1109
+ * }
1110
+ *
1111
+ * // Check if customer still has access
1112
+ * if (dunning.hasAccess) {
1113
+ * // Allow access
1114
+ * }
1115
+ * ```
1116
+ */
1117
+ async getDunningStatus(subscriptionId) {
1118
+ return this.http.get(
1119
+ `/v1/subscriptions/${subscriptionId}/dunning`
1120
+ );
1121
+ }
1122
+ /**
1123
+ * List all past-due subscriptions.
1124
+ *
1125
+ * Useful for monitoring and recovery efforts.
1126
+ *
1127
+ * @example
1128
+ * ```typescript
1129
+ * // List all past-due subscriptions
1130
+ * const pastDue = await stackbe.subscriptions.listPastDue();
1131
+ *
1132
+ * // List subscriptions losing access within 3 days
1133
+ * const urgent = await stackbe.subscriptions.listPastDue({ gracePeriodExpiringSoon: 3 });
1134
+ *
1135
+ * for (const sub of urgent) {
1136
+ * console.log(`${sub.customer.email} loses access in ${sub.gracePeriodEndsAt}`);
1137
+ * }
1138
+ * ```
1139
+ */
1140
+ async listPastDue(options) {
1141
+ const params = new URLSearchParams();
1142
+ if (options?.appId) params.set("appId", options.appId);
1143
+ if (options?.gracePeriodExpiringSoon) {
1144
+ params.set("gracePeriodExpiringSoon", String(options.gracePeriodExpiringSoon));
1145
+ }
1146
+ const query = params.toString();
1147
+ const path = `/v1/subscriptions/past-due${query ? `?${query}` : ""}`;
1148
+ return this.http.get(path);
1149
+ }
1150
+ /**
1151
+ * Check if a subscription still has access (considering grace period).
1152
+ *
1153
+ * Returns true if:
1154
+ * - Subscription is active
1155
+ * - Subscription is trialing
1156
+ * - Subscription is past_due but within grace period
1157
+ *
1158
+ * @example
1159
+ * ```typescript
1160
+ * const { hasAccess } = await stackbe.subscriptions.checkAccess('sub_123');
1161
+ * if (!hasAccess) {
1162
+ * // Show upgrade prompt or block feature
1163
+ * }
1164
+ * ```
1165
+ */
1166
+ async checkAccess(subscriptionId) {
1167
+ return this.http.get(
1168
+ `/v1/subscriptions/${subscriptionId}/has-access`
1169
+ );
1170
+ }
1089
1171
  };
1090
1172
 
1091
1173
  // src/auth.ts
@@ -2196,6 +2278,159 @@ var CouponsClient = class {
2196
2278
  }
2197
2279
  };
2198
2280
 
2281
+ // src/analytics.ts
2282
+ var AnalyticsClient = class {
2283
+ constructor(http) {
2284
+ this.http = http;
2285
+ }
2286
+ /**
2287
+ * Get the full analytics dashboard with all key metrics
2288
+ */
2289
+ async getDashboard(options) {
2290
+ const params = new URLSearchParams();
2291
+ if (options?.appId) params.append("appId", options.appId);
2292
+ const query = params.toString();
2293
+ return this.http.get(`/v1/analytics/dashboard${query ? `?${query}` : ""}`);
2294
+ }
2295
+ /**
2296
+ * Get current Monthly Recurring Revenue
2297
+ */
2298
+ async getMRR(options) {
2299
+ const params = new URLSearchParams();
2300
+ if (options?.appId) params.append("appId", options.appId);
2301
+ const query = params.toString();
2302
+ return this.http.get(`/v1/analytics/revenue/mrr${query ? `?${query}` : ""}`);
2303
+ }
2304
+ /**
2305
+ * Get MRR history over time for trend analysis
2306
+ */
2307
+ async getMRRHistory(options) {
2308
+ const params = new URLSearchParams();
2309
+ if (options?.appId) params.append("appId", options.appId);
2310
+ if (options?.days) params.append("days", options.days.toString());
2311
+ const query = params.toString();
2312
+ return this.http.get(`/v1/analytics/revenue/history${query ? `?${query}` : ""}`);
2313
+ }
2314
+ /**
2315
+ * Get revenue breakdown by plan
2316
+ */
2317
+ async getRevenueByPlan(options) {
2318
+ const params = new URLSearchParams();
2319
+ if (options?.appId) params.append("appId", options.appId);
2320
+ const query = params.toString();
2321
+ return this.http.get(`/v1/analytics/revenue/by-plan${query ? `?${query}` : ""}`);
2322
+ }
2323
+ /**
2324
+ * Get Average Revenue Per User
2325
+ */
2326
+ async getARPU(options) {
2327
+ const params = new URLSearchParams();
2328
+ if (options?.appId) params.append("appId", options.appId);
2329
+ const query = params.toString();
2330
+ return this.http.get(`/v1/analytics/revenue/arpu${query ? `?${query}` : ""}`);
2331
+ }
2332
+ /**
2333
+ * Get subscription metrics (active count, churn rate)
2334
+ */
2335
+ async getSubscriptionMetrics(options) {
2336
+ const params = new URLSearchParams();
2337
+ if (options?.appId) params.append("appId", options.appId);
2338
+ if (options?.days) params.append("days", options.days.toString());
2339
+ const query = params.toString();
2340
+ return this.http.get(`/v1/analytics/subscriptions/metrics${query ? `?${query}` : ""}`);
2341
+ }
2342
+ /**
2343
+ * Get subscriber distribution by plan
2344
+ */
2345
+ async getSubscribersByPlan(options) {
2346
+ const params = new URLSearchParams();
2347
+ if (options?.appId) params.append("appId", options.appId);
2348
+ const query = params.toString();
2349
+ return this.http.get(`/v1/analytics/subscriptions/by-plan${query ? `?${query}` : ""}`);
2350
+ }
2351
+ /**
2352
+ * Get trial metrics (starts, conversions, conversion rate)
2353
+ * Useful for freemium and trial-based pricing models
2354
+ */
2355
+ async getTrialMetrics(options) {
2356
+ const params = new URLSearchParams();
2357
+ if (options?.appId) params.append("appId", options.appId);
2358
+ if (options?.days) params.append("days", options.days.toString());
2359
+ const query = params.toString();
2360
+ return this.http.get(`/v1/analytics/trials/metrics${query ? `?${query}` : ""}`);
2361
+ }
2362
+ /**
2363
+ * Get growth metrics (new vs churned subscribers)
2364
+ */
2365
+ async getGrowthMetrics(options) {
2366
+ const params = new URLSearchParams();
2367
+ if (options?.appId) params.append("appId", options.appId);
2368
+ if (options?.days) params.append("days", options.days.toString());
2369
+ const query = params.toString();
2370
+ return this.http.get(`/v1/analytics/growth/metrics${query ? `?${query}` : ""}`);
2371
+ }
2372
+ /**
2373
+ * Get growth chart data (daily new vs churned for charting)
2374
+ */
2375
+ async getGrowthChart(options) {
2376
+ const params = new URLSearchParams();
2377
+ if (options?.appId) params.append("appId", options.appId);
2378
+ if (options?.days) params.append("days", options.days.toString());
2379
+ const query = params.toString();
2380
+ return this.http.get(`/v1/analytics/growth/chart${query ? `?${query}` : ""}`);
2381
+ }
2382
+ /**
2383
+ * Get checkout conversion rate
2384
+ */
2385
+ async getConversionRate(options) {
2386
+ const params = new URLSearchParams();
2387
+ if (options?.appId) params.append("appId", options.appId);
2388
+ if (options?.days) params.append("days", options.days.toString());
2389
+ const query = params.toString();
2390
+ return this.http.get(`/v1/analytics/conversion/rate${query ? `?${query}` : ""}`);
2391
+ }
2392
+ /**
2393
+ * Get API request counts over time
2394
+ */
2395
+ async getRequestCounts(options) {
2396
+ const params = new URLSearchParams();
2397
+ if (options?.appId) params.append("appId", options.appId);
2398
+ if (options?.days) params.append("days", options.days.toString());
2399
+ const query = params.toString();
2400
+ return this.http.get(`/v1/analytics/api/requests${query ? `?${query}` : ""}`);
2401
+ }
2402
+ /**
2403
+ * Get most popular API endpoints
2404
+ */
2405
+ async getPopularEndpoints(options) {
2406
+ const params = new URLSearchParams();
2407
+ if (options?.appId) params.append("appId", options.appId);
2408
+ if (options?.limit) params.append("limit", options.limit.toString());
2409
+ const query = params.toString();
2410
+ return this.http.get(`/v1/analytics/api/endpoints${query ? `?${query}` : ""}`);
2411
+ }
2412
+ /**
2413
+ * Get API performance metrics (error rate, response time)
2414
+ */
2415
+ async getPerformance(options) {
2416
+ const params = new URLSearchParams();
2417
+ if (options?.appId) params.append("appId", options.appId);
2418
+ if (options?.days) params.append("days", options.days.toString());
2419
+ const query = params.toString();
2420
+ return this.http.get(`/v1/analytics/api/performance${query ? `?${query}` : ""}`);
2421
+ }
2422
+ /**
2423
+ * Get feature usage over time (entitlement checks)
2424
+ */
2425
+ async getFeatureUsage(options) {
2426
+ const params = new URLSearchParams();
2427
+ if (options?.appId) params.append("appId", options.appId);
2428
+ if (options?.days) params.append("days", options.days.toString());
2429
+ const query = params.toString();
2430
+ return this.http.get(`/v1/analytics/features/usage${query ? `?${query}` : ""}`);
2431
+ }
2432
+ };
2433
+
2199
2434
  // src/client.ts
2200
2435
  var DEFAULT_BASE_URL = "https://api.stackbe.io";
2201
2436
  var DEFAULT_TIMEOUT = 3e4;
@@ -2262,6 +2497,7 @@ var StackBE = class {
2262
2497
  this.affiliates = new AffiliatesClient(this.http);
2263
2498
  this.earlyAccess = new EarlyAccessClient(this.http, config.appId);
2264
2499
  this.coupons = new CouponsClient(this.http, config.appId);
2500
+ this.analytics = new AnalyticsClient(this.http);
2265
2501
  }
2266
2502
  /**
2267
2503
  * Create a middleware for Express that tracks usage automatically.
@@ -2396,6 +2632,7 @@ var StackBE = class {
2396
2632
  // Annotate the CommonJS export names for ESM import in node:
2397
2633
  0 && (module.exports = {
2398
2634
  AffiliatesClient,
2635
+ AnalyticsClient,
2399
2636
  AuthClient,
2400
2637
  CheckoutClient,
2401
2638
  CouponsClient,
package/dist/index.mjs CHANGED
@@ -1046,6 +1046,87 @@ var SubscriptionsClient = class {
1046
1046
  `/v1/subscriptions/${subscriptionId}/trial/end`
1047
1047
  );
1048
1048
  }
1049
+ // ============================================
1050
+ // Dunning / Payment Recovery Methods
1051
+ // ============================================
1052
+ /**
1053
+ * Get dunning/payment recovery status for a subscription.
1054
+ *
1055
+ * Shows if the subscription is past due, in grace period, and when access
1056
+ * will be revoked if payment isn't recovered.
1057
+ *
1058
+ * @example
1059
+ * ```typescript
1060
+ * const dunning = await stackbe.subscriptions.getDunningStatus('sub_123');
1061
+ *
1062
+ * if (dunning.isPastDue) {
1063
+ * console.log(`Payment failed ${dunning.daysSinceFailure} days ago`);
1064
+ *
1065
+ * if (dunning.isInGracePeriod) {
1066
+ * console.log(`Access ends in ${dunning.daysUntilAccessRevoked} days`);
1067
+ * }
1068
+ * }
1069
+ *
1070
+ * // Check if customer still has access
1071
+ * if (dunning.hasAccess) {
1072
+ * // Allow access
1073
+ * }
1074
+ * ```
1075
+ */
1076
+ async getDunningStatus(subscriptionId) {
1077
+ return this.http.get(
1078
+ `/v1/subscriptions/${subscriptionId}/dunning`
1079
+ );
1080
+ }
1081
+ /**
1082
+ * List all past-due subscriptions.
1083
+ *
1084
+ * Useful for monitoring and recovery efforts.
1085
+ *
1086
+ * @example
1087
+ * ```typescript
1088
+ * // List all past-due subscriptions
1089
+ * const pastDue = await stackbe.subscriptions.listPastDue();
1090
+ *
1091
+ * // List subscriptions losing access within 3 days
1092
+ * const urgent = await stackbe.subscriptions.listPastDue({ gracePeriodExpiringSoon: 3 });
1093
+ *
1094
+ * for (const sub of urgent) {
1095
+ * console.log(`${sub.customer.email} loses access in ${sub.gracePeriodEndsAt}`);
1096
+ * }
1097
+ * ```
1098
+ */
1099
+ async listPastDue(options) {
1100
+ const params = new URLSearchParams();
1101
+ if (options?.appId) params.set("appId", options.appId);
1102
+ if (options?.gracePeriodExpiringSoon) {
1103
+ params.set("gracePeriodExpiringSoon", String(options.gracePeriodExpiringSoon));
1104
+ }
1105
+ const query = params.toString();
1106
+ const path = `/v1/subscriptions/past-due${query ? `?${query}` : ""}`;
1107
+ return this.http.get(path);
1108
+ }
1109
+ /**
1110
+ * Check if a subscription still has access (considering grace period).
1111
+ *
1112
+ * Returns true if:
1113
+ * - Subscription is active
1114
+ * - Subscription is trialing
1115
+ * - Subscription is past_due but within grace period
1116
+ *
1117
+ * @example
1118
+ * ```typescript
1119
+ * const { hasAccess } = await stackbe.subscriptions.checkAccess('sub_123');
1120
+ * if (!hasAccess) {
1121
+ * // Show upgrade prompt or block feature
1122
+ * }
1123
+ * ```
1124
+ */
1125
+ async checkAccess(subscriptionId) {
1126
+ return this.http.get(
1127
+ `/v1/subscriptions/${subscriptionId}/has-access`
1128
+ );
1129
+ }
1049
1130
  };
1050
1131
 
1051
1132
  // src/auth.ts
@@ -2156,6 +2237,159 @@ var CouponsClient = class {
2156
2237
  }
2157
2238
  };
2158
2239
 
2240
+ // src/analytics.ts
2241
+ var AnalyticsClient = class {
2242
+ constructor(http) {
2243
+ this.http = http;
2244
+ }
2245
+ /**
2246
+ * Get the full analytics dashboard with all key metrics
2247
+ */
2248
+ async getDashboard(options) {
2249
+ const params = new URLSearchParams();
2250
+ if (options?.appId) params.append("appId", options.appId);
2251
+ const query = params.toString();
2252
+ return this.http.get(`/v1/analytics/dashboard${query ? `?${query}` : ""}`);
2253
+ }
2254
+ /**
2255
+ * Get current Monthly Recurring Revenue
2256
+ */
2257
+ async getMRR(options) {
2258
+ const params = new URLSearchParams();
2259
+ if (options?.appId) params.append("appId", options.appId);
2260
+ const query = params.toString();
2261
+ return this.http.get(`/v1/analytics/revenue/mrr${query ? `?${query}` : ""}`);
2262
+ }
2263
+ /**
2264
+ * Get MRR history over time for trend analysis
2265
+ */
2266
+ async getMRRHistory(options) {
2267
+ const params = new URLSearchParams();
2268
+ if (options?.appId) params.append("appId", options.appId);
2269
+ if (options?.days) params.append("days", options.days.toString());
2270
+ const query = params.toString();
2271
+ return this.http.get(`/v1/analytics/revenue/history${query ? `?${query}` : ""}`);
2272
+ }
2273
+ /**
2274
+ * Get revenue breakdown by plan
2275
+ */
2276
+ async getRevenueByPlan(options) {
2277
+ const params = new URLSearchParams();
2278
+ if (options?.appId) params.append("appId", options.appId);
2279
+ const query = params.toString();
2280
+ return this.http.get(`/v1/analytics/revenue/by-plan${query ? `?${query}` : ""}`);
2281
+ }
2282
+ /**
2283
+ * Get Average Revenue Per User
2284
+ */
2285
+ async getARPU(options) {
2286
+ const params = new URLSearchParams();
2287
+ if (options?.appId) params.append("appId", options.appId);
2288
+ const query = params.toString();
2289
+ return this.http.get(`/v1/analytics/revenue/arpu${query ? `?${query}` : ""}`);
2290
+ }
2291
+ /**
2292
+ * Get subscription metrics (active count, churn rate)
2293
+ */
2294
+ async getSubscriptionMetrics(options) {
2295
+ const params = new URLSearchParams();
2296
+ if (options?.appId) params.append("appId", options.appId);
2297
+ if (options?.days) params.append("days", options.days.toString());
2298
+ const query = params.toString();
2299
+ return this.http.get(`/v1/analytics/subscriptions/metrics${query ? `?${query}` : ""}`);
2300
+ }
2301
+ /**
2302
+ * Get subscriber distribution by plan
2303
+ */
2304
+ async getSubscribersByPlan(options) {
2305
+ const params = new URLSearchParams();
2306
+ if (options?.appId) params.append("appId", options.appId);
2307
+ const query = params.toString();
2308
+ return this.http.get(`/v1/analytics/subscriptions/by-plan${query ? `?${query}` : ""}`);
2309
+ }
2310
+ /**
2311
+ * Get trial metrics (starts, conversions, conversion rate)
2312
+ * Useful for freemium and trial-based pricing models
2313
+ */
2314
+ async getTrialMetrics(options) {
2315
+ const params = new URLSearchParams();
2316
+ if (options?.appId) params.append("appId", options.appId);
2317
+ if (options?.days) params.append("days", options.days.toString());
2318
+ const query = params.toString();
2319
+ return this.http.get(`/v1/analytics/trials/metrics${query ? `?${query}` : ""}`);
2320
+ }
2321
+ /**
2322
+ * Get growth metrics (new vs churned subscribers)
2323
+ */
2324
+ async getGrowthMetrics(options) {
2325
+ const params = new URLSearchParams();
2326
+ if (options?.appId) params.append("appId", options.appId);
2327
+ if (options?.days) params.append("days", options.days.toString());
2328
+ const query = params.toString();
2329
+ return this.http.get(`/v1/analytics/growth/metrics${query ? `?${query}` : ""}`);
2330
+ }
2331
+ /**
2332
+ * Get growth chart data (daily new vs churned for charting)
2333
+ */
2334
+ async getGrowthChart(options) {
2335
+ const params = new URLSearchParams();
2336
+ if (options?.appId) params.append("appId", options.appId);
2337
+ if (options?.days) params.append("days", options.days.toString());
2338
+ const query = params.toString();
2339
+ return this.http.get(`/v1/analytics/growth/chart${query ? `?${query}` : ""}`);
2340
+ }
2341
+ /**
2342
+ * Get checkout conversion rate
2343
+ */
2344
+ async getConversionRate(options) {
2345
+ const params = new URLSearchParams();
2346
+ if (options?.appId) params.append("appId", options.appId);
2347
+ if (options?.days) params.append("days", options.days.toString());
2348
+ const query = params.toString();
2349
+ return this.http.get(`/v1/analytics/conversion/rate${query ? `?${query}` : ""}`);
2350
+ }
2351
+ /**
2352
+ * Get API request counts over time
2353
+ */
2354
+ async getRequestCounts(options) {
2355
+ const params = new URLSearchParams();
2356
+ if (options?.appId) params.append("appId", options.appId);
2357
+ if (options?.days) params.append("days", options.days.toString());
2358
+ const query = params.toString();
2359
+ return this.http.get(`/v1/analytics/api/requests${query ? `?${query}` : ""}`);
2360
+ }
2361
+ /**
2362
+ * Get most popular API endpoints
2363
+ */
2364
+ async getPopularEndpoints(options) {
2365
+ const params = new URLSearchParams();
2366
+ if (options?.appId) params.append("appId", options.appId);
2367
+ if (options?.limit) params.append("limit", options.limit.toString());
2368
+ const query = params.toString();
2369
+ return this.http.get(`/v1/analytics/api/endpoints${query ? `?${query}` : ""}`);
2370
+ }
2371
+ /**
2372
+ * Get API performance metrics (error rate, response time)
2373
+ */
2374
+ async getPerformance(options) {
2375
+ const params = new URLSearchParams();
2376
+ if (options?.appId) params.append("appId", options.appId);
2377
+ if (options?.days) params.append("days", options.days.toString());
2378
+ const query = params.toString();
2379
+ return this.http.get(`/v1/analytics/api/performance${query ? `?${query}` : ""}`);
2380
+ }
2381
+ /**
2382
+ * Get feature usage over time (entitlement checks)
2383
+ */
2384
+ async getFeatureUsage(options) {
2385
+ const params = new URLSearchParams();
2386
+ if (options?.appId) params.append("appId", options.appId);
2387
+ if (options?.days) params.append("days", options.days.toString());
2388
+ const query = params.toString();
2389
+ return this.http.get(`/v1/analytics/features/usage${query ? `?${query}` : ""}`);
2390
+ }
2391
+ };
2392
+
2159
2393
  // src/client.ts
2160
2394
  var DEFAULT_BASE_URL = "https://api.stackbe.io";
2161
2395
  var DEFAULT_TIMEOUT = 3e4;
@@ -2222,6 +2456,7 @@ var StackBE = class {
2222
2456
  this.affiliates = new AffiliatesClient(this.http);
2223
2457
  this.earlyAccess = new EarlyAccessClient(this.http, config.appId);
2224
2458
  this.coupons = new CouponsClient(this.http, config.appId);
2459
+ this.analytics = new AnalyticsClient(this.http);
2225
2460
  }
2226
2461
  /**
2227
2462
  * Create a middleware for Express that tracks usage automatically.
@@ -2355,6 +2590,7 @@ var StackBE = class {
2355
2590
  };
2356
2591
  export {
2357
2592
  AffiliatesClient,
2593
+ AnalyticsClient,
2358
2594
  AuthClient,
2359
2595
  CheckoutClient,
2360
2596
  CouponsClient,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackbe/sdk",
3
- "version": "0.9.4",
3
+ "version": "0.10.0",
4
4
  "description": "Official JavaScript/TypeScript SDK for StackBE - the billing backend for your side project",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",