flexops 1.0.1 → 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: 13d2f7754ba0f328f7deba370389156b15fa40b8e5a23b36f6eab43b8ddf6129
4
- data.tar.gz: 433300bc3d7dab3012f76b3e5450456a6a2fde313a31b032f8e5e21c61a2c0f1
3
+ metadata.gz: ae38cf941276d4053203fda4a44fb9ab1adb873d24bba9ec1de7fc634be3e7e2
4
+ data.tar.gz: 43b602d72cbac545bff0391aa2dee8ea28f73bd7807a6042ec17731fe7943881
5
5
  SHA512:
6
- metadata.gz: ce112d64b50b36231df3d187a6b2a093b66707b1425c556284666b8eb272a7353f6c1111008bcaaf9a9fc6ad592ea952645c8da70ecce24eb1e442898c388092
7
- data.tar.gz: c0409a3b240c0f18d2dba7993a682adf83281d3ef5c3223ded998b3f9c21a07a3f18ab32ec15337c08d42de377a5e2dd95cf488d8c730a7724bbb89382b607ec
6
+ metadata.gz: '0959231eed12a9abd27bc7d370ab9576e32393a131248e231f2d7bebb622c74c29c21596f55036c1af8df73a277a3cbb8ee282c516aca90fc787839c76f102dc'
7
+ data.tar.gz: 42fa01ac062f0f54ed7632e403a0d3a5ed37e3e942e6f11a45797b047f7f343c3b0419d354e83af9be217d58d1877a322ee7fee7fa6c79e9749e069cfca0f7cf
data/README.md CHANGED
@@ -35,28 +35,54 @@ client = FlexOps::Client.new(
35
35
 
36
36
  # Get shipping rates from all carriers
37
37
  rates = client.shipping.get_rates(
38
- from_address: {street1: "123 Main St", city: "New York", state: "NY", zip: "10001", country: "US"},
39
- to_address: {street1: "456 Oak Ave", city: "Los Angeles", state: "CA", zip: "90210", country: "US"},
40
- parcel: {weight: 16, weight_unit: "oz"}
38
+ origin: {addressLine1: "123 Main St", city: "New York", stateProvince: "NY", postalCode: "10001"},
39
+ destination: {addressLine1: "456 Oak Ave", city: "Los Angeles", stateProvince: "CA", postalCode: "90210"},
40
+ package: {weight: 16, weightUnit: "oz"}
41
41
  )
42
42
 
43
- # Create a label with the cheapest rate
44
- cheapest = rates["data"].min_by { |r| r["totalCost"].to_f }
45
- label = client.shipping.create_label(
46
- carrier: cheapest["carrier"],
47
- service: cheapest["service"],
48
- from_address: {name: "Warehouse", street1: "123 Main St", city: "New York", state: "NY", zip: "10001", country: "US"},
49
- to_address: {name: "Customer", street1: "456 Oak Ave", city: "Los Angeles", state: "CA", zip: "90210", country: "US"},
50
- parcel: {weight: 16, weight_unit: "oz"}
51
- )
52
-
53
- puts "Label URL: #{label["data"]["labelUrl"]}"
54
- puts "Tracking: #{label["data"]["trackingNumber"]}"
43
+ request = {
44
+ carrierCode: "USPS", serviceCode: "GROUND_ADVANTAGE",
45
+ origin: {name: "Warehouse", addressLine1: "123 Main St", city: "New York", stateProvince: "NY", postalCode: "10001", countryCode: "US"},
46
+ destination: {name: "Customer", addressLine1: "456 Oak Ave", city: "Los Angeles", stateProvince: "CA", postalCode: "90210", countryCode: "US"},
47
+ package: {weight: 16, weightUnit: "oz"},
48
+ maximumPostageAmount: 10.25 # Caller-approved ceiling in USD.
49
+ }
50
+ preview = client.shipping.create_label(request)
51
+ puts preview["quotedPostageAmount"]
52
+
53
+ # Call only after explicit caller approval, within five minutes.
54
+ purchase_approved_label = lambda do |purchase_key|
55
+ client.shipping.create_label(
56
+ request.merge(confirmationToken: preview["confirmationToken"]),
57
+ idempotency_key: purchase_key # Persist per purchase; reuse on retries.
58
+ )
59
+ end
55
60
 
56
61
  # Track a shipment
57
62
  info = client.shipping.track("9400111899223456789012")
58
63
  ```
59
64
 
65
+ ### Live label approval (1.1.0+)
66
+
67
+ The example below requires SDK 1.1.0 or later. Version 1.0.2 does not
68
+ include the per-call idempotency argument.
69
+
70
+ For live domestic single-label requests, `maximumPostageAmount` is required: positive
71
+ USD, at most two decimal places, up to 1,000,000. Missing or invalid values return
72
+ 400 `ApprovalRequired`. Omitting `confirmationToken` returns a raw 200 preview
73
+ (`status`, `quotedPostageAmount`, `maximumPostageAmount`, `currency`, `expiresAt`,
74
+ `confirmationToken`). After explicit approval, resubmit the same shipment and ceiling
75
+ with the token and a unique per-purchase `Idempotency-Key` header. The token expires
76
+ after five minutes. A successful purchase returns the raw 201 label, including
77
+ `labelId`, `trackingNumber`, `carrierCode`, and `labelData`, without a `data` wrapper.
78
+
79
+ Keep the same key and request across retries. An uncertain outcome needs reconciliation;
80
+ do not start another purchase with a new key. An expired approval returns 409
81
+ `ApprovalExpired`; obtain and explicitly approve a fresh preview when no purchase is
82
+ unresolved. The ceiling bounds postage authorization, not later adjustments or separate
83
+ fees. Sandbox execution bypasses approval; batch, return, and raw carrier routes have
84
+ separate contracts. The SDK never automatically confirms a preview.
85
+
60
86
  ## Authentication
61
87
 
62
88
  ### API key (recommended)
@@ -119,27 +145,31 @@ Every SDK method is a thin wrapper around the FlexOps REST API. If you want to v
119
145
 
120
146
  ```bash
121
147
  # Shop rates across all connected carriers
122
- curl -X POST https://gateway.flexops.io/api/workspaces/ws_abc123/shipping/rates \
148
+ curl -X POST https://gateway.flexops.io/api/shipping/rates \
123
149
  -H "X-API-Key: fxk_live_..." \
124
150
  -H "Content-Type: application/json" \
125
151
  -d '{
126
- "fromAddress": {"street1": "123 Main St", "city": "New York", "state": "NY", "zip": "10001", "country": "US"},
127
- "toAddress": {"street1": "456 Oak Ave", "city": "Los Angeles", "state": "CA", "zip": "90210", "country": "US"},
128
- "parcel": {"weight": 16, "weightUnit": "oz"}
152
+ "origin": {"addressLine1": "123 Main St", "city": "New York", "stateProvince": "NY", "postalCode": "10001", "countryCode": "US"},
153
+ "destination": {"addressLine1": "456 Oak Ave", "city": "Los Angeles", "stateProvince": "CA", "postalCode": "90210", "countryCode": "US"},
154
+ "package": {"weight": 16, "weightUnit": "oz"}
129
155
  }'
