zernio-sdk 0.0.781 → 0.0.783

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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -0
  3. data/docs/ConnectApi.md +80 -0
  4. data/docs/GetYoutubeCaptions200Response.md +38 -0
  5. data/docs/GetYoutubeCaptions200ResponseAvailableTracksInner.md +24 -0
  6. data/docs/GetYoutubeCaptions200ResponseCuesInner.md +22 -0
  7. data/docs/UsageApi.md +8 -2
  8. data/docs/UsageAttributionGroup.md +22 -0
  9. data/docs/UsageAttributionSlice.md +20 -0
  10. data/docs/UsageAttributionSliceByProduct.md +34 -0
  11. data/docs/UsageMetering.md +5 -1
  12. data/docs/UsageMeteringAttribution.md +26 -0
  13. data/docs/UsageMeteringScope.md +49 -0
  14. data/docs/UsageMeteringScopeOneOf.md +18 -0
  15. data/lib/zernio-sdk/api/connect_api.rb +83 -0
  16. data/lib/zernio-sdk/api/usage_api.rb +15 -2
  17. data/lib/zernio-sdk/models/get_youtube_captions200_response.rb +296 -0
  18. data/lib/zernio-sdk/models/get_youtube_captions200_response_available_tracks_inner.rb +209 -0
  19. data/lib/zernio-sdk/models/get_youtube_captions200_response_cues_inner.rb +166 -0
  20. data/lib/zernio-sdk/models/usage_attribution_group.rb +190 -0
  21. data/lib/zernio-sdk/models/usage_attribution_slice.rb +156 -0
  22. data/lib/zernio-sdk/models/usage_attribution_slice_by_product.rb +220 -0
  23. data/lib/zernio-sdk/models/usage_metering.rb +22 -4
  24. data/lib/zernio-sdk/models/usage_metering_attribution.rb +223 -0
  25. data/lib/zernio-sdk/models/usage_metering_call_usage.rb +1 -1
  26. data/lib/zernio-sdk/models/usage_metering_peaks.rb +1 -1
  27. data/lib/zernio-sdk/models/usage_metering_scope.rb +105 -0
  28. data/lib/zernio-sdk/models/usage_metering_scope_one_of.rb +164 -0
  29. data/lib/zernio-sdk/version.rb +1 -1
  30. data/lib/zernio-sdk.rb +9 -0
  31. data/openapi.yaml +206 -4
  32. data/spec/api/connect_api_spec.rb +16 -0
  33. data/spec/api/usage_api_spec.rb +4 -1
  34. data/spec/models/get_youtube_captions200_response_available_tracks_inner_spec.rb +58 -0
  35. data/spec/models/get_youtube_captions200_response_cues_inner_spec.rb +48 -0
  36. data/spec/models/get_youtube_captions200_response_spec.rb +104 -0
  37. data/spec/models/usage_attribution_group_spec.rb +48 -0
  38. data/spec/models/usage_attribution_slice_by_product_spec.rb +84 -0
  39. data/spec/models/usage_attribution_slice_spec.rb +42 -0
  40. data/spec/models/usage_metering_attribution_spec.rb +64 -0
  41. data/spec/models/usage_metering_scope_one_of_spec.rb +36 -0
  42. data/spec/models/usage_metering_scope_spec.rb +32 -0
  43. data/spec/models/usage_metering_spec.rb +12 -0
  44. metadata +38 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0758606d9249aa5531fc4d4c27c7eb0c3dd7d6c238f24ad976cfff84815a3f64'
4
- data.tar.gz: 149a4f99191dc15420d969dc47edc897c269d1eeae7663982cc7a202eec8854b
3
+ metadata.gz: 9a0bc51395c10adcf6db858d0db9fed18d74534f47650cd085fb2a3dde269bf4
4
+ data.tar.gz: 681dbd28bd5cfe96bcca836e86415b2c14e62d24fb9acc1c4484bd42b2eb17b0
5
5
  SHA512:
