metrifox-sdk 1.0.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dd2f3f03c15f2b2706851f83e95ddab68004fb5bf722201eae1301e2e5eb0ce9
4
- data.tar.gz: 4cc5c6d239788de18628f4a929a2d6a328816ad74372afdf703e0f5993c87f78
3
+ metadata.gz: 1dff9fd808bc32d6349ca7a116713b9985ed31e1bd77bf49fd52d96d72ebedb3
4
+ data.tar.gz: 03364bfa5c26be341eee0ba665bef63913e1992ad82edd0d14123fdb1e21d607
5
5
  SHA512:
6
- metadata.gz: d429ea4b6554d8da627f4b98687eadf40a02c6cc6a5b98cf8a528cb0f9eb171c16463a530dac6646d63927591080a77f40632ddf71c532cc664abcf5155694ea
7
- data.tar.gz: 78b222b28144cfef43f03f26941764fd914bcbfa6d80f5423b6d107833700ab9d6dd55aecc2075e43d927261a5e470bab43bfb8d3c27a9290b1cc9e00b7aae06
6
+ metadata.gz: ffe66393b2b92925c2f3dc15cc699b7129ca06fa8baf7a06eb73fc635637d2c42a8c193a94ca17a1f2405aa7e119a6725c3de225ef779db58301ac05367cebaf
7
+ data.tar.gz: e271a28735a68ce97be07578c748fd8e01247bdbb633112fbcdd664a1a945c028adac9f549d776e7cc452fd4d68520df7292f3ee30595477d1266f58afbc070b
data/CHANGELOG.md CHANGED
@@ -3,10 +3,11 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
5
  ## [Unreleased]
6
+ - Update usage access and recording to call the meter service (`https://api-meter.metrifox.com`).
6
7
 
7
- ## [1.0.0] - 2025-09-01
8
+ ## [1.0.3] - 2025-09-01
8
9
  - Initial release
9
10
  - Access control functionality
10
11
  - Usage tracking
11
12
  - Customer management
12
- - CSV upload support
13
+ - CSV upload support
data/README.md CHANGED
@@ -35,6 +35,7 @@ METRIFOX_SDK = MetrifoxSDK.init({ api_key: "your-api-key"})
35
35
  # Or set environment variable
36
36
  ENV["METRIFOX_API_KEY"] = "your-api-key"
37
37
  METRIFOX_SDK = MetrifoxSDK.init
38
+
38
39
  ```
39
40
 
40
41
  ### Access Control
@@ -46,7 +47,28 @@ response = METRIFOX_SDK.usages.check_access({
46
47
  customer_key: "customer_123"
47
48
  })
48
49
 
49
- puts response["can_access"] # true/false
50
+ puts response["data"]["can_access"] # true/false
51
+ ```
52
+
53
+ > Access checks are now served by the Metrifox Meter service (`https://api-meter.metrifox.com`).
54
+ Example response payload:
55
+
56
+ ```json
57
+ {
58
+ "data": {
59
+ "customer_key": "cust-mit7k5v8obzs",
60
+ "feature_key": "feature_seats",
61
+ "requested_quantity": 1,
62
+ "can_access": true,
63
+ "unlimited": false,
64
+ "balance": 4,
65
+ "used_quantity": 0,
66
+ "entitlement_active": true,
67
+ "prepaid": false,
68
+ "wallet_balance": 0,
69
+ "message": "Feature found"
70
+ }
71
+ }
50
72
  ```
51
73
 
52
74
  ### Usage Tracking
@@ -56,17 +78,27 @@ puts response["can_access"] # true/false
56
78
  response = METRIFOX_SDK.usages.record_usage({
57
79
  customer_key: "customer_123",
58
80
  event_name: "api_call",
59
- amount: 1
81
+ amount: 1,
82
+ event_id: "evt_12345", # required idempotency key
83
+ timestamp: (Time.now.to_f * 1000).to_i # recommended (milliseconds)
60
84
  })
85
+ puts response["message"] # "Event received"
86
+ puts response["data"]["quantity"] # 1
87
+ ```
88
+
89
+ The usage event endpoint now returns a simple payload with the recorded `data` and a `message` confirming the event reception.
90
+
91
+ > You can send either an `event_name` or a `feature_key` when recording usage events.
61
92
 
93
+ ```ruby
62
94
  # Advanced usage recording with additional fields