130
156
 
131
- # Create a label
157
+ # Preview a live label; this does not purchase it.
132
158
  curl -X POST https://gateway.flexops.io/api/workspaces/ws_abc123/shipping/labels \
133
159
  -H "X-API-Key: fxk_live_..." \
134
160
  -H "Content-Type: application/json" \
135
161
  -d '{
136
- "carrier": "USPS",
137
- "service": "PRIORITY_MAIL",
138
- "fromAddress": {"name": "Warehouse", "street1": "123 Main St", "city": "New York", "state": "NY", "zip": "10001", "country": "US"},
139
- "toAddress": {"name": "Customer", "street1": "456 Oak Ave", "city": "Los Angeles", "state": "CA", "zip": "90210", "country": "US"},
140
- "parcel": {"weight": 16, "weightUnit": "oz"}
162
+ "carrierCode": "USPS", "serviceCode": "GROUND_ADVANTAGE",
163
+ "origin": {"name": "Warehouse", "addressLine1": "123 Main St", "city": "New York", "stateProvince": "NY", "postalCode": "10001", "countryCode": "US"},
164
+ "destination": {"name": "Customer", "addressLine1": "456 Oak Ave", "city": "Los Angeles", "stateProvince": "CA", "postalCode": "90210", "countryCode": "US"},
165
+ "package": {"weight": 16, "weightUnit": "oz"},
166
+ "maximumPostageAmount": 10.25
141
167
  }'
