@firela/api-types 0.0.0-canary.0327ab9e → 0.0.0-canary.09a8ff4c

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.
@@ -29,6 +29,8 @@ import type {
29
29
  TransactionControllerListResponse,
30
30
  TransactionControllerCreateBatchData,
31
31
  TransactionControllerCreateBatchResponse,
32
+ TransactionControllerCorrectData,
33
+ TransactionControllerCorrectResponse,
32
34
  TransactionControllerSuggestTagsData,
33
35
  TransactionControllerSuggestTagsResponse,
34
36
  TransactionControllerGetDetailData,
@@ -169,6 +171,18 @@ import type {
169
171
  PropertyControllerUpdateResponse,
170
172
  PropertyControllerDeleteData,
171
173
  PropertyControllerDeleteResponse,
174
+ EventControllerCreateData,
175
+ EventControllerCreateResponse,
176
+ EventControllerFindAllData,
177
+ EventControllerFindAllResponse,
178
+ EventControllerFindOneData,
179
+ EventControllerFindOneResponse,
180
+ EventControllerUpdateData,
181
+ EventControllerUpdateResponse,
182
+ EventControllerDeleteData,
183
+ EventControllerDeleteResponse,
184
+ EventControllerGetSliceData,
185
+ EventControllerGetSliceResponse,
172
186
  ExportControllerExportBeancountResponse,
173
187
  FileImportControllerImportFileData,
174
188
  FileImportControllerImportFileResponse,
@@ -200,6 +214,10 @@ import type {
200
214
  ProviderSyncControllerIsProviderSupportedResponse,
201
215
  TelemetryControllerReportTelemetryData,
202
216
  TelemetryControllerReportTelemetryResponse,
217
+ TelemetryControllerReportCoverageMissData,
218
+ TelemetryControllerReportCoverageMissResponse,
219
+ TelemetryControllerGetCoverageMetricsData,
220
+ TelemetryControllerGetCoverageMetricsResponse,
203
221
  NlpControllerProcessNaturalLanguageData,
204
222
  NlpControllerProcessNaturalLanguageResponse,
205
223
  NlpControllerClearSessionData,
@@ -212,8 +230,24 @@ import type {
212
230
  DashboardControllerGetAccountsResponse,
213
231
  DashboardControllerGetCashFlowData,
214
232
  DashboardControllerGetCashFlowResponse,
233
+ HoldingPnlControllerGetHoldingPnlData,
234
+ HoldingPnlControllerGetHoldingPnlResponse,
235
+ PriceControllerCreateData,
236
+ PriceControllerCreateResponse,
237
+ PriceControllerFindAllData,
238
+ PriceControllerFindAllResponse,
239
+ PriceControllerFindOneData,
240
+ PriceControllerFindOneResponse,
241
+ PriceControllerUpdateData,
242
+ PriceControllerUpdateResponse,
243
+ PriceControllerDeleteData,
244
+ PriceControllerDeleteResponse,
245
+ PriceControllerBulkCreateData,
246
+ PriceControllerBulkCreateResponse,
215
247
  ReportingControllerGetPortfolioTrendsData,
216
248
  ReportingControllerGetPortfolioTrendsResponse,
249
+ ReportingControllerGetCashFlowTrendsData,
250
+ ReportingControllerGetCashFlowTrendsResponse,
217
251
  ReportingControllerGenerateSnapshotData,
218
252
  ReportingControllerGenerateSnapshotResponse,
219
253
  ReportingControllerBackfillSnapshotsData,
@@ -605,6 +639,36 @@ export class BeanTransactionsService {
605
639
  });
606
640
  }
607
641
 
642
+ /**
643
+ * Correct (supersede) a transaction
644
+ * Atomically voids the original (SUPERSEDED) and creates a replacement through the full validation pipeline.
645
+ * @param data The data for the request.
646
+ * @param data.id Original transaction ID to correct
647
+ * @param data.region Region code for tenant context
648
+ * @param data.requestBody
649
+ * @returns TransactionDetailDto Corrected transaction created
650
+ * @throws ApiError
651
+ */
652
+ public static transactionControllerCorrect(
653
+ data: TransactionControllerCorrectData
654
+ ): CancelablePromise<TransactionControllerCorrectResponse> {
655
+ return __request(OpenAPI, {
656
+ method: 'POST',
657
+ url: '/api/v1/{region}/bean/transactions/{id}/correct',
658
+ path: {
659
+ id: data.id,
660
+ region: data.region
661
+ },
662
+ body: data.requestBody,
663
+ mediaType: 'application/json',
664
+ errors: {
665
+ 404: 'Original transaction not found',
666
+ 409: 'Original no longer ACTIVE (concurrent modification)',
667
+ 422: 'Pipeline validation failed (does not balance, invalid accounts)'
668
+ }
669
+ });
670
+ }
671
+
608
672
  /**
609
673
  * Suggest transaction tags
610
674
  * Returns distinct tags from the user ACTIVE transactions, sorted by usage, for autocomplete. Optional q performs a case-insensitive prefix match.
@@ -2410,6 +2474,181 @@ export class PropertiesService {
2410
2474
  }
2411
2475
  }
2412
2476
 
2477
+ export class LifeEventsService {
2478
+ /**
2479
+ * Create a new life event
2480
+ * Creates a new life event entry for the authenticated user. Returns ETag header carrying the row updatedAt.
2481
+ * @param data The data for the request.
2482
+ * @param data.region Region code for tenant context (decorative for life events)
2483
+ * @param data.requestBody
2484
+ * @returns EventResponseDto Life event created successfully
2485
+ * @throws ApiError
2486
+ */
2487
+ public static eventControllerCreate(
2488
+ data: EventControllerCreateData
2489
+ ): CancelablePromise<EventControllerCreateResponse> {
2490
+ return __request(OpenAPI, {
2491
+ method: 'POST',
2492
+ url: '/api/v1/{region}/bean/events',
2493
+ path: {
2494
+ region: data.region
2495
+ },
2496
+ body: data.requestBody,
2497
+ mediaType: 'application/json',
2498
+ errors: {
2499
+ 409: 'Life event already exists for this (userId, type, date) combination'
2500
+ }
2501
+ });
2502
+ }
2503
+
2504
+ /**
2505
+ * List user life events
2506
+ * Returns life events for the authenticated user with optional filtering by type, description search, and date range.
2507
+ * @param data The data for the request.
2508
+ * @param data.region Region code for tenant context (decorative for life events)
2509
+ * @param data.type Filter by life event type (exact match)
2510
+ * @param data.q Search term for description (case-insensitive partial match)
2511
+ * @param data.from Filter life events from this date (ISO 8601 format)
2512
+ * @param data.to Filter life events to this date (ISO 8601 format)
2513
+ * @param data.page Page number for pagination (default: 1)
2514
+ * @param data.limit Number of items per page (default: 20, max: 100)
2515
+ * @returns EventListResponseDto Life events retrieved successfully
2516
+ * @throws ApiError
2517
+ */
2518
+ public static eventControllerFindAll(
2519
+ data: EventControllerFindAllData
2520
+ ): CancelablePromise<EventControllerFindAllResponse> {
2521
+ return __request(OpenAPI, {
2522
+ method: 'GET',
2523
+ url: '/api/v1/{region}/bean/events',
2524
+ path: {
2525
+ region: data.region
2526
+ },
2527
+ query: {
2528
+ type: data.type,
2529
+ q: data.q,
2530
+ from: data.from,
2531
+ to: data.to,
2532
+ page: data.page,
2533
+ limit: data.limit
2534
+ }
2535
+ });
2536
+ }
2537
+
2538
+ /**
2539
+ * Get life event by ID
2540
+ * Returns a single life event by its ID. Returns ETag header.
2541
+ * @param data The data for the request.
2542
+ * @param data.id Life event ID
2543
+ * @param data.region Region code for tenant context (decorative for life events)
2544
+ * @returns EventResponseDto Life event retrieved successfully
2545
+ * @throws ApiError
2546
+ */
2547
+ public static eventControllerFindOne(
2548
+ data: EventControllerFindOneData
2549
+ ): CancelablePromise<EventControllerFindOneResponse> {
2550
+ return __request(OpenAPI, {
2551
+ method: 'GET',
2552
+ url: '/api/v1/{region}/bean/events/{id}',
2553
+ path: {
2554
+ id: data.id,
2555
+ region: data.region
2556
+ },
2557
+ errors: {
2558
+ 404: 'Life event not found'
2559
+ }
2560
+ });
2561
+ }
2562
+
2563
+ /**
2564
+ * Update a life event
2565
+ * Updates an existing life event. If If-Match header is provided, performs optimistic concurrency check; mismatched updatedAt returns 412.
2566
+ * @param data The data for the request.
2567
+ * @param data.id Life event ID
2568
+ * @param data.region Region code for tenant context (decorative for life events)
2569
+ * @param data.requestBody
2570
+ * @returns EventResponseDto Life event updated successfully
2571
+ * @throws ApiError
2572
+ */
2573
+ public static eventControllerUpdate(
2574
+ data: EventControllerUpdateData
2575
+ ): CancelablePromise<EventControllerUpdateResponse> {
2576
+ return __request(OpenAPI, {
2577
+ method: 'PUT',
2578
+ url: '/api/v1/{region}/bean/events/{id}',
2579
+ path: {
2580
+ id: data.id,
2581
+ region: data.region
2582
+ },
2583
+ body: data.requestBody,
2584
+ mediaType: 'application/json',
2585
+ errors: {
2586
+ 400: 'If-Match header is not a valid ISO 8601 date',
2587
+ 404: 'Life event not found',
2588
+ 409: 'Updated event conflicts with an existing (userId, type, date) combination',
2589
+ 412: 'If-Match precondition failed (updatedAt mismatch)'
2590
+ }
2591
+ });
2592
+ }
2593
+
2594
+ /**
2595
+ * Delete a life event
2596
+ * Deletes a life event entry (hard delete). Returns 204.
2597
+ * @param data The data for the request.
2598
+ * @param data.id Life event ID
2599
+ * @param data.region Region code for tenant context (decorative for life events)
2600
+ * @returns void Life event deleted successfully
2601
+ * @throws ApiError
2602
+ */
2603
+ public static eventControllerDelete(
2604
+ data: EventControllerDeleteData
2605
+ ): CancelablePromise<EventControllerDeleteResponse> {
2606
+ return __request(OpenAPI, {
2607
+ method: 'DELETE',
2608
+ url: '/api/v1/{region}/bean/events/{id}',
2609
+ path: {
2610
+ id: data.id,
2611
+ region: data.region
2612
+ },
2613
+ errors: {
2614
+ 404: 'Life event not found'
2615
+ }
2616
+ });
2617
+ }
2618
+
2619
+ /**
2620
+ * Slice time-series by a life event (Phase 79)
2621
+ * Returns aggregated time-series for postings matching accountPattern within the half-open date range of the given life event.
2622
+ * @param data The data for the request.
2623
+ * @param data.id Life event ID
2624
+ * @param data.accountPattern
2625
+ * @param data.granularity
2626
+ * @param data.region Region code for tenant context (decorative for life events)
2627
+ * @returns unknown Time-series sliced by the life event range
2628
+ * @throws ApiError
2629
+ */
2630
+ public static eventControllerGetSlice(
2631
+ data: EventControllerGetSliceData
2632
+ ): CancelablePromise<EventControllerGetSliceResponse> {
2633
+ return __request(OpenAPI, {
2634
+ method: 'GET',
2635
+ url: '/api/v1/{region}/bean/events/{id}/slice',
2636
+ path: {
2637
+ id: data.id,
2638
+ region: data.region
2639
+ },
2640
+ query: {
2641
+ accountPattern: data.accountPattern,
2642
+ granularity: data.granularity
2643
+ },
2644
+ errors: {
2645
+ 400: 'accountPattern query param is empty',
2646
+ 404: 'Life event not found'
2647
+ }
2648
+ });
2649
+ }
2650
+ }
2651
+
2413
2652
  export class BeanExportService {
2414
2653
  /**
2415
2654
  * Export Beancount ledger as ZIP
@@ -2729,7 +2968,7 @@ export class ProviderSyncService {
2729
2968
  *
2730
2969
  * @param data The data for the request.
2731
2970
  * @param data.providerName Provider name
2732
- * @param data.region Region code
2971
+ * @param data.region Region code for tenant context
2733
2972
  * @param data.requestBody
2734
2973
  * @returns ProviderSyncResponseDto Sync completed successfully
2735
2974
  * @throws ApiError
@@ -2828,6 +3067,54 @@ export class ImportTelemetryService {
2828
3067
  }
2829
3068
  });
2830
3069
  }
3070
+
3071
+ /**
3072
+ * Receive anonymous zero-hit coverage miss report
3073
+ * @param data The data for the request.
3074
+ * @param data.region Region code for tenant context
3075
+ * @param data.requestBody
3076
+ * @returns unknown Coverage miss report received
3077
+ * @throws ApiError
3078
+ */
3079
+ public static telemetryControllerReportCoverageMiss(
3080
+ data: TelemetryControllerReportCoverageMissData
3081
+ ): CancelablePromise<TelemetryControllerReportCoverageMissResponse> {
3082
+ return __request(OpenAPI, {
3083
+ method: 'POST',
3084
+ url: '/api/v1/{region}/bean/import/parser-coverage-miss',
3085
+ path: {
3086
+ region: data.region
3087
+ },
3088
+ body: data.requestBody,
3089
+ mediaType: 'application/json',
3090
+ errors: {
3091
+ 401: 'Unauthorized'
3092
+ }
3093
+ });
3094
+ }
3095
+
3096
+ /**
3097
+ * Coverage metrics (uncovered format aggregation)
3098
+ * @param data The data for the request.
3099
+ * @param data.region Region code for tenant context
3100
+ * @param data.topN Top-N uncovered formats (default 10)
3101
+ * @returns unknown Coverage metrics
3102
+ * @throws ApiError
3103
+ */
3104
+ public static telemetryControllerGetCoverageMetrics(
3105
+ data: TelemetryControllerGetCoverageMetricsData
3106
+ ): CancelablePromise<TelemetryControllerGetCoverageMetricsResponse> {
3107
+ return __request(OpenAPI, {
3108
+ method: 'GET',
3109
+ url: '/api/v1/{region}/bean/import/parser-coverage-metrics',
3110
+ path: {
3111
+ region: data.region
3112
+ },
3113
+ query: {
3114
+ topN: data.topN
3115
+ }
3116
+ });
3117
+ }
2831
3118
  }
2832
3119
 
2833
3120
  export class BeanNlpService {
@@ -2948,6 +3235,7 @@ export class DashboardService {
2948
3235
  * @param data.region Region code for tenant context
2949
3236
  * @param data.groupBy Grouping strategy
2950
3237
  * @param data.date Date for balance calculation (ISO 8601 format)
3238
+ * @param data.accountId Scope to a single account (only valid with groupBy=holdingAssetClass, ADR-0105 §6)
2951
3239
  * @returns unknown Accounts retrieved successfully. Response type depends on groupBy parameter.
2952
3240
  * @throws ApiError
2953
3241
  */
@@ -2962,7 +3250,8 @@ export class DashboardService {
2962
3250
  },
2963
3251
  query: {
2964
3252
  groupBy: data.groupBy,
2965
- date: data.date
3253
+ date: data.date,
3254
+ accountId: data.accountId
2966
3255
  },
2967
3256
  errors: {
2968
3257
  401: 'User not authenticated'
@@ -2999,6 +3288,207 @@ export class DashboardService {
2999
3288
  }
3000
3289
  }
3001
3290
 
3291
+ export class InvestmentService {
3292
+ /**
3293
+ * Get per-holding unrealized + realized P&L
3294
+ * Average-cost unrealized P&L per account × commodity, plus cumulative realized P&L on sold lots (method = FIFO | average, default average).
3295
+ * @param data The data for the request.
3296
+ * @param data.region Region code for tenant context
3297
+ * @param data.asOf As-of date (ISO 8601), defaults to today
3298
+ * @param data.accountId Scope to a single account
3299
+ * @param data.method Realized-P&L lot-matching method (default average). Does not affect the average-cost unrealized basis.
3300
+ * @returns HoldingPnlResponseDto Holding P&L retrieved successfully
3301
+ * @throws ApiError
3302
+ */
3303
+ public static holdingPnlControllerGetHoldingPnl(
3304
+ data: HoldingPnlControllerGetHoldingPnlData
3305
+ ): CancelablePromise<HoldingPnlControllerGetHoldingPnlResponse> {
3306
+ return __request(OpenAPI, {
3307
+ method: 'GET',
3308
+ url: '/api/v1/{region}/investment/holdings/pnl',
3309
+ path: {
3310
+ region: data.region
3311
+ },
3312
+ query: {
3313
+ asOf: data.asOf,
3314
+ accountId: data.accountId,
3315
+ method: data.method
3316
+ },
3317
+ errors: {
3318
+ 400: 'Invalid asOf format/value/future date, invalid accountId format, or unsupported method',
3319
+ 401: 'User not authenticated'
3320
+ }
3321
+ });
3322
+ }
3323
+ }
3324
+
3325
+ export class BeanPricesService {
3326
+ /**
3327
+ * Create a new price
3328
+ * Creates a new price entry for the authenticated user
3329
+ * @param data The data for the request.
3330
+ * @param data.region Region code for tenant context
3331
+ * @param data.requestBody
3332
+ * @returns PriceResponseDto Price created successfully
3333
+ * @throws ApiError
3334
+ */
3335
+ public static priceControllerCreate(
3336
+ data: PriceControllerCreateData
3337
+ ): CancelablePromise<PriceControllerCreateResponse> {
3338
+ return __request(OpenAPI, {
3339
+ method: 'POST',
3340
+ url: '/api/v1/{region}/bean/prices',
3341
+ path: {
3342
+ region: data.region
3343
+ },
3344
+ body: data.requestBody,
3345
+ mediaType: 'application/json',
3346
+ errors: {
3347
+ 404: 'Currency or quoteCurrency commodity not found',
3348
+ 409: 'Price already exists for this currency pair and date'
3349
+ }
3350
+ });
3351
+ }
3352
+
3353
+ /**
3354
+ * List user prices
3355
+ * Returns all price entries for the authenticated user with optional filtering
3356
+ * @param data The data for the request.
3357
+ * @param data.region Region code for tenant context
3358
+ * @param data.currency Filter by currency (e.g., BTC, AAPL, USD)
3359
+ * @param data.quoteCurrency Filter by quote currency (pricing currency, e.g., USD, CNY)
3360
+ * @param data.dateFrom Filter prices from this date (ISO 8601 format)
3361
+ * @param data.dateTo Filter prices to this date (ISO 8601 format)
3362
+ * @param data.search Search term for currency or quoteCurrency (case-insensitive partial match)
3363
+ * @param data.page Page number for pagination (default: 1)
3364
+ * @param data.limit Number of items per page (default: 20, max: 100)
3365
+ * @returns PriceListResponseDto Prices retrieved successfully
3366
+ * @throws ApiError
3367
+ */
3368
+ public static priceControllerFindAll(
3369
+ data: PriceControllerFindAllData
3370
+ ): CancelablePromise<PriceControllerFindAllResponse> {
3371
+ return __request(OpenAPI, {
3372
+ method: 'GET',
3373
+ url: '/api/v1/{region}/bean/prices',
3374
+ path: {
3375
+ region: data.region
3376
+ },
3377
+ query: {
3378
+ currency: data.currency,
3379
+ quoteCurrency: data.quoteCurrency,
3380
+ dateFrom: data.dateFrom,
3381
+ dateTo: data.dateTo,
3382
+ search: data.search,
3383
+ page: data.page,
3384
+ limit: data.limit
3385
+ }
3386
+ });
3387
+ }
3388
+
3389
+ /**
3390
+ * Get price by ID
3391
+ * Returns a single price entry by its ID
3392
+ * @param data The data for the request.
3393
+ * @param data.id Price ID
3394
+ * @param data.region Region code for tenant context
3395
+ * @returns PriceResponseDto Price retrieved successfully
3396
+ * @throws ApiError
3397
+ */
3398
+ public static priceControllerFindOne(
3399
+ data: PriceControllerFindOneData
3400
+ ): CancelablePromise<PriceControllerFindOneResponse> {
3401
+ return __request(OpenAPI, {
3402
+ method: 'GET',
3403
+ url: '/api/v1/{region}/bean/prices/{id}',
3404
+ path: {
3405
+ id: data.id,
3406
+ region: data.region
3407
+ },
3408
+ errors: {
3409
+ 404: 'Price not found'
3410
+ }
3411
+ });
3412
+ }
3413
+
3414
+ /**
3415
+ * Update a price
3416
+ * Updates an existing price entry
3417
+ * @param data The data for the request.
3418
+ * @param data.id Price ID
3419
+ * @param data.region Region code for tenant context
3420
+ * @param data.requestBody
3421
+ * @returns PriceResponseDto Price updated successfully
3422
+ * @throws ApiError
3423
+ */
3424
+ public static priceControllerUpdate(
3425
+ data: PriceControllerUpdateData
3426
+ ): CancelablePromise<PriceControllerUpdateResponse> {
3427
+ return __request(OpenAPI, {
3428
+ method: 'PUT',
3429
+ url: '/api/v1/{region}/bean/prices/{id}',
3430
+ path: {
3431
+ id: data.id,
3432
+ region: data.region
3433
+ },
3434
+ body: data.requestBody,
3435
+ mediaType: 'application/json',
3436
+ errors: {
3437
+ 404: 'Price not found',
3438
+ 409: 'Updated price conflicts with existing price'
3439
+ }
3440
+ });
3441
+ }
3442
+
3443
+ /**
3444
+ * Delete a price
3445
+ * Deletes a price entry (hard delete)
3446
+ * @param data The data for the request.
3447
+ * @param data.id Price ID
3448
+ * @param data.region Region code for tenant context
3449
+ * @returns void Price deleted successfully
3450
+ * @throws ApiError
3451
+ */
3452
+ public static priceControllerDelete(
3453
+ data: PriceControllerDeleteData
3454
+ ): CancelablePromise<PriceControllerDeleteResponse> {
3455
+ return __request(OpenAPI, {
3456
+ method: 'DELETE',
3457
+ url: '/api/v1/{region}/bean/prices/{id}',
3458
+ path: {
3459
+ id: data.id,
3460
+ region: data.region
3461
+ },
3462
+ errors: {
3463
+ 404: 'Price not found'
3464
+ }
3465
+ });
3466
+ }
3467
+
3468
+ /**
3469
+ * Bulk create prices
3470
+ * Creates multiple price entries at once (skips duplicates)
3471
+ * @param data The data for the request.
3472
+ * @param data.region Region code for tenant context
3473
+ * @param data.requestBody
3474
+ * @returns PriceResponseDto Prices created successfully
3475
+ * @throws ApiError
3476
+ */
3477
+ public static priceControllerBulkCreate(
3478
+ data: PriceControllerBulkCreateData
3479
+ ): CancelablePromise<PriceControllerBulkCreateResponse> {
3480
+ return __request(OpenAPI, {
3481
+ method: 'POST',
3482
+ url: '/api/v1/{region}/bean/prices/bulk',
3483
+ path: {
3484
+ region: data.region
3485
+ },
3486
+ body: data.requestBody,
3487
+ mediaType: 'application/json'
3488
+ });
3489
+ }
3490
+ }
3491
+
3002
3492
  export class ReportingService {
3003
3493
  /**
3004
3494
  * Get portfolio value trends
@@ -3040,6 +3530,42 @@ export class ReportingService {
3040
3530
  });
3041
3531
  }
3042
3532
 
3533
+ /**
3534
+ * Get cash-flow trends
3535
+ *
3536
+ * Monthly income / expense / netSavings over a fixed N-month window
3537
+ * (current month + N−1 prior). Missing months are zero-filled (flow metric).
3538
+ *
3539
+ * **Parameters:**
3540
+ * - `period`: 1m | 3m | 6m | 1y (default 6m)
3541
+ * - `granularity`: accepted for API symmetry; v1 returns month buckets
3542
+ *
3543
+ * @param data The data for the request.
3544
+ * @param data.region Region code for tenant context
3545
+ * @param data.period Time period
3546
+ * @param data.granularity Data granularity (accepted for API symmetry; v1 returns month buckets)
3547
+ * @returns CashFlowTrendsResponseDto Cash-flow trends retrieved successfully
3548
+ * @throws ApiError
3549
+ */
3550
+ public static reportingControllerGetCashFlowTrends(
3551
+ data: ReportingControllerGetCashFlowTrendsData
3552
+ ): CancelablePromise<ReportingControllerGetCashFlowTrendsResponse> {
3553
+ return __request(OpenAPI, {
3554
+ method: 'GET',
3555
+ url: '/api/v1/{region}/reporting/cash-flow/trends',
3556
+ path: {
3557
+ region: data.region
3558
+ },
3559
+ query: {
3560
+ period: data.period,
3561
+ granularity: data.granularity
3562
+ },
3563
+ errors: {
3564
+ 401: 'User not authenticated'
3565
+ }
3566
+ });
3567
+ }
3568
+
3043
3569
  /**
3044
3570
  * Generate portfolio snapshot
3045
3571
  *