63
95
  response = METRIFOX_SDK.usages.record_usage({
64
96
  customer_key: "customer_123",
65
- event_name: "api_call",
97
+ event_name: "api_call", # Or use feature_key
66
98
  amount: 1,
99
+ event_id: "event_uuid_123", # required idempotency key
67
100
  credit_used: 5,
68
- event_id: "event_uuid_123",
69
- timestamp: 1640995200,
101
+ timestamp: (Time.now.to_f * 1000).to_i,
70
102
  metadata: {
71
103
  source: "web_app",
72
104
  feature: "premium_search"
@@ -76,23 +108,36 @@ response = METRIFOX_SDK.usages.record_usage({
76
108
  # Using structured request object
77
109
  usage_request = MetrifoxSDK::Types::UsageEventRequest.new(
78
110
  customer_key: "customer_123",
79
- event_name: "api_call",
111
+ feature_key: "feat_my_feat_234", # OR use event_name
80
112
  amount: 1,
81
113
  credit_used: 5,
82
114
  event_id: "event_uuid_123",
83
- timestamp: Time.now.to_i,
115
+ timestamp: (Time.now.to_f * 1000).to_i,
84
116
  metadata: { source: "mobile_app" }
85
117
  )
86
118
 
87
119
  response = METRIFOX_SDK.usages.record_usage(usage_request)
88
120
  ```
89
121
 
122
+ Sample response body:
123
+
124
+ ```json
125
+ {
126
+ "data": {
127
+ "customer_key": "cust-mit7k5v8obzs",
128
+ "quantity": 1,
129
+ "feature_key": "feature_job_posts"
130
+ },
131
+ "message": "Event received"
132
+ }
133
+ ```
134
+
90
135
  ### Customer Management
91
136
 
92
137
  ```ruby
93
- # Create customer
138
+ # Create customer (customer_key is REQUIRED)
94
139
  customer_data = {
95
- customer_key: "customer_123",
140
+ customer_key: "customer_123", # Required - unique identifier for the customer
96
141
  customer_type: "BUSINESS",
97
142
  primary_email: "customer@example.com",
98
143
  legal_name: "Acme Corp",
@@ -101,10 +146,11 @@ customer_data = {
101
146
 
102
147
  response = METRIFOX_SDK.customers.create(customer_data)
103
148
 
104
- # Update customer
149
+ # Update customer (customer_key cannot be changed and is passed as a parameter)
105
150
  update_data = {
106
151
  display_name: "ACME Corporation",
107
152
  website_url: "https://acme.com"
153
+ # Note: customer_key is NOT included here - it's immutable
108
154
  }
109
155
 
110
156
  response = METRIFOX_SDK.customers.update("customer_123", update_data)
@@ -115,6 +161,10 @@ response = METRIFOX_SDK.customers.get_customer({ customer_key: "customer_123" })
115
161
  # Get customer details
116
162
  response = METRIFOX_SDK.customers.get_details({ customer_key: "customer_123" })
117
163
 
164
+ # Check for an active subscription
165
+ has_active_subscription = MetrifoxSDK.customers.has_active_subscription?(customer_key: "customer_123")
166
+ puts has_active_subscription # true or false
167
+
118
168
  # List customers
119
169
  response = METRIFOX_SDK.customers.list
120
170
 
@@ -194,26 +244,29 @@ response = METRIFOX_SDK.usages.check_access({
194
244
 
195
245
  ## Type Safety with Structs
196
246
 
197
- The SDK provides structured types for better type safety:
247
+ The SDK exposes lightweight structs for the usage and checkout helpers when you want a bit more structure:
198
248
 
199
249
  ```ruby
200
- # Using structured request objects
201
- access_request = MetrifoxSDK::Types::AccessCheckRequest.new(
202
- feature_key: "premium_feature",
203
- customer_key: "customer_123"
250
+ # Usage events (event_id required for idempotency)
251
+ usage_request = MetrifoxSDK::Types::UsageEventRequest.new(
252
+ customer_key: "customer_123",
253
+ feature_key: "feature_seats",
254
+ amount: 1,
255
+ event_id: "event_uuid_123",
256
+ timestamp: (Time.now.to_f * 1000).to_i,
257
+ metadata: { source: "mobile_app" }
204
258
  )
205
259
 
206
- response = METRIFOX_SDK.usages.check_access(access_request)
260
+ response = METRIFOX_SDK.usages.record_usage(usage_request)
207
261
 
208
- # Customer creation with structured data
209
- customer_request = MetrifoxSDK::Types::CustomerCreateRequest.new(
210
- customer_key: "customer_123",
211
- customer_type: MetrifoxSDK::Types::CustomerType::BUSINESS,
212
- primary_email: "customer@example.com",
213
- legal_name: "Acme Corp"
262
+ # Checkout configuration
263
+ checkout_config = MetrifoxSDK::Types::CheckoutConfig.new(
264
+ offering_key: "premium_plan",
265
+ billing_interval: "monthly",
266
+ customer_key: "customer_123"
214
267
  )
215
268
 
216
- response = METRIFOX_SDK.customers.create(customer_request)
269
+ checkout_url = METRIFOX_SDK.checkout.url(checkout_config)
217
270
  ```
218
271
 
219
272
  ## Error Handling
@@ -11,5 +11,13 @@ module MetrifoxSDK::Checkout
11
11
  data = parse_response(response, "Failed to get tenant checkout settings")
12
12
  data.dig("data", "checkout_username")
13
13
  end
14
+
15
+ def generate_checkout_url(base_url, api_key, query_params)
16
+ uri = URI.join(base_url, "products/offerings/generate-checkout-url")
17
+ uri.query = URI.encode_www_form(query_params)
18
+ response = make_request(uri, "GET", api_key)
19
+ data = parse_response(response, "Failed to generate checkout URL")
20
+ data.dig("data", "checkout_url")
21
+ end
14
22
  end
15
23
  end
@@ -6,7 +6,7 @@ module MetrifoxSDK
6
6
  class Module < BaseModule
7
7
  def url(config)
8
8
  validate_api_key!
9
-
9
+
10
10
  # Handle both hash and struct access patterns
11
11
  offering_key = get_value(config, :offering_key)
12
12
  billing_interval = get_value(config, :billing_interval)
@@ -14,20 +14,16 @@ module MetrifoxSDK
14
14
 
15
15
  raise ArgumentError, "offering_key is required" if offering_key.nil? || offering_key.empty?
16
16
 
17
- checkout_key = get_checkout_key
18
- raise StandardError, "Checkout Key could not be retrieved. Ensure the API key is valid" if checkout_key.nil? || checkout_key.empty?
19
-
20
- url_string = "#{web_app_base_url}/#{checkout_key}/checkout/#{offering_key}"
21
- uri = URI(url_string)
22
-
23
- # Add query parameters if provided
24
- query_params = {}
25
- query_params["billing_period"] = billing_interval if billing_interval && !billing_interval.empty?
26
- query_params["customer"] = customer_key if customer_key && !customer_key.empty?
27
-
28
- uri.query = URI.encode_www_form(query_params) unless query_params.empty?
29
-
30
- uri.to_s
17
+ # Build query parameters
18
+ query_params = { offering_key: offering_key }
19
+ query_params[:billing_interval] = billing_interval if billing_interval && !billing_interval.empty?
20
+ query_params[:customer_key] = customer_key if customer_key && !customer_key.empty?
21
+
22
+ # Call API to generate checkout URL
23
+ checkout_url = api.generate_checkout_url(base_url, api_key, query_params)
24
+ raise StandardError, "Checkout URL could not be generated" if checkout_url.nil? || checkout_url.empty?
25
+
26
+ checkout_url
31
27
  end
32
28
 
33
29
  private
@@ -4,13 +4,18 @@ module MetrifoxSDK
4
4
  class Client
5
5
  include MetrifoxSDK::UtilMethods
6
6
 
7
- attr_reader :config, :api_key, :base_url, :web_app_base_url
7
+ DEFAULT_BASE_URL = "https://api.metrifox.com/api/v1/".freeze
8
+ DEFAULT_WEB_APP_BASE_URL = "https://app.metrifox.com".freeze
9
+ METER_SERVICE_BASE_URL = "https://api-meter.metrifox.com/".freeze
10
+
11
+ attr_reader :config, :api_key, :base_url, :web_app_base_url, :meter_service_base_url
8
12
 
9
13
  def initialize(config = {})
10
14
  @config = config
11
15
  @api_key = config[:api_key] || get_api_key_from_environment
12
- @base_url = config[:base_url] || "https://api.metrifox.com/api/v1/"
13
- @web_app_base_url = config[:web_app_base_url] || "https://app.metrifox.com"
16
+ @base_url = config[:base_url] || DEFAULT_BASE_URL
17
+ @web_app_base_url = config[:web_app_base_url] || DEFAULT_WEB_APP_BASE_URL
18
+ @meter_service_base_url = METER_SERVICE_BASE_URL
14
19
  end
15
20
 
16
21
  def customers
@@ -41,6 +41,12 @@ module MetrifoxSDK::Customers
41
41
  parse_response(response, "Failed to Fetch Customer Details")
42
42
  end
43
43
 
44
+ def customer_active_subscription_request(base_url, api_key, customer_key)
45
+ uri = URI.join(base_url, "customers/#{customer_key}/check-active-subscription")
46
+ response = make_request(uri, "GET", api_key)
47
+ parse_response(response, "Failed to Check Active Subscription")
48
+ end
49
+
44
50
  def customer_list_request(base_url, api_key, request_payload = {})
45
51
  uri = URI.join(base_url, "customers")
46
52
 
@@ -110,4 +116,4 @@ module MetrifoxSDK::Customers
110
116
  end
111
117
  end
112
118
  end
113
- end
119
+ end
@@ -19,16 +19,31 @@ module MetrifoxSDK
19
19
  api.customer_get_request(base_url, api_key, request_payload)
20
20
  end
21
21
 
22
+ def get(request_payload)
23
+ get_customer(request_payload)
24
+ end
25
+
22
26
  def get_details(request_payload)
23
27
  validate_api_key!
24
28
  api.customer_details_get_request(base_url, api_key, request_payload)
25
29
  end
26
30
 
31
+ def has_active_subscription?(customer_key:)
32
+ validate_api_key!
33
+ result = api.customer_active_subscription_request(base_url, api_key, customer_key)
34
+ data = result["data"] || {}
35
+ data["has_active_subscription"]
36
+ end
37
+
27
38
  def delete_customer(request_payload)
28
39
  validate_api_key!
29
40
  api.customer_delete_request(base_url, api_key, request_payload)
30
41
  end
31
42
 
43
+ def delete(request_payload)
44
+ delete_customer(request_payload)
45
+ end
46
+
32
47
  def list(request_payload = {})
33
48
  validate_api_key!
34
49
  api.customer_list_request(base_url, api_key, request_payload)
@@ -46,4 +61,4 @@ module MetrifoxSDK
46
61
  end
47
62
  end
48
63
  end
49
- end
64
+ end
@@ -1,115 +1,14 @@
1
1
  module MetrifoxSDK
2
2
  module Types
3
- # Enums
4
- module TaxStatus
5
- TAXABLE = "TAXABLE"
6
- TAX_EXEMPT = "TAX_EXEMPT"
7
- REVERSE_CHARGE = "REVERSE_CHARGE"
8
- end
9
-
10
- module CustomerType
11
- BUSINESS = "BUSINESS"
12
- INDIVIDUAL = "INDIVIDUAL"
13
- end
14
-
15
- # Value objects / Structs
16
- EmailAddress = Struct.new(:email, :is_primary, keyword_init: true)
17
- PhoneNumber = Struct.new(:phone_number, :country_code, :is_primary, keyword_init: true)
18
-
19
- Address = Struct.new(
20
- :country, :address_line_one, :address_line_two, :city,
21
- :state, :zip_code, :phone_number, keyword_init: true
22
- )
23
-
24
- BillingConfig = Struct.new(
25
- :preferred_payment_gateway, :preferred_payment_method, :billing_email,
26
- :billing_address, :payment_reminder_days, keyword_init: true
27
- )
28
-
29
- TaxIdentification = Struct.new(:type, :number, :country, keyword_init: true)
30
-
31
- ContactPerson = Struct.new(
32
- :first_name, :last_name, :email_address, :designation,
33
- :department, :is_primary, :phone_number, keyword_init: true
34
- )
35
-
36
- PaymentTerm = Struct.new(:type, :value, keyword_init: true)
37
-
38
- # Request/Response objects
39
- AccessCheckRequest = Struct.new(:feature_key, :customer_key, keyword_init: true)
40
-
41
- AccessResponse = Struct.new(
42
- :message, :can_access, :customer_id, :feature_key, :required_quantity,
43
- :used_quantity, :included_usage, :next_reset_at, :quota, :unlimited,
44
- :carryover_quantity, :balance, keyword_init: true
45
- )
46
-
47
3
  UsageEventRequest = Struct.new(
48
- :customer_key, :event_name, :amount, :credit_used, :event_id, :timestamp, :metadata,
4
+ :customer_key, :event_name, :feature_key, :amount, :credit_used, :event_id, :timestamp, :metadata,
49
5
  keyword_init: true
50
6
  ) do
51
- def initialize(customer_key:, event_name:, amount: 1, credit_used: nil, event_id: nil, timestamp: nil, metadata: {})
7
+ def initialize(customer_key:, event_name: nil, feature_key: nil, amount: 1, credit_used: nil, event_id: nil, timestamp: nil, metadata: {})
52
8
  super
53
9
  end
54
10
  end
55
11
 
56
- UsageEventResponse = Struct.new(:message, :event_name, :customer_key, keyword_init: true)
57
-
58
- CustomerCreateRequest = Struct.new(
59
- # Core fields
60
- :customer_key, :customer_type, :primary_email, :primary_phone,
61
- # Business fields
62
- :legal_name, :display_name, :legal_number, :tax_identification_number,
63
- :logo_url, :website_url, :account_manager,
64
- # Individual fields
65
- :first_name, :middle_name, :last_name, :date_of_birth, :billing_email,
66
- # Preferences
67
- :timezone, :language, :currency, :tax_status,
68
- # Address fields
69
- :address_line1, :address_line2, :city, :state, :country, :zip_code,
70
- # Shipping address fields
71
- :shipping_address_line1, :shipping_address_line2, :shipping_city,
72
- :shipping_state, :shipping_country, :shipping_zip_code,
73
- # Complex fields
74
- :billing_configuration, :tax_identifications, :contact_people,
75
- :payment_terms, :metadata, keyword_init: true
76
- )
77
-
78
- CustomerUpdateRequest = Struct.new(
79
- # Core fields
80
- :customer_key, :customer_type, :primary_email, :primary_phone, :billing_email,
81
- # Business fields
82
- :legal_name, :display_name, :legal_number, :tax_identification_number,
83
- :logo_url, :website_url, :account_manager,
84
- # Individual fields
85
- :first_name, :middle_name, :last_name, :date_of_birth,
86
- # Preferences
87
- :timezone, :language, :currency, :tax_status,
88
- # Address fields
89
- :address_line1, :address_line2, :city, :state, :country, :zip_code,
90
- # Shipping address fields
91
- :shipping_address_line1, :shipping_address_line2, :shipping_city,
92
- :shipping_state, :shipping_country, :shipping_zip_code,
93
- # Complex fields
94
- :billing_configuration, :tax_identifications, :contact_people,
95
- :payment_terms, :metadata, :phone_numbers, :email_addresses, keyword_init: true
96
- )
97
-
98
- CustomerDeleteRequest = Struct.new(:customer_key, keyword_init: true)
99
- CustomerGetRequest = Struct.new(:customer_key, keyword_init: true)
100
-
101
- CustomerCSVSyncResponse = Struct.new(
102
- :status_code, :message, :data, :errors, :meta, keyword_init: true
103
- ) do
104
- CSVSyncData = Struct.new(
105
- :total_customers, :successful_upload_count, :failed_upload_count,
106
- :customers_added, :customers_failed, keyword_init: true
107
- )
108
- end
109
-
110
- APIResponse = Struct.new(:status_code, :message, :data, :errors, :meta, keyword_init: true)
111
-
112
- EmbedConfig = Struct.new(:container, :product_key, keyword_init: true)
113
12
  CheckoutConfig = Struct.new(:offering_key, :billing_interval, :customer_key, keyword_init: true)
114
13
  end
115
- end
14
+ end
@@ -22,7 +22,7 @@ module MetrifoxSDK::Usages
22
22
  parse_response(response, "Failed to check access")
23
23
  end
24
24
 
25
- def fetch_usage(base_url, api_key, request_payload)
25
+ def record_usage(base_url, api_key, request_payload)
26
26
  uri = URI.join(base_url, "usage/events")
27
27
 
28
28
  # Handle both hash and struct access patterns
@@ -33,18 +33,20 @@ module MetrifoxSDK::Usages
33
33
  event_id = get_value(request_payload, :event_id)
34
34
  timestamp = get_value(request_payload, :timestamp)
35
35
  metadata = get_value(request_payload, :metadata) || {}
36
+ feature_key = get_value(request_payload, :feature_key)
36
37
 
37
38
  body = {
38
- customer_key: customer_key,
39
- event_name: event_name,
40
- amount: amount
39
+ customer_key:,
40
+ amount:,
41
+ event_id:
41
42
  }
42
43
 
43
44
  # Add optional fields if present
44
45
  body[:credit_used] = credit_used if credit_used
45
- body[:event_id] = event_id if event_id && !event_id.empty?
46
46
  body[:timestamp] = timestamp if timestamp
47
47
  body[:metadata] = metadata if metadata
48
+ body[:feature_key] = feature_key if feature_key
49
+ body[:event_name] = event_name if event_name
48
50
 
49
51
  response = make_request(uri, "POST", api_key, body)
50
52
  parse_response(response, "Failed to record usage")
@@ -77,4 +79,4 @@ module MetrifoxSDK::Usages
77
79
  end
78
80
  end
79
81
  end
80
- end
82
+ end
@@ -6,12 +6,12 @@ module MetrifoxSDK
6
6
  class Module < BaseModule
7
7
  def check_access(request_payload)
8
8
  validate_api_key!
9
- api.fetch_access(base_url, api_key, request_payload)
9
+ api.fetch_access(meter_service_base_url, api_key, request_payload)
10
10
  end
11
11
 
12
12
  def record_usage(request_payload)
13
13
  validate_api_key!
14
- api.fetch_usage(base_url, api_key, request_payload)
14
+ api.record_usage(meter_service_base_url, api_key, request_payload)
15
15
  end
16
16
 
17
17
  def get_tenant_id
@@ -26,9 +26,13 @@ module MetrifoxSDK
26
26
 
27
27
  private
28
28
 
29
+ def meter_service_base_url
30
+ client.respond_to?(:meter_service_base_url) ? client.meter_service_base_url : base_url
31
+ end
32
+
29
33
  def api
30
34
  @api ||= API.new
31
35
  end
32
36
  end
33
37
  end
34
- end
38
+ end
@@ -1,3 +1,3 @@
1
1
  module MetrifoxSDK
2
- VERSION = '1.0.2'
2
+ VERSION = '1.1.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metrifox-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Metrifox
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2025-10-03 00:00:00.000000000 Z
10
+ date: 2025-12-12 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: json
@@ -138,7 +137,6 @@ metadata:
138
137
  homepage_uri: https://github.com/metrifox/metrifox-ruby
139
138
  source_code_uri: https://github.com/metrifox/metrifox-ruby
140
139
  changelog_uri: https://github.com/metrifox/metrifox-ruby/tree/main/CHANGELOG.md
141
- post_install_message:
142
140
  rdoc_options: []
143
141
  require_paths:
144
142
  - lib
@@ -153,8 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
151
  - !ruby/object:Gem::Version
154
152
  version: '0'
155
153
  requirements: []
156
- rubygems_version: 3.5.22
157
- signing_key:
154
+ rubygems_version: 3.6.2
158
155
  specification_version: 4
159
156
  summary: Ruby SDK for Metrifox API
160
157
  test_files: []