late-sdk 0.0.782 → 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 (34) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -0
  3. data/docs/UsageApi.md +8 -2
  4. data/docs/UsageAttributionGroup.md +22 -0
  5. data/docs/UsageAttributionSlice.md +20 -0
  6. data/docs/UsageAttributionSliceByProduct.md +34 -0
  7. data/docs/UsageMetering.md +5 -1
  8. data/docs/UsageMeteringAttribution.md +26 -0
  9. data/docs/UsageMeteringScope.md +49 -0
  10. data/docs/UsageMeteringScopeOneOf.md +18 -0
  11. data/lib/zernio-sdk/api/usage_api.rb +15 -2
  12. data/lib/zernio-sdk/models/usage_attribution_group.rb +190 -0
  13. data/lib/zernio-sdk/models/usage_attribution_slice.rb +156 -0
  14. data/lib/zernio-sdk/models/usage_attribution_slice_by_product.rb +220 -0
  15. data/lib/zernio-sdk/models/usage_metering.rb +22 -4
  16. data/lib/zernio-sdk/models/usage_metering_attribution.rb +223 -0
  17. data/lib/zernio-sdk/models/usage_metering_call_usage.rb +1 -1
  18. data/lib/zernio-sdk/models/usage_metering_peaks.rb +1 -1
  19. data/lib/zernio-sdk/models/usage_metering_scope.rb +105 -0
  20. data/lib/zernio-sdk/models/usage_metering_scope_one_of.rb +164 -0
  21. data/lib/zernio-sdk/version.rb +1 -1
  22. data/lib/zernio-sdk.rb +6 -0
  23. data/openapi.yaml +90 -4
  24. data/spec/api/usage_api_spec.rb +4 -1
  25. data/spec/models/usage_attribution_group_spec.rb +48 -0
  26. data/spec/models/usage_attribution_slice_by_product_spec.rb +84 -0
  27. data/spec/models/usage_attribution_slice_spec.rb +42 -0
  28. data/spec/models/usage_metering_attribution_spec.rb +64 -0
  29. data/spec/models/usage_metering_scope_one_of_spec.rb +36 -0
  30. data/spec/models/usage_metering_scope_spec.rb +32 -0
  31. data/spec/models/usage_metering_spec.rb +12 -0
  32. data/zernio-sdk-0.0.783.gem +0 -0
  33. metadata +26 -2
  34. data/zernio-sdk-0.0.782.gem +0 -0
