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.
- checksums.yaml +4 -4
- data/README.md +6 -0
- data/docs/UsageApi.md +8 -2
- data/docs/UsageAttributionGroup.md +22 -0
- data/docs/UsageAttributionSlice.md +20 -0
- data/docs/UsageAttributionSliceByProduct.md +34 -0
- data/docs/UsageMetering.md +5 -1
- data/docs/UsageMeteringAttribution.md +26 -0
- data/docs/UsageMeteringScope.md +49 -0
- data/docs/UsageMeteringScopeOneOf.md +18 -0
- data/lib/zernio-sdk/api/usage_api.rb +15 -2
- data/lib/zernio-sdk/models/usage_attribution_group.rb +190 -0
- data/lib/zernio-sdk/models/usage_attribution_slice.rb +156 -0
- data/lib/zernio-sdk/models/usage_attribution_slice_by_product.rb +220 -0
- data/lib/zernio-sdk/models/usage_metering.rb +22 -4
- data/lib/zernio-sdk/models/usage_metering_attribution.rb +223 -0
- data/lib/zernio-sdk/models/usage_metering_call_usage.rb +1 -1
- data/lib/zernio-sdk/models/usage_metering_peaks.rb +1 -1
- data/lib/zernio-sdk/models/usage_metering_scope.rb +105 -0
- data/lib/zernio-sdk/models/usage_metering_scope_one_of.rb +164 -0
- data/lib/zernio-sdk/version.rb +1 -1
- data/lib/zernio-sdk.rb +6 -0
- data/openapi.yaml +90 -4
- data/spec/api/usage_api_spec.rb +4 -1
- data/spec/models/usage_attribution_group_spec.rb +48 -0
- data/spec/models/usage_attribution_slice_by_product_spec.rb +84 -0
- data/spec/models/usage_attribution_slice_spec.rb +42 -0
- data/spec/models/usage_metering_attribution_spec.rb +64 -0
- data/spec/models/usage_metering_scope_one_of_spec.rb +36 -0
- data/spec/models/usage_metering_scope_spec.rb +32 -0
- data/spec/models/usage_metering_spec.rb +12 -0
- data/zernio-sdk-0.0.783.gem +0 -0
- metadata +26 -2
- 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
|
data/lib/zernio-sdk/version.rb
CHANGED
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: |
|
data/spec/api/usage_api_spec.rb
CHANGED
|
@@ -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 `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`.
|
|
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 `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`.
|
|
80
80
|
# @param [Hash] opts the optional parameters
|
|
81
81
|
# @option opts [Boolean] :reconcile Snapshot mode only. For Stripe subscription users, `true` forces a subscription reconciliation pass even when cached plan data looks complete.
|
|
82
82
|
# @option opts [String] :range 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`.
|
|
83
83
|
# @option opts [Date] :from Inclusive start (UTC date). Required when `range=custom`.
|
|
84
84
|
# @option opts [Date] :to Inclusive end (UTC date). Required when `range=custom`. Max span 366 days.
|
|
85
85
|
# @option opts [String] :granularity 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`.
|
|
86
|
+
# @option opts [String] :group_by 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`).
|
|
87
|
+
# @option opts [String] :profile_id 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).
|
|
88
|
+
# @option opts [String] :account_id 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.
|
|
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
|