142
168
 
169
+ # After explicit approval, resend the same body with confirmationToken from
170
+ # the preview and an Idempotency-Key header unique to this purchase.
171
+ # See the SDK example above; retain that key for retries.
172
+
143
173
  # Track a shipment
144
174
  curl https://gateway.flexops.io/api/workspaces/ws_abc123/shipping/track/9400111899223456789012 \
145
175
  -H "X-API-Key: fxk_live_..."
@@ -1,35 +1,35 @@
1
- # ***********************************************************************
2
- # Package : flexops
3
- # Author : FlexOps, LLC
4
- # Created : 2026-03-08
5
- #
6
- # Copyright (c) 2021-2026 by FlexOps, LLC. All rights reserved.
7
- # ***********************************************************************
8
-
9
- module FlexOps
10
- class Error < StandardError
11
- attr_reader :status, :code, :errors
12
-
13
- def initialize(message, status: 0, code: nil, errors: nil)
14
- super(message)
15
- @status = status
16
- @code = code
17
- @errors = errors
18
- end
19
- end
20
-
21
- class AuthError < Error
22
- def initialize(message = "Authentication required. Check your access token or API key.")
23
- super(message, status: 401, code: "UNAUTHORIZED")
24
- end
25
- end
26
-
27
- class RateLimitError < Error
28
- attr_reader :retry_after
29
-
30
- def initialize(retry_after: 0)
31
- super("Rate limited. Retry after #{retry_after}s", status: 429, code: "RATE_LIMITED")
32
- @retry_after = retry_after
33
- end
34
- end
35
- end
1
+ # ***********************************************************************
2
+ # Package : flexops
3
+ # Author : FlexOps, LLC
4
+ # Created : 2026-03-08
5
+ #
6
+ # Copyright (c) 2021-2026 by FlexOps, LLC. All rights reserved.
7
+ # ***********************************************************************
8
+
9
+ module FlexOps
10
+ class Error < StandardError
11
+ attr_reader :status, :code, :errors
12
+
13
+ def initialize(message, status: 0, code: nil, errors: nil)
14
+ super(message)
15
+ @status = status
16
+ @code = code
17
+ @errors = errors
18
+ end
19
+ end
20
+
21
+ class AuthError < Error
22
+ def initialize(message = "Authentication required. Check your access token or API key.")
23
+ super(message, status: 401, code: "UNAUTHORIZED")
24
+ end
25
+ end
26
+
27
+ class RateLimitError < Error
28
+ attr_reader :retry_after
29
+
30
+ def initialize(retry_after: 0)
31
+ super("Rate limited. Retry after #{retry_after}s", status: 429, code: "RATE_LIMITED")
32
+ @retry_after = retry_after
33
+ end
34
+ end
35
+ end
data/lib/flexops/http.rb CHANGED
@@ -38,8 +38,8 @@ module FlexOps
38
38
  request(:get, path, query: query)
39
39
  end
40
40
 
41
- def post(path, body: nil, query: nil)
42
- request(:post, path, body: body, query: query)
41
+ def post(path, body: nil, query: nil, headers: {})
42
+ request(:post, path, body: body, query: query, headers: headers)
43
43
  end
44
44
 
45
45
  def put(path, body: nil)
@@ -56,7 +56,7 @@ module FlexOps
56
56
 
57
57
  private
58
58
 
59
- def request(method, path, body: nil, query: nil)
59
+ def request(method, path, body: nil, query: nil, headers: {})
60
60
  uri = build_uri(path, query)
61
61
  last_error = nil
62
62
 
@@ -66,6 +66,7 @@ module FlexOps
66
66
  end
67
67
 
68
68
  req = build_request(method, uri, body)
69
+ headers.each { |name, value| req[name] = value }
69
70
  begin
70
71
  response = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https",
71
72
  open_timeout: @timeout, read_timeout: @timeout) do |http|
@@ -97,6 +98,7 @@ module FlexOps
97
98
  error = Error.new(
98
99
  error_body["message"] || "HTTP #{status}: #{response.message}",
99
100
  status: status,
101
+ code: error_body["errorCode"] || error_body["code"],
100
102
  errors: error_body["errors"]
101
103
  )
102
104
 