@@ -0,0 +1,105 @@
1
+ =begin
2
+ #Zernio API
3
+
4
+ #API reference for Zernio. Authenticate with a Bearer API key. Base URL: https://zernio.com/api Versioning and deprecation: all endpoints are versioned in the URL path (current version: /v1). Breaking changes only ship in a new path version; existing versions keep working. Deprecated operations are marked 'deprecated: true' in this spec and announced in the changelog (https://zernio.com/changelog) before removal. Errors: every 4xx/5xx response is application/json with a machine-readable 'code' and a human-readable 'error' message (see the ErrorResponse schema).
5
+
6
+ The version of the OpenAPI document: 1.0.4
7
+ Contact: support@zernio.com
8
+ Generated by: https://openapi-generator.tech
9
+ Generator version: 7.19.0
10
+
11
+ =end
12
+
13
+ require 'date'
14
+ require 'time'
15
+
16
+ module Zernio
17
+ # Present with `profileId` / `accountId`: echoes the group the payload was projected onto.
18
+ module UsageMeteringScope
19
+ class << self
20
+ # List of class defined in oneOf (OpenAPI v3)
21
+ def openapi_one_of
22
+ [
23
+ :'DeleteInboxReviewReplyRequest',
24
+ :'UsageMeteringScopeOneOf'
25
+ ]
26
+ end
27
+
28
+ # Builds the object
29
+ # @param [Mixed] Data to be matched against the list of oneOf items
30
+ # @return [Object] Returns the model or the data itself
31
+ def build(data)
32
+ # Go through the list of oneOf items and attempt to identify the appropriate one.
33
+ # Note:
34
+ # - We do not attempt to check whether exactly one item matches.
35
+ # - No advanced validation of types in some cases (e.g. "x: { type: string }" will happily match { x: 123 })
36
+ # due to the way the deserialization is made in the base_object template (it just casts without verifying).
37
+ # - TODO: scalar values are de facto behaving as if they were nullable.
38
+ # - TODO: logging when debugging is set.
39
+ openapi_one_of.each do |klass|
40
+ begin
41
+ next if klass == :AnyType # "nullable: true"
42
+ return find_and_cast_into_type(klass, data)
43
+ rescue # rescue all errors so we keep iterating even if the current item lookup raises
44
+ end
45
+ end
46
+
47
+ openapi_one_of.include?(:AnyType) ? data : nil
48
+ end
49
+
50
+ private
51
+
52
+ SchemaMismatchError = Class.new(StandardError)
53
+
54
+ # Note: 'File' is missing here because in the regular case we get the data _after_ a call to JSON.parse.
55
+ def find_and_cast_into_type(klass, data)
56
+ return if data.nil?
57
+
58
+ case klass.to_s
59
+ when 'Boolean'
60
+ return data if data.instance_of?(TrueClass) || data.instance_of?(FalseClass)
61
+ when 'Float'
62
+ return data if data.instance_of?(Float)
63
+ when 'Integer'
64
+ return data if data.instance_of?(Integer)
65
+ when 'Time'
66
+ return Time.parse(data)
67
+ when 'Date'
68
+ return Date.iso8601(data)
69
+ when 'String'
70
+ return data if data.instance_of?(String)
71
+ when 'Object' # "type: object"
72
+ return data if data.instance_of?(Hash)
73
+ when /\AArray<(?<sub_type>.+)>\z/ # "type: array"
74
+ if data.instance_of?(Array)
75
+ sub_type = Regexp.last_match[:sub_type]
76
+ return data.map { |item| find_and_cast_into_type(sub_type, item) }
77
+ end
78
+ when /\AHash<String, (?<sub_type>.+)>\z/ # "type: object" with "additionalProperties: { ... }"
79
+ if data.instance_of?(Hash) && data.keys.all? { |k| k.instance_of?(Symbol) || k.instance_of?(String) }
80
+ sub_type = Regexp.last_match[:sub_type]
81
+ return data.each_with_object({}) { |(k, v), hsh| hsh[k] = find_and_cast_into_type(sub_type, v) }
82
+ end
83
+ else # model
84
+ const = Zernio.const_get(klass)
85
+ if const
86
+ if const.respond_to?(:openapi_one_of) # nested oneOf model
87
+ model = const.build(data)
88
+ return model if model
89
+ else
90
+ # raise if data contains keys that are not known to the model
91
+ raise if const.respond_to?(:acceptable_attributes) && !(data.keys - const.acceptable_attributes).empty?
92
+ model = const.build_from_hash(data)
93
+ return model if model
94
+ end
95
+ end
96
+ end
97
+
98
+ raise # if no match by now, raise
99
+ rescue
100
+ raise SchemaMismatchError, "#{data} doesn't match the #{klass} type"
101
+ end
102
+ end
103
+ end
104
+
105
+ end
@@ -0,0 +1,164 @@
1
+ =begin
2
+ #Zernio API
3
+
4
+ #API reference for Zernio. Authenticate with a Bearer API key. Base URL: https://zernio.com/api Versioning and deprecation: all endpoints are versioned in the URL path (current version: /v1). Breaking changes only ship in a new path version; existing versions keep working. Deprecated operations are marked 'deprecated: true' in this spec and announced in the changelog (https://zernio.com/changelog) before removal. Errors: every 4xx/5xx response is application/json with a machine-readable 'code' and a human-readable 'error' message (see the ErrorResponse schema).
5
+
6
+ The version of the OpenAPI document: 1.0.4
7
+ Contact: support@zernio.com
8
+ Generated by: https://openapi-generator.tech
9
+ Generator version: 7.19.0
10
+
11
+ =end
12
+
13
+ require 'date'
14
+ require 'time'
15
+
16
+ module Zernio
17
+ class UsageMeteringScopeOneOf < ApiModelBase
18
+ attr_accessor :profile_id
19
+
20
+ # Attribute mapping from ruby-style variable name to JSON key.
21
+ def self.attribute_map
22
+ {
23
+ :'profile_id' => :'profileId'
24
+ }
25
+ end
26
+
27
+ # Returns attribute mapping this model knows about
28
+ def self.acceptable_attribute_map
29
+ attribute_map
30
+ end
31
+
32
+ # Returns all the JSON keys this model knows about
33
+ def self.acceptable_attributes
34
+ acceptable_attribute_map.values
35
+ end
36
+
37
+ # Attribute type mapping.
38
+ def self.openapi_types
39
+ {
40
+ :'profile_id' => :'String'
41
+ }
42
+ end
43
+
44
+ # List of attributes with nullable: true
45
+ def self.openapi_nullable
46
+ Set.new([
47
+ ])
48
+ end
49
+
50
+ # Initializes the object
51
+ # @param [Hash] attributes Model attributes in the form of hash
52
+ def initialize(attributes = {})
53
+ if (!attributes.is_a?(Hash))
54
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Zernio::UsageMeteringScopeOneOf` initialize method"
55
+ end
56
+
57
+ # check to see if the attribute exists and convert string to symbol for hash key
58
+ acceptable_attribute_map = self.class.acceptable_attribute_map
59
+ attributes = attributes.each_with_object({}) { |(k, v), h|
60
+ if (!acceptable_attribute_map.key?(k.to_sym))
61
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Zernio::UsageMeteringScopeOneOf`. Please check the name to make sure it's valid. List of attributes: " + acceptable_attribute_map.keys.inspect
62
+ end
63
+ h[k.to_sym] = v
64
+ }
65
+
66
+ if attributes.key?(:'profile_id')
67
+ self.profile_id = attributes[:'profile_id']
68
+ else
69
+ self.profile_id = nil
70
+ end
71
+ end
72
+
73
+ # Show invalid properties with the reasons. Usually used together with valid?
74
+ # @return Array for valid properties with the reasons
75
+ def list_invalid_properties
76
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
77
+ invalid_properties = Array.new
78
+ if @profile_id.nil?
79
+ invalid_properties.push('invalid value for "profile_id", profile_id cannot be nil.')
80
+ end
81
+
82
+ invalid_properties
83
+ end
84
+
85
+ # Check to see if the all the properties in the model are valid
86
+ # @return true if the model is valid
87
+ def valid?
88
+ warn '[DEPRECATED] the `valid?` method is obsolete'
89
+ return false if @profile_id.nil?
90
+ true
91
+ end
92
+
93
+ # Custom attribute writer method with validation
94
+ # @param [Object] profile_id Value to be assigned
95
+ def profile_id=(profile_id)
96
+ if profile_id.nil?
97
+ fail ArgumentError, 'profile_id cannot be nil'
98
+ end
99
+
100
+ @profile_id = profile_id
101
+ end
102
+
103
+ # Checks equality by comparing each attribute.
104
+ # @param [Object] Object to be compared
105
+ def ==(o)
106
+ return true if self.equal?(o)
107
+ self.class == o.class &&
108
+ profile_id == o.profile_id
109
+ end
110
+
111
+ # @see the `==` method
112
+ # @param [Object] Object to be compared
113
+ def eql?(o)
114
+ self == o
115
+ end
116
+
117
+ # Calculates hash code according to all attributes.
118
+ # @return [Integer] Hash code
119
+ def hash
120
+ [profile_id].hash
121
+ end
122
+
123
+ # Builds the object from hash
124
+ # @param [Hash] attributes Model attributes in the form of hash
125
+ # @return [Object] Returns the model itself
126
+ def self.build_from_hash(attributes)
127
+ return nil unless attributes.is_a?(Hash)
128
+ attributes = attributes.transform_keys(&:to_sym)
129
+ transformed_hash = {}
130
+ openapi_types.each_pair do |key, type|
131
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
132
+ transformed_hash["#{key}"] = nil
133
+ elsif type =~ /\AArray<(.*)>/i
134
+ # check to ensure the input is an array given that the attribute
135
+ # is documented as an array but the input is not
136
+ if attributes[attribute_map[key]].is_a?(Array)
137
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
138
+ end
139
+ elsif !attributes[attribute_map[key]].nil?
140
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
141
+ end
142
+ end
143
+ new(transformed_hash)
144
+ end
145
+
146
+ # Returns the object in the form of hash
147
+ # @return [Hash] Returns the object in the form of hash
148
+ def to_hash
149
+ hash = {}
150
+ self.class.attribute_map.each_pair do |attr, param|
151
+ value = self.send(attr)
152
+ if value.nil?
153
+ is_nullable = self.class.openapi_nullable.include?(attr)
154
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
155
+ end
156
+
157
+ hash[param] = _to_hash(value)
158
+ end
159
+ hash
160
+ end
161
+
162
+ end
163
+
164
+ end
@@ -11,5 +11,5 @@ Generator version: 7.19.0
11
11
  =end