6
- metadata.gz: 823d67f0fdfe4ba9330cd500c586103d4f3e73f18fb81b9c2884697ffd955e5a276565aeedef390cfdd034e976f31cc4aaee90f35749e081e6ce0f26eb412f43
7
- data.tar.gz: 1081074c28dcc6e269539214cb720d5730a907d2d0ac091d3dace3e2b17ea4c83cd515b9623a5096117a158132e9774ae3b7a42ee4c520e9f04238022d87bccb
6
+ metadata.gz: 411d260d794a379815491cfbec765b65cb8988fdf6542988c3d742bc3594e0b727d2a84474a6103ed48a8165c8a639f384ea43eed4ddf0cc85acc7cd4af23fb5
7
+ data.tar.gz: d4802dd9779762d3d62ff5f74d4144be9be0dced53587fbbd679d5db2152189d326f55217255aca105abe9cf51145d8fe52326defae438fdcf736609e2a81cbb
data/README.md CHANGED
@@ -277,6 +277,7 @@ Class | Method | HTTP request | Description
277
277
  *Zernio::ConnectApi* | [**get_shopify_connect_url**](docs/ConnectApi.md#get_shopify_connect_url) | **GET** /v1/connect/shopify | Get Shopify OAuth connect URL
278
278
  *Zernio::ConnectApi* | [**get_subreddit_rules**](docs/ConnectApi.md#get_subreddit_rules) | **GET** /v1/accounts/{accountId}/reddit-subreddits/{subreddit}/rules | Get subreddit rules
279
279
  *Zernio::ConnectApi* | [**get_telegram_connect_status**](docs/ConnectApi.md#get_telegram_connect_status) | **GET** /v1/connect/telegram | Generate Telegram code
280
+ *Zernio::ConnectApi* | [**get_youtube_captions**](docs/ConnectApi.md#get_youtube_captions) | **GET** /v1/accounts/{accountId}/youtube-captions | Get a YouTube video transcript
280
281
  *Zernio::ConnectApi* | [**get_youtube_playlists**](docs/ConnectApi.md#get_youtube_playlists) | **GET** /v1/accounts/{accountId}/youtube-playlists | List YouTube playlists
281
282
  *Zernio::ConnectApi* | [**handle_o_auth_callback**](docs/ConnectApi.md#handle_o_auth_callback) | **POST** /v1/connect/{platform} | Complete OAuth callback
282
283
  *Zernio::ConnectApi* | [**initiate_telegram_connect**](docs/ConnectApi.md#initiate_telegram_connect) | **POST** /v1/connect/telegram | Connect Telegram directly
@@ -1454,6 +1455,9 @@ Class | Method | HTTP request | Description
1454
1455
  - [Zernio::GetYouTubeDemographics412Response](docs/GetYouTubeDemographics412Response.md)
1455
1456
  - [Zernio::GetYouTubeDemographics412ResponseScopeStatus](docs/GetYouTubeDemographics412ResponseScopeStatus.md)
1456
1457
  - [Zernio::GetYouTubeVideoRetention404Response](docs/GetYouTubeVideoRetention404Response.md)
1458
+ - [Zernio::GetYoutubeCaptions200Response](docs/GetYoutubeCaptions200Response.md)
1459
+ - [Zernio::GetYoutubeCaptions200ResponseAvailableTracksInner](docs/GetYoutubeCaptions200ResponseAvailableTracksInner.md)
1460
+ - [Zernio::GetYoutubeCaptions200ResponseCuesInner](docs/GetYoutubeCaptions200ResponseCuesInner.md)
1457
1461
  - [Zernio::GetYoutubePlaylists200Response](docs/GetYoutubePlaylists200Response.md)
1458
1462
  - [Zernio::GetYoutubePlaylists200ResponsePlaylistsInner](docs/GetYoutubePlaylists200ResponsePlaylistsInner.md)
1459
1463
  - [Zernio::GoogleBusinessPlatformData](docs/GoogleBusinessPlatformData.md)
@@ -2204,13 +2208,19 @@ Class | Method | HTTP request | Description
2204
2208
  - [Zernio::UploadedOrDerivedAudience](docs/UploadedOrDerivedAudience.md)
2205
2209
  - [Zernio::UploadedOrDerivedAudienceCompaniesInner](docs/UploadedOrDerivedAudienceCompaniesInner.md)
2206
2210
  - [Zernio::UploadedOrDerivedAudienceMatchRulesInner](docs/UploadedOrDerivedAudienceMatchRulesInner.md)
2211
+ - [Zernio::UsageAttributionGroup](docs/UsageAttributionGroup.md)
2212
+ - [Zernio::UsageAttributionSlice](docs/UsageAttributionSlice.md)
2213
+ - [Zernio::UsageAttributionSliceByProduct](docs/UsageAttributionSliceByProduct.md)
2207
2214
  - [Zernio::UsageMetering](docs/UsageMetering.md)
2215
+ - [Zernio::UsageMeteringAttribution](docs/UsageMeteringAttribution.md)
2208
2216
  - [Zernio::UsageMeteringCallUsage](docs/UsageMeteringCallUsage.md)
2209
2217
  - [Zernio::UsageMeteringCallUsageWhatsapp](docs/UsageMeteringCallUsageWhatsapp.md)
2210
2218
  - [Zernio::UsageMeteringDaysInner](docs/UsageMeteringDaysInner.md)
2211
2219
  - [Zernio::UsageMeteringLineItemsInner](docs/UsageMeteringLineItemsInner.md)
2212
2220
  - [Zernio::UsageMeteringPeaks](docs/UsageMeteringPeaks.md)
2213
2221
  - [Zernio::UsageMeteringPeriod](docs/UsageMeteringPeriod.md)
2222
+ - [Zernio::UsageMeteringScope](docs/UsageMeteringScope.md)
2223
+ - [Zernio::UsageMeteringScopeOneOf](docs/UsageMeteringScopeOneOf.md)
2214
2224
  - [Zernio::UsageMeteringTax](docs/UsageMeteringTax.md)
2215
2225
  - [Zernio::UsageMeteringTotals](docs/UsageMeteringTotals.md)
2216
2226
  - [Zernio::UsageStats](docs/UsageStats.md)
data/docs/ConnectApi.md CHANGED
@@ -28,6 +28,7 @@ All URIs are relative to *https://zernio.com/api*
28
28
  | [**get_shopify_connect_url**](ConnectApi.md#get_shopify_connect_url) | **GET** /v1/connect/shopify | Get Shopify OAuth connect URL |
29
29
  | [**get_subreddit_rules**](ConnectApi.md#get_subreddit_rules) | **GET** /v1/accounts/{accountId}/reddit-subreddits/{subreddit}/rules | Get subreddit rules |
30
30
  | [**get_telegram_connect_status**](ConnectApi.md#get_telegram_connect_status) | **GET** /v1/connect/telegram | Generate Telegram code |
31
+ | [**get_youtube_captions**](ConnectApi.md#get_youtube_captions) | **GET** /v1/accounts/{accountId}/youtube-captions | Get a YouTube video transcript |
31
32
  | [**get_youtube_playlists**](ConnectApi.md#get_youtube_playlists) | **GET** /v1/accounts/{accountId}/youtube-playlists | List YouTube playlists |
32
33
  | [**handle_o_auth_callback**](ConnectApi.md#handle_o_auth_callback) | **POST** /v1/connect/{platform} | Complete OAuth callback |
33
34
  | [**initiate_telegram_connect**](ConnectApi.md#initiate_telegram_connect) | **POST** /v1/connect/telegram | Connect Telegram directly |
@@ -1765,6 +1766,85 @@ end
1765
1766
  - **Accept**: application/json
1766
1767
 
1767
1768
 
1769
+ ## get_youtube_captions
1770
+
1771
+ > <GetYoutubeCaptions200Response> get_youtube_captions(account_id, video_id, opts)
1772
+
1773
+ Get a YouTube video transcript
1774
+
1775
+ Returns the caption track YouTube already holds for one of the connected channel's own videos, as plain text plus timed cues. Use it instead of downloading and transcribing the video yourself. Auto-generated (ASR) tracks are included: YouTube serves them to the channel owner, which is what the connected account is. Uploaded tracks win over auto-generated ones when both exist for a language. Caching: we store the transcript on first read and serve it from there afterwards, so you do not need to cache it yourself. A cached read costs no YouTube quota and does not call YouTube at all. `source` tells you which happened (`youtube` on the first read, `cache` after). Pass `refresh=true` only when the captions actually changed on YouTube, since that re-downloads. Notes: - Only videos owned by this connected channel. Anything else returns 404. - `contentDetails.caption` in YouTube's own API reads `false` on videos that DO have a serving auto-generated track, so it is not a usable availability signal. Call this endpoint and handle the 404. - YouTube generates auto-captions only for videos with recognisable speech, and can take a few hours after upload to publish them.
1776
+
1777
+ ### Examples
1778
+
1779
+ ```ruby
1780
+ require 'time'
1781
+ require 'zernio-sdk'
1782
+ # setup authorization
1783
+ Zernio.configure do |config|
1784
+ # Configure Bearer authorization (JWT): bearerAuth
1785
+ config.access_token = 'YOUR_BEARER_TOKEN'
1786
+ end
1787
+
1788
+ api_instance = Zernio::ConnectApi.new
1789
+ account_id = 'account_id_example' # String | The connected YouTube account.
1790
+ video_id = 'video_id_example' # String | The YouTube video id (the `platformPostId` on a synced external post).
1791
+ opts = {
1792
+ language: 'language_example', # String | BCP-47 language tag as YouTube labels the track. `en` also matches an `en-GB` track. Omit to take the best available track.
1793
+ format: 'json', # String | `json` returns timed `cues`; `srt` returns the raw SubRip body instead. `text` is present either way.
1794
+ refresh: true # Boolean | Re-download from YouTube instead of serving the stored copy. Spends 200 quota units.
1795
+ }
1796
+
1797
+ begin
1798
+ # Get a YouTube video transcript
1799
+ result = api_instance.get_youtube_captions(account_id, video_id, opts)
1800
+ p result
1801
+ rescue Zernio::ApiError => e
1802
+ puts "Error when calling ConnectApi->get_youtube_captions: #{e}"
1803
+ end
1804
+ ```
1805
+
1806
+ #### Using the get_youtube_captions_with_http_info variant
1807
+
1808
+ This returns an Array which contains the response data, status code and headers.
1809
+
1810
+ > <Array(<GetYoutubeCaptions200Response>, Integer, Hash)> get_youtube_captions_with_http_info(account_id, video_id, opts)
1811
+
1812
+ ```ruby
1813
+ begin
1814
+ # Get a YouTube video transcript
1815
+ data, status_code, headers = api_instance.get_youtube_captions_with_http_info(account_id, video_id, opts)
1816
+ p status_code # => 2xx
1817
+ p headers # => { ... }
1818
+ p data # => <GetYoutubeCaptions200Response>
1819
+ rescue Zernio::ApiError => e
1820
+ puts "Error when calling ConnectApi->get_youtube_captions_with_http_info: #{e}"
1821
+ end
1822
+ ```
1823
+
1824
+ ### Parameters
1825
+
1826
+ | Name | Type | Description | Notes |
1827
+ | ---- | ---- | ----------- | ----- |
1828
+ | **account_id** | **String** | The connected YouTube account. | |
1829
+ | **video_id** | **String** | The YouTube video id (the &#x60;platformPostId&#x60; on a synced external post). | |
1830
+ | **language** | **String** | BCP-47 language tag as YouTube labels the track. &#x60;en&#x60; also matches an &#x60;en-GB&#x60; track. Omit to take the best available track. | [optional] |
1831
+ | **format** | **String** | &#x60;json&#x60; returns timed &#x60;cues&#x60;; &#x60;srt&#x60; returns the raw SubRip body instead. &#x60;text&#x60; is present either way. | [optional][default to &#39;json&#39;] |
1832
+ | **refresh** | **Boolean** | Re-download from YouTube instead of serving the stored copy. Spends 200 quota units. | [optional][default to false] |
1833
+
1834
+ ### Return type
1835
+
1836
+ [**GetYoutubeCaptions200Response**](GetYoutubeCaptions200Response.md)
1837
+
1838
+ ### Authorization
1839
+
1840
+ [bearerAuth](../README.md#bearerAuth)
1841
+
1842
+ ### HTTP request headers
1843
+
1844
+ - **Content-Type**: Not defined
1845
+ - **Accept**: application/json
1846
+
1847
+
1768
1848
  ## get_youtube_playlists
1769
1849
 
1770
1850
  > <GetYoutubePlaylists200Response> get_youtube_playlists(account_id)
@@ -0,0 +1,38 @@
1
+ # Zernio::GetYoutubeCaptions200Response
2
+
3
+ ## Properties
4
+
5
+ | Name | Type | Description | Notes |
6
+ | ---- | ---- | ----------- | ----- |
7
+ | **account_id** | **String** | | [optional] |
8
+ | **video_id** | **String** | | [optional] |
9
+ | **language** | **String** | The language of the returned track. | [optional] |
10
+ | **track_id** | **String** | YouTube&#39;s own caption track id. | [optional] |
11
+ | **track_kind** | **String** | &#x60;asr&#x60; is YouTube&#39;s auto-generated track; &#x60;standard&#x60; was uploaded by the channel. | [optional] |
12
+ | **source** | **String** | &#x60;cache&#x60; when served from our stored copy, &#x60;youtube&#x60; when this call spent the quota units. | [optional] |
13
+ | **fetched_at** | **Time** | When the stored copy was downloaded from YouTube. | [optional] |
14
+ | **text** | **String** | The whole transcript as one paragraph, no timings. | [optional] |
15
+ | **cues** | [**Array&lt;GetYoutubeCaptions200ResponseCuesInner&gt;**](GetYoutubeCaptions200ResponseCuesInner.md) | Timed cues. Present when format is json. Auto-generated cues overlap in time by design (captions roll), so &#x60;start&#x60; can precede the previous cue&#39;s &#x60;end&#x60;. | [optional] |
16
+ | **srt** | **String** | Raw SubRip body. Present when format is srt. | [optional] |
17
+ | **available_tracks** | [**Array&lt;GetYoutubeCaptions200ResponseAvailableTracksInner&gt;**](GetYoutubeCaptions200ResponseAvailableTracksInner.md) | Every track on the video, so you can re-request another language. On a cached read this is the listing as it stood when we downloaded, so a language added to the video since then appears only after a &#x60;refresh&#x3D;true&#x60; or when you request that language directly. | [optional] |
18
+
19
+ ## Example
20
+
21
+ ```ruby
22
+ require 'zernio-sdk'
23
+
24
+ instance = Zernio::GetYoutubeCaptions200Response.new(
25
+ account_id: null,
26
+ video_id: null,
27
+ language: null,
28
+ track_id: null,
29
+ track_kind: null,
30
+ source: null,
31
+ fetched_at: null,
32
+ text: null,
33
+ cues: null,
34
+ srt: null,
35
+ available_tracks: null
36
+ )
37
+ ```
38
+
@@ -0,0 +1,24 @@
1
+ # Zernio::GetYoutubeCaptions200ResponseAvailableTracksInner
2
+
3
+ ## Properties
4
+
5
+ | Name | Type | Description | Notes |
6
+ | ---- | ---- | ----------- | ----- |
7
+ | **track_id** | **String** | | [optional] |
8
+ | **language** | **String** | | [optional] |
9
+ | **track_kind** | **String** | | [optional] |
10
+ | **name** | **String** | The track&#39;s display name. Empty for auto-generated tracks. | [optional] |
11
+
12
+ ## Example
13
+
14
+ ```ruby
15
+ require 'zernio-sdk'
16
+
17
+ instance = Zernio::GetYoutubeCaptions200ResponseAvailableTracksInner.new(
18
+ track_id: null,
19
+ language: null,
20
+ track_kind: null,
21
+ name: null
22
+ )
23
+ ```
24
+
@@ -0,0 +1,22 @@
1
+ # Zernio::GetYoutubeCaptions200ResponseCuesInner
2
+
3
+ ## Properties
4
+
5
+ | Name | Type | Description | Notes |
6
+ | ---- | ---- | ----------- | ----- |
7
+ | **start** | **Float** | Seconds from the start of the video. | [optional] |
8
+ | **_end** | **Float** | | [optional] |
9
+ | **text** | **String** | | [optional] |
10
+
11
+ ## Example
12
+
13
+ ```ruby
14
+ require 'zernio-sdk'
15
+
16
+ instance = Zernio::GetYoutubeCaptions200ResponseCuesInner.new(
17
+ start: null,
18
+ _end: null,
19
+ text: null
20
+ )
21
+ ```
22
+
data/docs/UsageApi.md CHANGED
@@ -240,7 +240,7 @@ end
240
240
 
241
241
  Usage snapshot (default) or billed-spend metering (with params)
242
242
 
243
- Dual-mode endpoint, selected by query params — fully backward compatible: **Without metering params (the default):** the plan / quota / usage snapshot — plan name, billing period, limits, usage counts, access state. Identical to `GET /v1/usage-stats`. Existing integrations keep working unchanged. **With `range`, `granularity`, `from`, or `to`:** usage METERING — billed spend (USD) by product family (`accounts`, `numbers`, `calls`, `sms`, `dlc`, `xApi`, `credits`, `other`) over the window, at `day` / `month` / `total` granularity, from Metronome's invoice breakdown (the CHARGE view — always reconciles with what gets billed). Also served at `GET /v1/usage/daily`. Usage-based accounts only — legacy Stripe accounts get `{ \"supported\": false, \"days\": [] }`. For per-domain consumption *volumes* use `GET /v1/usage/calls` and `GET /v1/usage/sms`. For the billing statement (balance, credits, caps, payment status) use `GET /v1/billing`.
243
+ Dual-mode endpoint, selected by query params — fully backward compatible: **Without metering params (the default):** the plan / quota / usage snapshot — plan name, billing period, limits, usage counts, access state. Identical to `GET /v1/usage-stats`. Existing integrations keep working unchanged. **With `range`, `granularity`, `from`, or `to`:** usage METERING — billed spend (USD) by product family (`accounts`, `numbers`, `calls`, `sms`, `dlc`, `xApi`, `credits`, `other`) over the window, at `day` / `month` / `total` granularity, from Metronome's invoice breakdown (the CHARGE view — always reconciles with what gets billed). Also served at `GET /v1/usage/daily`. Usage-based accounts only — legacy Stripe accounts get `{ \"supported\": false, \"days\": [] }`. **Attribution (metering mode):** `groupBy=profile|account` adds an `attribution` breakdown of the window's spend per profile or account, assembled from your own records and pro-rated against the invoice so `sum(groups) + unattributed` equals `totals` exactly. `profileId` / `accountId` instead project the whole payload (`days`, `totals`, `lineItems`) onto that one group; `peaks`, `callUsage` and `tax` are then `null` (workspace-level facts). Projected `days` spread the group's period share over each day (usage is attributed per period, not per day). Profile-scoped API keys and members only see their profiles' groups (`attribution.restricted: true`, with `totals` summing the visible groups). Credits, 10DLC fees and Verify are always unattributed. `profileId` / `accountId` on their own do not select metering mode: pair them with `range`. For per-domain consumption *volumes* use `GET /v1/usage/calls` and `GET /v1/usage/sms`. For the billing statement (balance, credits, caps, payment status) use `GET /v1/billing`.
244
244
 
245
245
  ### Examples
246
246
 
@@ -259,7 +259,10 @@ opts = {
259
259
  range: 'cycle', # String | Window to report. `cycle` / `prev-cycle` resolve to the customer's real billing-period bounds (falling back to a trailing 30 days when no invoice exists yet); `7d`…`12mo` are trailing windows; `custom` uses `from` / `to`.
260
260
  from: Date.parse('2013-10-20'), # Date | Inclusive start (UTC date). Required when `range=custom`.
261
261
  to: Date.parse('2013-10-20'), # Date | Inclusive end (UTC date). Required when `range=custom`. Max span 366 days.
262
- granularity: 'day' # String | Bucketing of the `days` series: `day` (one row per UTC day), `month` (one row per calendar month, dated to the 1st), or `total` (no series — read `totals`). Does not affect `totals`.
262
+ granularity: 'day', # String | Bucketing of the `days` series: `day` (one row per UTC day), `month` (one row per calendar month, dated to the 1st), or `total` (no series — read `totals`). Does not affect `totals`.
263
+ group_by: 'profile', # String | Metering mode. Adds `attribution`: the window's spend split per profile or per account (keys are ids; resolve names via `GET /v1/profiles` / `GET /v1/accounts`).
264
+ profile_id: 'profile_id_example', # String | Metering mode (pair with `range`). Project the payload onto this profile's attributed share. Mutually exclusive with `accountId`, and `groupBy` (if given) must be `profile`; 404 when the profile is not in your workspace (or outside a scoped key's profiles).
265
+ account_id: 'account_id_example' # String | Metering mode (pair with `range`). Project the payload onto this account's attributed share. Mutually exclusive with `profileId`, and `groupBy` (if given) must be `account`; 404 when the account is not visible to the caller.
263
266
  }
264
267
 
265
268
  begin
@@ -298,6 +301,9 @@ end
298
301
  | **from** | **Date** | Inclusive start (UTC date). Required when &#x60;range&#x3D;custom&#x60;. | [optional] |
299
302
  | **to** | **Date** | Inclusive end (UTC date). Required when &#x60;range&#x3D;custom&#x60;. Max span 366 days. | [optional] |
300
303
  | **granularity** | **String** | Bucketing of the &#x60;days&#x60; series: &#x60;day&#x60; (one row per UTC day), &#x60;month&#x60; (one row per calendar month, dated to the 1st), or &#x60;total&#x60; (no series — read &#x60;totals&#x60;). Does not affect &#x60;totals&#x60;. | [optional][default to &#39;day&#39;] |
304
+ | **group_by** | **String** | Metering mode. Adds &#x60;attribution&#x60;: the window&#39;s spend split per profile or per account (keys are ids; resolve names via &#x60;GET /v1/profiles&#x60; / &#x60;GET /v1/accounts&#x60;). | [optional] |
305
+ | **profile_id** | **String** | Metering mode (pair with &#x60;range&#x60;). Project the payload onto this profile&#39;s attributed share. Mutually exclusive with &#x60;accountId&#x60;, and &#x60;groupBy&#x60; (if given) must be &#x60;profile&#x60;; 404 when the profile is not in your workspace (or outside a scoped key&#39;s profiles). | [optional] |
306
+ | **account_id** | **String** | Metering mode (pair with &#x60;range&#x60;). Project the payload onto this account&#39;s attributed share. Mutually exclusive with &#x60;profileId&#x60;, and &#x60;groupBy&#x60; (if given) must be &#x60;account&#x60;; 404 when the account is not visible to the caller. | [optional] |
301
307
 
302
308
  ### Return type
303
309
 
@@ -0,0 +1,22 @@
1
+ # Zernio::UsageAttributionGroup
2
+
3
+ ## Properties
4
+
5
+ | Name | Type | Description | Notes |
6
+ | ---- | ---- | ----------- | ----- |
7
+ | **by_product** | [**UsageAttributionSliceByProduct**](UsageAttributionSliceByProduct.md) | | [optional] |
8
+ | **total_usd** | **Float** | | [optional] |
9
+ | **key** | **String** | Profile id or account id, per &#x60;groupBy&#x60;. | |
10
+
11
+ ## Example
12
+
13
+ ```ruby
14
+ require 'zernio-sdk'
15
+
16
+ instance = Zernio::UsageAttributionGroup.new(
17
+ by_product: null,
18
+ total_usd: null,
19
+ key: null
20
+ )
21
+ ```
22
+
@@ -0,0 +1,20 @@
1
+ # Zernio::UsageAttributionSlice
2
+
3
+ ## Properties
4
+
5
+ | Name | Type | Description | Notes |
6
+ | ---- | ---- | ----------- | ----- |
7
+ | **by_product** | [**UsageAttributionSliceByProduct**](UsageAttributionSliceByProduct.md) | | [optional] |
8
+ | **total_usd** | **Float** | | [optional] |
9
+
10
+ ## Example
11
+
12
+ ```ruby
13
+ require 'zernio-sdk'
14
+
15
+ instance = Zernio::UsageAttributionSlice.new(
16
+ by_product: null,
17
+ total_usd: null
18
+ )
19
+ ```
20
+
@@ -0,0 +1,34 @@
1
+ # Zernio::UsageAttributionSliceByProduct
2
+
3
+ ## Properties
4
+
5
+ | Name | Type | Description | Notes |
6
+ | ---- | ---- | ----------- | ----- |
7
+ | **accounts** | **Float** | | [optional] |
8
+ | **numbers** | **Float** | | [optional] |
9
+ | **calls** | **Float** | | [optional] |
10
+ | **sms** | **Float** | | [optional] |
11
+ | **verify** | **Float** | | [optional] |
12
+ | **dlc** | **Float** | | [optional] |
13
+ | **x_api** | **Float** | | [optional] |
14
+ | **credits** | **Float** | | [optional] |
15
+ | **other** | **Float** | | [optional] |
16
+
17
+ ## Example
18
+
19
+ ```ruby
20
+ require 'zernio-sdk'
21
+
22
+ instance = Zernio::UsageAttributionSliceByProduct.new(
23
+ accounts: null,
24
+ numbers: null,
25
+ calls: null,
26
+ sms: null,
27
+ verify: null,
28
+ dlc: null,
29
+ x_api: null,
30
+ credits: null,
31
+ other: null
32
+ )
33
+ ```
34
+
@@ -13,6 +13,8 @@
13
13
  | **call_usage** | [**UsageMeteringCallUsage**](UsageMeteringCallUsage.md) | | [optional] |
14
14
  | **period** | [**UsageMeteringPeriod**](UsageMeteringPeriod.md) | | [optional] |
15
15
  | **tax** | [**UsageMeteringTax**](UsageMeteringTax.md) | | [optional] |
16
+ | **attribution** | [**UsageMeteringAttribution**](UsageMeteringAttribution.md) | | [optional] |
17
+ | **scope** | [**UsageMeteringScope**](UsageMeteringScope.md) | | [optional] |
16
18
 
17
19
  ## Example
18
20
 
@@ -28,7 +30,9 @@ instance = Zernio::UsageMetering.new(
28
30
  peaks: null,
29
31
  call_usage: null,
30
32
  period: null,
31
- tax: null
33
+ tax: null,
34
+ attribution: null,
35
+ scope: null
32
36
  )
33
37
  ```
34
38
 
@@ -0,0 +1,26 @@
1
+ # Zernio::UsageMeteringAttribution
2
+
3
+ ## Properties
4
+
5
+ | Name | Type | Description | Notes |
6
+ | ---- | ---- | ----------- | ----- |
7
+ | **group_by** | **String** | | [optional] |
8
+ | **groups** | [**Array&lt;UsageAttributionGroup&gt;**](UsageAttributionGroup.md) | | [optional] |
9
+ | **unattributed** | [**UsageAttributionSlice**](UsageAttributionSlice.md) | Spend no profile/account can claim: credits, 10DLC fees, Verify, and usage whose record no longer resolves to an account. Zero for a restricted principal. | [optional] |
10
+ | **totals** | [**UsageAttributionSlice**](UsageAttributionSlice.md) | The window totals; for a restricted principal, the sum of the visible groups. | [optional] |
11
+ | **restricted** | **Boolean** | True when the caller (profile-scoped API key or member) cannot see every profile: &#x60;groups&#x60; are filtered, &#x60;totals&#x60; sum them, &#x60;unattributed&#x60; is zero, and the top-level &#x60;days&#x60; / &#x60;totals&#x60; / &#x60;lineItems&#x60; are projected onto the visible groups with &#x60;peaks&#x60;, &#x60;callUsage&#x60; and &#x60;tax&#x60; null. | [optional] |
12
+
13
+ ## Example
14
+
15
+ ```ruby
16
+ require 'zernio-sdk'
17
+
18
+ instance = Zernio::UsageMeteringAttribution.new(
19
+ group_by: null,
20
+ groups: null,
21
+ unattributed: null,
22
+ totals: null,
23
+ restricted: null
24
+ )
25
+ ```
26
+
@@ -0,0 +1,49 @@
1
+ # Zernio::UsageMeteringScope
2
+
3
+ ## Class instance methods
4
+
5
+ ### `openapi_one_of`
6
+
7
+ Returns the list of classes defined in oneOf.
8
+
9
+ #### Example
10
+
11
+ ```ruby
12
+ require 'zernio-sdk'
13
+
14
+ Zernio::UsageMeteringScope.openapi_one_of
15
+ # =>
16
+ # [
17
+ # :'DeleteInboxReviewReplyRequest',
18
+ # :'UsageMeteringScopeOneOf'
19
+ # ]
20
+ ```
21
+
22
+ ### build
23
+
24
+ Find the appropriate object from the `openapi_one_of` list and casts the data into it.
25
+
26
+ #### Example
27
+
28
+ ```ruby
29
+ require 'zernio-sdk'
30
+
31
+ Zernio::UsageMeteringScope.build(data)
32
+ # => #<DeleteInboxReviewReplyRequest:0x00007fdd4aab02a0>
33
+
34
+ Zernio::UsageMeteringScope.build(data_that_doesnt_match)
35
+ # => nil
36
+ ```
37
+
38
+ #### Parameters
39
+
40
+ | Name | Type | Description |
41
+ | ---- | ---- | ----------- |
42
+ | **data** | **Mixed** | data to be matched against the list of oneOf items |
43
+
44
+ #### Return type
45
+
46
+ - `DeleteInboxReviewReplyRequest`
47
+ - `UsageMeteringScopeOneOf`
48
+ - `nil` (if no type matches)
49
+
@@ -0,0 +1,18 @@
1
+ # Zernio::UsageMeteringScopeOneOf
2
+
3
+ ## Properties
4
+
5
+ | Name | Type | Description | Notes |
6
+ | ---- | ---- | ----------- | ----- |
7
+ | **profile_id** | **String** | | |
8
+
9
+ ## Example
10
+
11
+ ```ruby
12
+ require 'zernio-sdk'
13
+
14
+ instance = Zernio::UsageMeteringScopeOneOf.new(
15
+ profile_id: null
16
+ )
17
+ ```
18
+
@@ -1714,6 +1714,89 @@ module Zernio
1714
1714
  return data, status_code, headers
1715
1715
  end
1716
1716
 
1717
+ # Get a YouTube video transcript
1718
+ # Returns the caption track YouTube already holds for one of the connected channel's own videos, as plain text plus timed cues. Use it instead of downloading and transcribing the video yourself. Auto-generated (ASR) tracks are included: YouTube serves them to the channel owner, which is what the connected account is. Uploaded tracks win over auto-generated ones when both exist for a language. Caching: we store the transcript on first read and serve it from there afterwards, so you do not need to cache it yourself. A cached read costs no YouTube quota and does not call YouTube at all. `source` tells you which happened (`youtube` on the first read, `cache` after). Pass `refresh=true` only when the captions actually changed on YouTube, since that re-downloads. Notes: - Only videos owned by this connected channel. Anything else returns 404. - `contentDetails.caption` in YouTube's own API reads `false` on videos that DO have a serving auto-generated track, so it is not a usable availability signal. Call this endpoint and handle the 404. - YouTube generates auto-captions only for videos with recognisable speech, and can take a few hours after upload to publish them.
1719
+ # @param account_id [String] The connected YouTube account.
1720
+ # @param video_id [String] The YouTube video id (the &#x60;platformPostId&#x60; on a synced external post).
1721
+ # @param [Hash] opts the optional parameters
1722
+ # @option opts [String] :language BCP-47 language tag as YouTube labels the track. &#x60;en&#x60; also matches an &#x60;en-GB&#x60; track. Omit to take the best available track.
1723
+ # @option opts [String] :format &#x60;json&#x60; returns timed &#x60;cues&#x60;; &#x60;srt&#x60; returns the raw SubRip body instead. &#x60;text&#x60; is present either way. (default to 'json')
1724
+ # @option opts [Boolean] :refresh Re-download from YouTube instead of serving the stored copy. Spends 200 quota units. (default to false)
1725
+ # @return [GetYoutubeCaptions200Response]
1726
+ def get_youtube_captions(account_id, video_id, opts = {})
1727
+ data, _status_code, _headers = get_youtube_captions_with_http_info(account_id, video_id, opts)
1728
+ data
1729
+ end
1730
+
1731
+ # Get a YouTube video transcript
1732
+ # Returns the caption track YouTube already holds for one of the connected channel&#39;s own videos, as plain text plus timed cues. Use it instead of downloading and transcribing the video yourself. Auto-generated (ASR) tracks are included: YouTube serves them to the channel owner, which is what the connected account is. Uploaded tracks win over auto-generated ones when both exist for a language. Caching: we store the transcript on first read and serve it from there afterwards, so you do not need to cache it yourself. A cached read costs no YouTube quota and does not call YouTube at all. &#x60;source&#x60; tells you which happened (&#x60;youtube&#x60; on the first read, &#x60;cache&#x60; after). Pass &#x60;refresh&#x3D;true&#x60; only when the captions actually changed on YouTube, since that re-downloads. Notes: - Only videos owned by this connected channel. Anything else returns 404. - &#x60;contentDetails.caption&#x60; in YouTube&#39;s own API reads &#x60;false&#x60; on videos that DO have a serving auto-generated track, so it is not a usable availability signal. Call this endpoint and handle the 404. - YouTube generates auto-captions only for videos with recognisable speech, and can take a few hours after upload to publish them.
1733
+ # @param account_id [String] The connected YouTube account.
1734
+ # @param video_id [String] The YouTube video id (the &#x60;platformPostId&#x60; on a synced external post).
1735
+ # @param [Hash] opts the optional parameters
1736
+ # @option opts [String] :language BCP-47 language tag as YouTube labels the track. &#x60;en&#x60; also matches an &#x60;en-GB&#x60; track. Omit to take the best available track.
1737
+ # @option opts [String] :format &#x60;json&#x60; returns timed &#x60;cues&#x60;; &#x60;srt&#x60; returns the raw SubRip body instead. &#x60;text&#x60; is present either way. (default to 'json')
1738
+ # @option opts [Boolean] :refresh Re-download from YouTube instead of serving the stored copy. Spends 200 quota units. (default to false)
1739
+ # @return [Array<(GetYoutubeCaptions200Response, Integer, Hash)>] GetYoutubeCaptions200Response data, response status code and response headers
1740
+ def get_youtube_captions_with_http_info(account_id, video_id, opts = {})
1741
+ if @api_client.config.debugging
1742
+ @api_client.config.logger.debug 'Calling API: ConnectApi.get_youtube_captions ...'
1743
+ end
1744
+ # verify the required parameter 'account_id' is set
1745
+ if @api_client.config.client_side_validation && account_id.nil?
1746
+ fail ArgumentError, "Missing the required parameter 'account_id' when calling ConnectApi.get_youtube_captions"
1747
+ end
1748
+ # verify the required parameter 'video_id' is set
1749
+ if @api_client.config.client_side_validation && video_id.nil?
1750
+ fail ArgumentError, "Missing the required parameter 'video_id' when calling ConnectApi.get_youtube_captions"
1751
+ end
1752
+ allowable_values = ["json", "srt"]
1753
+ if @api_client.config.client_side_validation && opts[:'format'] && !allowable_values.include?(opts[:'format'])
1754
+ fail ArgumentError, "invalid value for \"format\", must be one of #{allowable_values}"
1755
+ end
1756
+ # resource path
1757
+ local_var_path = '/v1/accounts/{accountId}/youtube-captions'.sub('{' + 'accountId' + '}', CGI.escape(account_id.to_s))
1758
+
1759
+ # query parameters
1760
+ query_params = opts[:query_params] || {}
1761
+ query_params[:'videoId'] = video_id
1762
+ query_params[:'language'] = opts[:'language'] if !opts[:'language'].nil?
1763
+ query_params[:'format'] = opts[:'format'] if !opts[:'format'].nil?
1764
+ query_params[:'refresh'] = opts[:'refresh'] if !opts[:'refresh'].nil?
1765
+
1766
+ # header parameters
1767
+ header_params = opts[:header_params] || {}
1768
+ # HTTP header 'Accept' (if needed)
1769
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
1770
+
1771
+ # form parameters
1772
+ form_params = opts[:form_params] || {}
1773
+
1774
+ # http body (model)
1775
+ post_body = opts[:debug_body]
1776
+
1777
+ # return_type
1778
+ return_type = opts[:debug_return_type] || 'GetYoutubeCaptions200Response'
1779
+
1780
+ # auth_names
1781
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
1782
+
1783
+ new_options = opts.merge(
1784
+ :operation => :"ConnectApi.get_youtube_captions",
1785
+ :header_params => header_params,
1786
+ :query_params => query_params,
1787
+ :form_params => form_params,
1788
+ :body => post_body,
1789
+ :auth_names => auth_names,
1790
+ :return_type => return_type
1791
+ )
1792
+
1793
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
1794
+ if @api_client.config.debugging
1795
+ @api_client.config.logger.debug "API called: ConnectApi#get_youtube_captions\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
1796
+ end
1797
+ return data, status_code, headers
1798
+ end
1799
+
1717
1800
  # List YouTube playlists
1718
1801
  # Returns the playlists available for a connected YouTube account. Use this to get a playlist ID when creating a YouTube post with the playlistId field.
1719
1802
  # @param account_id [String]
@@ -230,13 +230,16 @@ module Zernio
230
230
  end
231
231
 
232
232
  # Usage snapshot (default) or billed-spend metering (with params)
233
- # Dual-mode endpoint, selected by query params — fully backward compatible: **Without metering params (the default):** the plan / quota / usage snapshot — plan name, billing period, limits, usage counts, access state. Identical to `GET /v1/usage-stats`. Existing integrations keep working unchanged. **With `range`, `granularity`, `from`, or `to`:** usage METERING — billed spend (USD) by product family (`accounts`, `numbers`, `calls`, `sms`, `dlc`, `xApi`, `credits`, `other`) over the window, at `day` / `month` / `total` granularity, from Metronome's invoice breakdown (the CHARGE view — always reconciles with what gets billed). Also served at `GET /v1/usage/daily`. Usage-based accounts only — legacy Stripe accounts get `{ \"supported\": false, \"days\": [] }`. For per-domain consumption *volumes* use `GET /v1/usage/calls` and `GET /v1/usage/sms`. For the billing statement (balance, credits, caps, payment status) use `GET /v1/billing`.
233
+ # Dual-mode endpoint, selected by query params — fully backward compatible: **Without metering params (the default):** the plan / quota / usage snapshot — plan name, billing period, limits, usage counts, access state. Identical to `GET /v1/usage-stats`. Existing integrations keep working unchanged. **With `range`, `granularity`, `from`, or `to`:** usage METERING — billed spend (USD) by product family (`accounts`, `numbers`, `calls`, `sms`, `dlc`, `xApi`, `credits`, `other`) over the window, at `day` / `month` / `total` granularity, from Metronome's invoice breakdown (the CHARGE view — always reconciles with what gets billed). Also served at `GET /v1/usage/daily`. Usage-based accounts only — legacy Stripe accounts get `{ \"supported\": false, \"days\": [] }`. **Attribution (metering mode):** `groupBy=profile|account` adds an `attribution` breakdown of the window's spend per profile or account, assembled from your own records and pro-rated against the invoice so `sum(groups) + unattributed` equals `totals` exactly. `profileId` / `accountId` instead project the whole payload (`days`, `totals`, `lineItems`) onto that one group; `peaks`, `callUsage` and `tax` are then `null` (workspace-level facts). Projected `days` spread the group's period share over each day (usage is attributed per period, not per day). Profile-scoped API keys and members only see their profiles' groups (`attribution.restricted: true`, with `totals` summing the visible groups). Credits, 10DLC fees and Verify are always unattributed. `profileId` / `accountId` on their own do not select metering mode: pair them with `range`. For per-domain consumption *volumes* use `GET /v1/usage/calls` and `GET /v1/usage/sms`. For the billing statement (balance, credits, caps, payment status) use `GET /v1/billing`.
234
234
  # @param [Hash] opts the optional parameters
235
235
  # @option opts [Boolean] :reconcile Snapshot mode only. For Stripe subscription users, &#x60;true&#x60; forces a subscription reconciliation pass even when cached plan data looks complete.
236
236
  # @option opts [String] :range Window to report. &#x60;cycle&#x60; / &#x60;prev-cycle&#x60; resolve to the customer&#39;s real billing-period bounds (falling back to a trailing 30 days when no invoice exists yet); &#x60;7d&#x60;…&#x60;12mo&#x60; are trailing windows; &#x60;custom&#x60; uses &#x60;from&#x60; / &#x60;to&#x60;. (default to 'cycle')
237
237
  # @option opts [Date] :from Inclusive start (UTC date). Required when &#x60;range&#x3D;custom&#x60;.
238
238
  # @option opts [Date] :to Inclusive end (UTC date). Required when &#x60;range&#x3D;custom&#x60;. Max span 366 days.
239
239
  # @option opts [String] :granularity Bucketing of the &#x60;days&#x60; series: &#x60;day&#x60; (one row per UTC day), &#x60;month&#x60; (one row per calendar month, dated to the 1st), or &#x60;total&#x60; (no series — read &#x60;totals&#x60;). Does not affect &#x60;totals&#x60;. (default to 'day')
240
+ # @option opts [String] :group_by Metering mode. Adds &#x60;attribution&#x60;: the window&#39;s spend split per profile or per account (keys are ids; resolve names via &#x60;GET /v1/profiles&#x60; / &#x60;GET /v1/accounts&#x60;).
241
+ # @option opts [String] :profile_id Metering mode (pair with &#x60;range&#x60;). Project the payload onto this profile&#39;s attributed share. Mutually exclusive with &#x60;accountId&#x60;, and &#x60;groupBy&#x60; (if given) must be &#x60;profile&#x60;; 404 when the profile is not in your workspace (or outside a scoped key&#39;s profiles).
242
+ # @option opts [String] :account_id Metering mode (pair with &#x60;range&#x60;). Project the payload onto this account&#39;s attributed share. Mutually exclusive with &#x60;profileId&#x60;, and &#x60;groupBy&#x60; (if given) must be &#x60;account&#x60;; 404 when the account is not visible to the caller.
240
243
  # @return [GetUsage200Response]
241
244
  def get_usage(opts = {})
242
245
  data, _status_code, _headers = get_usage_with_http_info(opts)
@@ -244,13 +247,16 @@ module Zernio
244
247
  end
245
248
 
246
249
  # Usage snapshot (default) or billed-spend metering (with params)
247
- # Dual-mode endpoint, selected by query params — fully backward compatible: **Without metering params (the default):** the plan / quota / usage snapshot — plan name, billing period, limits, usage counts, access state. Identical to &#x60;GET /v1/usage-stats&#x60;. Existing integrations keep working unchanged. **With &#x60;range&#x60;, &#x60;granularity&#x60;, &#x60;from&#x60;, or &#x60;to&#x60;:** usage METERING — billed spend (USD) by product family (&#x60;accounts&#x60;, &#x60;numbers&#x60;, &#x60;calls&#x60;, &#x60;sms&#x60;, &#x60;dlc&#x60;, &#x60;xApi&#x60;, &#x60;credits&#x60;, &#x60;other&#x60;) over the window, at &#x60;day&#x60; / &#x60;month&#x60; / &#x60;total&#x60; granularity, from Metronome&#39;s invoice breakdown (the CHARGE view — always reconciles with what gets billed). Also served at &#x60;GET /v1/usage/daily&#x60;. Usage-based accounts only — legacy Stripe accounts get &#x60;{ \&quot;supported\&quot;: false, \&quot;days\&quot;: [] }&#x60;. For per-domain consumption *volumes* use &#x60;GET /v1/usage/calls&#x60; and &#x60;GET /v1/usage/sms&#x60;. For the billing statement (balance, credits, caps, payment status) use &#x60;GET /v1/billing&#x60;.
250
+ # Dual-mode endpoint, selected by query params — fully backward compatible: **Without metering params (the default):** the plan / quota / usage snapshot — plan name, billing period, limits, usage counts, access state. Identical to &#x60;GET /v1/usage-stats&#x60;. Existing integrations keep working unchanged. **With &#x60;range&#x60;, &#x60;granularity&#x60;, &#x60;from&#x60;, or &#x60;to&#x60;:** usage METERING — billed spend (USD) by product family (&#x60;accounts&#x60;, &#x60;numbers&#x60;, &#x60;calls&#x60;, &#x60;sms&#x60;, &#x60;dlc&#x60;, &#x60;xApi&#x60;, &#x60;credits&#x60;, &#x60;other&#x60;) over the window, at &#x60;day&#x60; / &#x60;month&#x60; / &#x60;total&#x60; granularity, from Metronome&#39;s invoice breakdown (the CHARGE view — always reconciles with what gets billed). Also served at &#x60;GET /v1/usage/daily&#x60;. Usage-based accounts only — legacy Stripe accounts get &#x60;{ \&quot;supported\&quot;: false, \&quot;days\&quot;: [] }&#x60;. **Attribution (metering mode):** &#x60;groupBy&#x3D;profile|account&#x60; adds an &#x60;attribution&#x60; breakdown of the window&#39;s spend per profile or account, assembled from your own records and pro-rated against the invoice so &#x60;sum(groups) + unattributed&#x60; equals &#x60;totals&#x60; exactly. &#x60;profileId&#x60; / &#x60;accountId&#x60; instead project the whole payload (&#x60;days&#x60;, &#x60;totals&#x60;, &#x60;lineItems&#x60;) onto that one group; &#x60;peaks&#x60;, &#x60;callUsage&#x60; and &#x60;tax&#x60; are then &#x60;null&#x60; (workspace-level facts). Projected &#x60;days&#x60; spread the group&#39;s period share over each day (usage is attributed per period, not per day). Profile-scoped API keys and members only see their profiles&#39; groups (&#x60;attribution.restricted: true&#x60;, with &#x60;totals&#x60; summing the visible groups). Credits, 10DLC fees and Verify are always unattributed. &#x60;profileId&#x60; / &#x60;accountId&#x60; on their own do not select metering mode: pair them with &#x60;range&#x60;. For per-domain consumption *volumes* use &#x60;GET /v1/usage/calls&#x60; and &#x60;GET /v1/usage/sms&#x60;. For the billing statement (balance, credits, caps, payment status) use &#x60;GET /v1/billing&#x60;.
248
251
  # @param [Hash] opts the optional parameters
249
252
  # @option opts [Boolean] :reconcile Snapshot mode only. For Stripe subscription users, &#x60;true&#x60; forces a subscription reconciliation pass even when cached plan data looks complete.
250
253
  # @option opts [String] :range Window to report. &#x60;cycle&#x60; / &#x60;prev-cycle&#x60; resolve to the customer&#39;s real billing-period bounds (falling back to a trailing 30 days when no invoice exists yet); &#x60;7d&#x60;…&#x60;12mo&#x60; are trailing windows; &#x60;custom&#x60; uses &#x60;from&#x60; / &#x60;to&#x60;. (default to 'cycle')
251
254
  # @option opts [Date] :from Inclusive start (UTC date). Required when &#x60;range&#x3D;custom&#x60;.
252
255
  # @option opts [Date] :to Inclusive end (UTC date). Required when &#x60;range&#x3D;custom&#x60;. Max span 366 days.
253
256
  # @option opts [String] :granularity Bucketing of the &#x60;days&#x60; series: &#x60;day&#x60; (one row per UTC day), &#x60;month&#x60; (one row per calendar month, dated to the 1st), or &#x60;total&#x60; (no series — read &#x60;totals&#x60;). Does not affect &#x60;totals&#x60;. (default to 'day')
257
+ # @option opts [String] :group_by Metering mode. Adds &#x60;attribution&#x60;: the window&#39;s spend split per profile or per account (keys are ids; resolve names via &#x60;GET /v1/profiles&#x60; / &#x60;GET /v1/accounts&#x60;).
258
+ # @option opts [String] :profile_id Metering mode (pair with &#x60;range&#x60;). Project the payload onto this profile&#39;s attributed share. Mutually exclusive with &#x60;accountId&#x60;, and &#x60;groupBy&#x60; (if given) must be &#x60;profile&#x60;; 404 when the profile is not in your workspace (or outside a scoped key&#39;s profiles).
259
+ # @option opts [String] :account_id Metering mode (pair with &#x60;range&#x60;). Project the payload onto this account&#39;s attributed share. Mutually exclusive with &#x60;profileId&#x60;, and &#x60;groupBy&#x60; (if given) must be &#x60;account&#x60;; 404 when the account is not visible to the caller.
254
260
  # @return [Array<(GetUsage200Response, Integer, Hash)>] GetUsage200Response data, response status code and response headers
255
261
  def get_usage_with_http_info(opts = {})
256
262
  if @api_client.config.debugging
@@ -264,6 +270,10 @@ module Zernio
264
270
  if @api_client.config.client_side_validation && opts[:'granularity'] && !allowable_values.include?(opts[:'granularity'])
265
271
  fail ArgumentError, "invalid value for \"granularity\", must be one of #{allowable_values}"
266
272
  end
273
+ allowable_values = ["profile", "account"]
274
+ if @api_client.config.client_side_validation && opts[:'group_by'] && !allowable_values.include?(opts[:'group_by'])
275
+ fail ArgumentError, "invalid value for \"group_by\", must be one of #{allowable_values}"
276
+ end
267
277
  # resource path
268
278
  local_var_path = '/v1/usage'
269
279
 
@@ -274,6 +284,9 @@ module Zernio
274
284
  query_params[:'from'] = opts[:'from'] if !opts[:'from'].nil?
275
285
  query_params[:'to'] = opts[:'to'] if !opts[:'to'].nil?
276
286
  query_params[:'granularity'] = opts[:'granularity'] if !opts[:'granularity'].nil?
287
+ query_params[:'groupBy'] = opts[:'group_by'] if !opts[:'group_by'].nil?
288
+ query_params[:'profileId'] = opts[:'profile_id'] if !opts[:'profile_id'].nil?
289
+ query_params[:'accountId'] = opts[:'account_id'] if !opts[:'account_id'].nil?
277
290
 
278
291
  # header parameters
279
292
  header_params = opts[:header_params] || {}