@@ -1,85 +1,85 @@
1
- # ***********************************************************************
2
- # Package : flexops
3
- # Author : FlexOps, LLC
4
- # Created : 2026-03-08
5
- #
6
- # Copyright (c) 2021-2026 by FlexOps, LLC. All rights reserved.
7
- # ***********************************************************************
8
-
9
- module FlexOps
10
- module Resources
11
- class Analytics
12
- BASE = "/api/ApiProxy/api/v4/Analytics"
13
-
14
- def initialize(http)
15
- @http = http
16
- end
17
-
18
- def shipments_trend(start_date: nil, end_date: nil)
19
- @http.get("#{BASE}/ShipmentsTrend", query: date_query(start_date, end_date))
20
- end
21
-
22
- def carrier_summary(start_date: nil, end_date: nil)
23
- @http.get("#{BASE}/CarrierSummary", query: date_query(start_date, end_date))
24
- end
25
-
26
- def top_destinations(start_date: nil, end_date: nil, limit: nil)
27
- @http.get("#{BASE}/TopDestinations", query: date_query(start_date, end_date).merge(limit: limit).compact)
28
- end
29
-
30
- def inventory_metrics
31
- @http.get("#{BASE}/InventoryMetrics")
32
- end
33
-
34
- def stock_by_warehouse
35
- @http.get("#{BASE}/StockByWarehouse")
36
- end
37
-
38
- def order_metrics(start_date: nil, end_date: nil)
39
- @http.get("#{BASE}/OrderMetrics", query: date_query(start_date, end_date))
40
- end
41
-
42
- def order_trend(start_date: nil, end_date: nil)
43
- @http.get("#{BASE}/OrderTrend", query: date_query(start_date, end_date))
44
- end
45
-
46
- def top_selling_products(start_date: nil, end_date: nil, limit: nil)
47
- @http.get("#{BASE}/TopSellingProducts", query: date_query(start_date, end_date).merge(limit: limit).compact)
48
- end
49
-
50
- def returns_metrics(start_date: nil, end_date: nil)
51
- @http.get("#{BASE}/ReturnsMetrics", query: date_query(start_date, end_date))
52
- end
53
-
54
- def returns_trend(start_date: nil, end_date: nil)
55
- @http.get("#{BASE}/ReturnsTrend", query: date_query(start_date, end_date))
56
- end
57
-
58
- def return_reasons(start_date: nil, end_date: nil)
59
- @http.get("#{BASE}/ReturnReasons", query: date_query(start_date, end_date))
60
- end
61
-
62
- def performance_metrics(start_date: nil, end_date: nil)
63
- @http.get("#{BASE}/PerformanceMetrics", query: date_query(start_date, end_date))
64
- end
65
-
66
- def carrier_performance(start_date: nil, end_date: nil)
67
- @http.get("#{BASE}/CarrierPerformance", query: date_query(start_date, end_date))
68
- end
69
-
70
- def shipping_cost_analytics(start_date: nil, end_date: nil)
71
- @http.get("#{BASE}/ShippingCostAnalytics", query: date_query(start_date, end_date))
72
- end
73
-
74
- def delivery_performance(start_date: nil, end_date: nil)
75
- @http.get("#{BASE}/DeliveryPerformance", query: date_query(start_date, end_date))
76
- end
77
-
78
- private
79
-
80
- def date_query(start_date, end_date)
81
- { startDate: start_date, endDate: end_date }.compact
82
- end
83
- end
84
- end
85
- end
1
+ # ***********************************************************************
2
+ # Package : flexops
3
+ # Author : FlexOps, LLC
4
+ # Created : 2026-03-08
5
+ #
6
+ # Copyright (c) 2021-2026 by FlexOps, LLC. All rights reserved.
7
+ # ***********************************************************************
8
+
9
+ module FlexOps
10
+ module Resources
11
+ class Analytics
12
+ BASE = "/api/ApiProxy/api/v4/Analytics"
13
+
14
+ def initialize(http)
15
+ @http = http
16
+ end
17
+
18
+ def shipments_trend(start_date: nil, end_date: nil)
19
+ @http.get("#{BASE}/ShipmentsTrend", query: date_query(start_date, end_date))
20
+ end
21
+
22
+ def carrier_summary(start_date: nil, end_date: nil)
23
+ @http.get("#{BASE}/CarrierSummary", query: date_query(start_date, end_date))
24
+ end
25
+
26
+ def top_destinations(start_date: nil, end_date: nil, limit: nil)
27
+ @http.get("#{BASE}/TopDestinations", query: date_query(start_date, end_date).merge(limit: limit).compact)
28
+ end
29
+
30
+ def inventory_metrics
31
+ @http.get("#{BASE}/InventoryMetrics")
32
+ end
33
+
34
+ def stock_by_warehouse
35
+ @http.get("#{BASE}/StockByWarehouse")
36
+ end
37
+
38
+ def order_metrics(start_date: nil, end_date: nil)
39
+ @http.get("#{BASE}/OrderMetrics", query: date_query(start_date, end_date))
40
+ end
41
+
42
+ def order_trend(start_date: nil, end_date: nil)
43
+ @http.get("#{BASE}/OrderTrend", query: date_query(start_date, end_date))
44
+ end
45
+
46
+ def top_selling_products(start_date: nil, end_date: nil, limit: nil)
47
+ @http.get("#{BASE}/TopSellingProducts", query: date_query(start_date, end_date).merge(limit: limit).compact)
48
+ end
49
+
50
+ def returns_metrics(start_date: nil, end_date: nil)
51
+ @http.get("#{BASE}/ReturnsMetrics", query: date_query(start_date, end_date))
52
+ end
53
+
54
+ def returns_trend(start_date: nil, end_date: nil)
55
+ @http.get("#{BASE}/ReturnsTrend", query: date_query(start_date, end_date))
56
+ end
57
+
58
+ def return_reasons(start_date: nil, end_date: nil)
59
+ @http.get("#{BASE}/ReturnReasons", query: date_query(start_date, end_date))
60
+ end
61
+
62
+ def performance_metrics(start_date: nil, end_date: nil)
63
+ @http.get("#{BASE}/PerformanceMetrics", query: date_query(start_date, end_date))
64
+ end
65
+
66
+ def carrier_performance(start_date: nil, end_date: nil)
67
+ @http.get("#{BASE}/CarrierPerformance", query: date_query(start_date, end_date))
68
+ end
69
+
70
+ def shipping_cost_analytics(start_date: nil, end_date: nil)
71
+ @http.get("#{BASE}/ShippingCostAnalytics", query: date_query(start_date, end_date))
72
+ end
73
+
74
+ def delivery_performance(start_date: nil, end_date: nil)
75
+ @http.get("#{BASE}/DeliveryPerformance", query: date_query(start_date, end_date))
76
+ end
77
+
78
+ private
79
+
80
+ def date_query(start_date, end_date)
81
+ { startDate: start_date, endDate: end_date }.compact
82
+ end
83
+ end
84
+ end
85
+ end
@@ -1,40 +1,40 @@
1
- # ***********************************************************************
2
- # Package : flexops
3
- # Author : FlexOps, LLC
4
- # Created : 2026-03-08
5
- #
6
- # Copyright (c) 2021-2026 by FlexOps, LLC. All rights reserved.
7
- # ***********************************************************************
8
-
9
- module FlexOps
10
- module Resources
11
- class ApiKeys
12
- def initialize(http, ws_id_proc)
13
- @http = http
14
- @ws_id = ws_id_proc
15
- end
16
-
17
- def list
18
- @http.get("#{ws_path}/api-keys")
19
- end
20
-
21
- def create(request)
22
- @http.post("#{ws_path}/api-keys", body: request)
23
- end
24
-
25
- def revoke(key_id)
26
- @http.delete("#{ws_path}/api-keys/#{key_id}")
27
- end
28
-
29
- def rotate(key_id)
30
- @http.post("#{ws_path}/api-keys/#{key_id}/rotate")
31
- end
32
-
33
- private
34
-
35
- def ws_path
36
- "/api/workspaces/#{@ws_id.call}"
37
- end
38
- end
39
- end
40
- end
1
+ # ***********************************************************************
2
+ # Package : flexops
3
+ # Author : FlexOps, LLC
4
+ # Created : 2026-03-08
5
+ #
6
+ # Copyright (c) 2021-2026 by FlexOps, LLC. All rights reserved.
7
+ # ***********************************************************************
8
+
9
+ module FlexOps
10
+ module Resources
11
+ class ApiKeys
12
+ def initialize(http, ws_id_proc)
13
+ @http = http
14
+ @ws_id = ws_id_proc
15
+ end
16
+
17
+ def list
18
+ @http.get("#{ws_path}/api-keys")
19
+ end
20
+
21
+ def create(request)
22
+ @http.post("#{ws_path}/api-keys", body: request)
23
+ end
24
+
25
+ def revoke(key_id)
26
+ @http.delete("#{ws_path}/api-keys/#{key_id}")
27
+ end
28
+
29
+ def rotate(key_id)
30
+ @http.post("#{ws_path}/api-keys/#{key_id}/rotate")
31
+ end
32
+
33
+ private
34
+
35
+ def ws_path
36
+ "/api/workspaces/#{@ws_id.call}"
37
+ end
38
+ end
39
+ end
40
+ end
@@ -1,57 +1,57 @@
1
- # ***********************************************************************
2
- # Package : flexops
3
- # Author : FlexOps, LLC
4
- # Created : 2026-03-08
5
- #
6
- # Copyright (c) 2021-2026 by FlexOps, LLC. All rights reserved.
7
- # ***********************************************************************
8
-
9
- module FlexOps
10
- module Resources
11
- class Auth
12
- def initialize(http)
13
- @http = http
14
- end
15
-
16
- def login(email:, password:)
17
- @http.post("/api/Account/login", body: { email: email, password: password })
18
- end
19
-
20
- def register(request)
21
- @http.post("/api/Account/register", body: request)
22
- end
23
-
24
- def refresh_token(refresh_token)
25
- @http.post("/api/Account/refresh-token", body: { refreshToken: refresh_token })
26
- end
27
-
28
- def logout
29
- @http.post("/api/Account/logout")
30
- end
31
-
32
- def get_profile
33
- @http.get("/api/Account/profile")
34
- end
35
-
36
- def update_profile(data)
37
- @http.put("/api/Account/profile", body: data)
38
- end
39
-
40
- def change_password(current_password:, new_password:)
41
- @http.post("/api/Account/change-password", body: { currentPassword: current_password, newPassword: new_password })
42
- end
43
-
44
- def forgot_password(email:)
45
- @http.post("/api/Account/forgot-password", body: { email: email })
46
- end
47
-
48
- def reset_password(token:, new_password:)
49
- @http.post("/api/Account/reset-password", body: { token: token, newPassword: new_password })
50
- end
51
-
52
- def verify_email(token:)
53
- @http.post("/api/Account/verify-email", body: { token: token })
54
- end
55
- end
56
- end
57
- end
1
+ # ***********************************************************************
2
+ # Package : flexops
3
+ # Author : FlexOps, LLC
4
+ # Created : 2026-03-08
5
+ #
6
+ # Copyright (c) 2021-2026 by FlexOps, LLC. All rights reserved.
7
+ # ***********************************************************************
8
+
9
+ module FlexOps
10
+ module Resources
11
+ class Auth
12
+ def initialize(http)
13
+ @http = http
14
+ end
15
+
16
+ def login(email:, password:)
17
+ @http.post("/api/Account/login", body: { email: email, password: password })
18
+ end
19
+
20
+ def register(request)
21
+ @http.post("/api/Account/register", body: request)
22
+ end
23
+
24
+ def refresh_token(refresh_token)
25
+ @http.post("/api/Account/refresh-token", body: { refreshToken: refresh_token })
26
+ end
27
+
28
+ def logout
29
+ @http.post("/api/Account/logout")
30
+ end
31
+
32
+ def get_profile
33
+ @http.get("/api/Account/profile")
34
+ end
35
+
36
+ def update_profile(data)
37
+ @http.put("/api/Account/profile", body: data)
38
+ end
39
+
40
+ def change_password(current_password:, new_password:)
41
+ @http.post("/api/Account/change-password", body: { currentPassword: current_password, newPassword: new_password })
42
+ end
43
+
44
+ def forgot_password(email:)
45
+ @http.post("/api/Account/forgot-password", body: { email: email })
46
+ end
47
+
48
+ def reset_password(token:, new_password:)
49
+ @http.post("/api/Account/reset-password", body: { token: token, newPassword: new_password })
50
+ end
51
+
52
+ def verify_email(token:)
53
+ @http.post("/api/Account/verify-email", body: { token: token })
54
+ end
55
+ end
56
+ end
57
+ end