12
12
 
13
13
  module Zernio
14
- VERSION = '0.0.782'
14
+ VERSION = '0.0.783'
15
15
  end
data/lib/zernio-sdk.rb CHANGED
@@ -1557,13 +1557,19 @@ require 'zernio-sdk/models/uploaded_file'
1557
1557
  require 'zernio-sdk/models/uploaded_or_derived_audience'
1558
1558
  require 'zernio-sdk/models/uploaded_or_derived_audience_companies_inner'
1559
1559
  require 'zernio-sdk/models/uploaded_or_derived_audience_match_rules_inner'
1560
+ require 'zernio-sdk/models/usage_attribution_group'
1561
+ require 'zernio-sdk/models/usage_attribution_slice'
1562
+ require 'zernio-sdk/models/usage_attribution_slice_by_product'
1560
1563
  require 'zernio-sdk/models/usage_metering'
1564
+ require 'zernio-sdk/models/usage_metering_attribution'
1561
1565
  require 'zernio-sdk/models/usage_metering_call_usage'
1562
1566
  require 'zernio-sdk/models/usage_metering_call_usage_whatsapp'
1563
1567
  require 'zernio-sdk/models/usage_metering_days_inner'
1564
1568
  require 'zernio-sdk/models/usage_metering_line_items_inner'
1565
1569
  require 'zernio-sdk/models/usage_metering_peaks'
1566
1570
  require 'zernio-sdk/models/usage_metering_period'
1571
+ require 'zernio-sdk/models/usage_metering_scope'
1572
+ require 'zernio-sdk/models/usage_metering_scope_one_of'
1567
1573
  require 'zernio-sdk/models/usage_metering_tax'
1568
1574
  require 'zernio-sdk/models/usage_metering_totals'
1569
1575
  require 'zernio-sdk/models/usage_stats'
data/openapi.yaml CHANGED
@@ -6960,14 +6960,14 @@ components:
6960
6960
  totalUsd: { type: number }
6961
6961
  quantity: { type: number }
6962
6962
  peaks:
6963
- type: object
6964
- description: Peak counts over the window (Metronome COUNT metrics + live active-number count).
6963
+ type: [object, "null"]
6964
+ description: 'Peak counts over the window (Metronome COUNT metrics + live active-number count). Null when `profileId` / `accountId` is set.'
6965
6965
  properties:
6966
6966
  accounts: { type: integer }
6967
6967
  numbers: { type: integer }
6968
6968
  callUsage:
6969
- type: object
6970
- description: Billable call volumes over the window.
6969
+ type: [object, "null"]
6970
+ description: 'Billable call volumes over the window. Null when `profileId` / `accountId` is set.'
6971
6971
  properties:
6972
6972
  whatsapp:
6973
6973
  type: object
@@ -7001,6 +7001,61 @@ components:
7001
7001
  ratePercent: { type: [number, "null"], description: "Combined rate percentage, e.g. 21." }
7002
7002
  jurisdictionLabel: { type: [string, "null"], description: 'Human jurisdiction label, e.g. "ES VAT" or "WA sales tax".' }
7003
7003
  reverseCharge: { type: boolean, description: True for EU/UK B2B reverse charge (0 tax added by design). }
7004
+ attribution:
7005
+ type: object
7006
+ description: 'Present with `groupBy`. The window''s spend split per profile or account; `sum(groups) + unattributed` equals `totals` per product.'
7007
+ properties:
7008
+ groupBy:
7009
+ type: string
7010
+ enum: [profile, account]
7011
+ groups:
7012
+ type: array
7013
+ items:
7014
+ $ref: '#/components/schemas/UsageAttributionGroup'
7015
+ unattributed:
7016
+ $ref: '#/components/schemas/UsageAttributionSlice'
7017
+ description: '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.'
7018
+ totals:
7019
+ $ref: '#/components/schemas/UsageAttributionSlice'
7020
+ description: 'The window totals; for a restricted principal, the sum of the visible groups.'
7021
+ restricted:
7022
+ type: boolean
7023
+ description: 'True when the caller (profile-scoped API key or member) cannot see every profile: `groups` are filtered, `totals` sum them, `unattributed` is zero, and the top-level `days` / `totals` / `lineItems` are projected onto the visible groups with `peaks`, `callUsage` and `tax` null.'
7024
+ scope:
7025
+ description: 'Present with `profileId` / `accountId`: echoes the group the payload was projected onto.'
7026
+ oneOf:
7027
+ - type: object
7028
+ required: [profileId]
7029
+ properties:
7030
+ profileId: { type: string }
7031
+ - type: object
7032
+ required: [accountId]
7033
+ properties:
7034
+ accountId: { type: string }
7035
+ UsageAttributionGroup:
7036
+ allOf:
7037
+ - $ref: '#/components/schemas/UsageAttributionSlice'
7038
+ - type: object
7039
+ required: [key]
7040
+ properties:
7041
+ key: { type: string, description: 'Profile id or account id, per `groupBy`.' }
7042
+ UsageAttributionSlice:
7043
+ type: object
7044
+ properties:
7045
+ byProduct:
7046
+ type: object
7047
+ description: USD per product family.
7048
+ properties:
7049
+ accounts: { type: number }
7050
+ numbers: { type: number }
7051
+ calls: { type: number }
7052
+ sms: { type: number }
7053
+ verify: { type: number }
7054
+ dlc: { type: number }
7055
+ xApi: { type: number }
7056
+ credits: { type: number }
7057
+ other: { type: number }
7058
+ totalUsd: { type: number }
7004
7059
  UsageStats:
7005
7060
  type: object
7006
7061
  description: |
@@ -13856,6 +13911,20 @@ paths:
13856
13911
  Also served at `GET /v1/usage/daily`. Usage-based accounts only —
13857
13912
  legacy Stripe accounts get `{ "supported": false, "days": [] }`.
13858
13913
 
13914
+ **Attribution (metering mode):** `groupBy=profile|account` adds an
13915
+ `attribution` breakdown of the window's spend per profile or account,
13916
+ assembled from your own records and pro-rated against the invoice so
13917
+ `sum(groups) + unattributed` equals `totals` exactly. `profileId` /
13918
+ `accountId` instead project the whole payload (`days`, `totals`,
13919
+ `lineItems`) onto that one group; `peaks`, `callUsage` and `tax` are
13920
+ then `null` (workspace-level facts). Projected `days` spread the
13921
+ group's period share over each day (usage is attributed per period,
13922
+ not per day). Profile-scoped API keys and members only see their
13923
+ profiles' groups (`attribution.restricted: true`, with `totals`
13924
+ summing the visible groups). Credits, 10DLC fees and Verify are always
13925
+ unattributed. `profileId` / `accountId` on their own do not select
13926
+ metering mode: pair them with `range`.
13927
+
13859
13928
  For per-domain consumption *volumes* use `GET /v1/usage/calls` and
13860
13929
  `GET /v1/usage/sms`. For the billing statement (balance, credits,
13861
13930
  caps, payment status) use `GET /v1/billing`.
@@ -13902,6 +13971,23 @@ paths:
13902
13971
  Bucketing of the `days` series: `day` (one row per UTC day),
13903
13972
  `month` (one row per calendar month, dated to the 1st), or `total`
13904
13973
  (no series — read `totals`). Does not affect `totals`.
13974
+ - name: groupBy
13975
+ in: query
13976
+ required: false
13977
+ schema:
13978
+ type: string
13979
+ enum: [profile, account]
13980
+ description: '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`).'
13981
+ - name: profileId
13982
+ in: query
13983
+ required: false
13984
+ schema: { type: string }
13985
+ description: '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).'
13986
+ - name: accountId
13987
+ in: query
13988
+ required: false
13989
+ schema: { type: string }
13990
+ description: '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.'
13905
13991
  responses:
13906
13992
  '200':
13907
13993
  description: |
@@ -76,13 +76,16 @@ describe 'UsageApi' do
76
76
 
77
77
  # unit tests for get_usage
78
78
  # Usage snapshot (default) or billed-spend metering (with params)
79
- # 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;.
79
+ # 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;.
80
80
  # @param [Hash] opts the optional parameters
81
81
  # @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.
82
82
  # @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;.
83
83
  # @option opts [Date] :from Inclusive start (UTC date). Required when &#x60;range&#x3D;custom&#x60;.
84
84
  # @option opts [Date] :to Inclusive end (UTC date). Required when &#x60;range&#x3D;custom&#x60;. Max span 366 days.
85
85
  # @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;.
86
+ # @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;).
87
+ # @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).
88
+ # @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.
86
89
  # @return [GetUsage200Response]
87
90
  describe 'get_usage test' do
88
91
  it 'should work' do
@@ -0,0 +1,48 @@
1
+ =begin
2
+ #Zernio API
3
+
4
+ #API reference for Zernio. Authenticate with a Bearer API key. Base URL: https://zernio.com/api Versioning and deprecation: all endpoints are versioned in the URL path (current version: /v1). Breaking changes only ship in a new path version; existing versions keep working. Deprecated operations are marked 'deprecated: true' in this spec and announced in the changelog (https://zernio.com/changelog) before removal. Errors: every 4xx/5xx response is application/json with a machine-readable 'code' and a human-readable 'error' message (see the ErrorResponse schema).
5
+
6
+ The version of the OpenAPI document: 1.0.4
7
+ Contact: support@zernio.com
8
+ Generated by: https://openapi-generator.tech
9
+ Generator version: 7.19.0
10
+
11
+ =end
12
+
13
+ require 'spec_helper'
14
+ require 'json'
15
+ require 'date'
16
+
17
+ # Unit tests for Zernio::UsageAttributionGroup
18
+ # Automatically generated by openapi-generator (https://openapi-generator.tech)
19
+ # Please update as you see appropriate
20
+ describe Zernio::UsageAttributionGroup do
21
+ #let(:instance) { Zernio::UsageAttributionGroup.new }
22
+
23
+ describe 'test an instance of UsageAttributionGroup' do
24
+ it 'should create an instance of UsageAttributionGroup' do
25
+ # uncomment below to test the instance creation
26
+ #expect(instance).to be_instance_of(Zernio::UsageAttributionGroup)
27
+ end
28
+ end
29
+
30
+ describe 'test attribute "by_product"' do
31
+ it 'should work' do
32
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
33
+ end
34
+ end
35
+
36
+ describe 'test attribute "total_usd"' do
37
+ it 'should work' do
38
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
39
+ end
40
+ end
41
+
42
+ describe 'test attribute "key"' do
43
+ it 'should work' do
44
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
45
+ end
46
+ end
47
+
48
+ end
@@ -0,0 +1,84 @@
1
+ =begin
2
+ #Zernio API
3
+
4
+ #API reference for Zernio. Authenticate with a Bearer API key. Base URL: https://zernio.com/api Versioning and deprecation: all endpoints are versioned in the URL path (current version: /v1). Breaking changes only ship in a new path version; existing versions keep working. Deprecated operations are marked 'deprecated: true' in this spec and announced in the changelog (https://zernio.com/changelog) before removal. Errors: every 4xx/5xx response is application/json with a machine-readable 'code' and a human-readable 'error' message (see the ErrorResponse schema).
5
+
6
+ The version of the OpenAPI document: 1.0.4
7
+ Contact: support@zernio.com
8
+ Generated by: https://openapi-generator.tech
9
+ Generator version: 7.19.0
10
+
11
+ =end
12
+
13
+ require 'spec_helper'
14
+ require 'json'
15
+ require 'date'
16
+
17
+ # Unit tests for Zernio::UsageAttributionSliceByProduct
18
+ # Automatically generated by openapi-generator (https://openapi-generator.tech)
19
+ # Please update as you see appropriate
20
+ describe Zernio::UsageAttributionSliceByProduct do
21
+ #let(:instance) { Zernio::UsageAttributionSliceByProduct.new }
22
+
23
+ describe 'test an instance of UsageAttributionSliceByProduct' do
24
+ it 'should create an instance of UsageAttributionSliceByProduct' do
25
+ # uncomment below to test the instance creation
26
+ #expect(instance).to be_instance_of(Zernio::UsageAttributionSliceByProduct)
27
+ end
28
+ end
29
+
30
+ describe 'test attribute "accounts"' do
31
+ it 'should work' do
32
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
33
+ end
34
+ end
35
+
36
+ describe 'test attribute "numbers"' do
37
+ it 'should work' do
38
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
39
+ end
40
+ end
41
+
42
+ describe 'test attribute "calls"' do
43
+ it 'should work' do
44
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
45
+ end
46
+ end
47
+
48
+ describe 'test attribute "sms"' do
49
+ it 'should work' do
50
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
51
+ end
52
+ end
53
+
54
+ describe 'test attribute "verify"' do
55
+ it 'should work' do
56
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
57
+ end
58
+ end
59
+
60
+ describe 'test attribute "dlc"' do
61
+ it 'should work' do
62
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
63
+ end
64
+ end
65
+
66
+ describe 'test attribute "x_api"' do
67
+ it 'should work' do
68
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
69
+ end
70
+ end
71
+
72
+ describe 'test attribute "credits"' do
73
+ it 'should work' do
74
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
75
+ end
76
+ end
77
+
78
+ describe 'test attribute "other"' do
79
+ it 'should work' do
80
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
81
+ end
82
+ end
83
+
84
+ end
@@ -0,0 +1,42 @@
1
+ =begin
2
+ #Zernio API
3
+
4
+ #API reference for Zernio. Authenticate with a Bearer API key. Base URL: https://zernio.com/api Versioning and deprecation: all endpoints are versioned in the URL path (current version: /v1). Breaking changes only ship in a new path version; existing versions keep working. Deprecated operations are marked 'deprecated: true' in this spec and announced in the changelog (https://zernio.com/changelog) before removal. Errors: every 4xx/5xx response is application/json with a machine-readable 'code' and a human-readable 'error' message (see the ErrorResponse schema).
5
+
6
+ The version of the OpenAPI document: 1.0.4
7
+ Contact: support@zernio.com
8
+ Generated by: https://openapi-generator.tech
9
+ Generator version: 7.19.0
10
+
11
+ =end
12
+
13
+ require 'spec_helper'
14
+ require 'json'
15
+ require 'date'
16
+
17
+ # Unit tests for Zernio::UsageAttributionSlice
18
+ # Automatically generated by openapi-generator (https://openapi-generator.tech)
19
+ # Please update as you see appropriate
20
+ describe Zernio::UsageAttributionSlice do
21
+ #let(:instance) { Zernio::UsageAttributionSlice.new }
22
+
23
+ describe 'test an instance of UsageAttributionSlice' do
24
+ it 'should create an instance of UsageAttributionSlice' do
25
+ # uncomment below to test the instance creation
26
+ #expect(instance).to be_instance_of(Zernio::UsageAttributionSlice)
27
+ end
28
+ end
29
+
30
+ describe 'test attribute "by_product"' do
31
+ it 'should work' do
32
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
33
+ end
34
+ end
35
+
36
+ describe 'test attribute "total_usd"' do
37
+ it 'should work' do
38
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
39
+ end
40
+ end
41
+
42
+ end