@openmeter/client 1.0.0-beta.229 → 1.0.0-beta.231

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 (135) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +364 -66
  3. package/dist/core.d.ts +0 -1
  4. package/dist/core.js +8 -1
  5. package/dist/funcs/addons.d.ts +49 -1
  6. package/dist/funcs/addons.js +161 -29
  7. package/dist/funcs/apps.d.ts +14 -1
  8. package/dist/funcs/apps.js +52 -9
  9. package/dist/funcs/billing.d.ts +46 -1
  10. package/dist/funcs/billing.js +126 -17
  11. package/dist/funcs/currencies.d.ts +30 -1
  12. package/dist/funcs/currencies.js +113 -23
  13. package/dist/funcs/customers.d.ts +167 -2
  14. package/dist/funcs/customers.js +580 -90
  15. package/dist/funcs/defaults.d.ts +10 -1
  16. package/dist/funcs/defaults.js +35 -5
  17. package/dist/funcs/entitlements.d.ts +5 -1
  18. package/dist/funcs/entitlements.js +25 -6
  19. package/dist/funcs/events.d.ts +14 -1
  20. package/dist/funcs/events.js +41 -9
  21. package/dist/funcs/features.d.ts +42 -1
  22. package/dist/funcs/features.js +142 -28
  23. package/dist/funcs/governance.d.ts +14 -1
  24. package/dist/funcs/governance.js +42 -10
  25. package/dist/funcs/index.d.ts +1 -1
  26. package/dist/funcs/index.js +2 -1
  27. package/dist/funcs/invoices.d.ts +51 -0
  28. package/dist/funcs/invoices.js +125 -0
  29. package/dist/funcs/llmCost.d.ts +36 -1
  30. package/dist/funcs/llmCost.js +114 -24
  31. package/dist/funcs/meters.d.ts +55 -2
  32. package/dist/funcs/meters.js +172 -28
  33. package/dist/funcs/planAddons.d.ts +35 -1
  34. package/dist/funcs/planAddons.js +139 -29
  35. package/dist/funcs/plans.d.ts +49 -1
  36. package/dist/funcs/plans.js +163 -25
  37. package/dist/funcs/subscriptions.d.ts +61 -2
  38. package/dist/funcs/subscriptions.js +238 -40
  39. package/dist/funcs/tax.d.ts +25 -1
  40. package/dist/funcs/tax.js +104 -22
  41. package/dist/index.d.ts +6 -4
  42. package/dist/index.js +4 -3
  43. package/dist/lib/config.d.ts +9 -1
  44. package/dist/lib/config.js +1 -1
  45. package/dist/lib/encodings.d.ts +1 -2
  46. package/dist/lib/encodings.js +6 -5
  47. package/dist/lib/paginate.d.ts +56 -0
  48. package/dist/lib/paginate.js +60 -0
  49. package/dist/lib/request.d.ts +0 -1
  50. package/dist/lib/request.js +1 -1
  51. package/dist/lib/to-error.d.ts +0 -1
  52. package/dist/lib/to-error.js +1 -1
  53. package/dist/lib/types.d.ts +0 -1
  54. package/dist/lib/types.js +1 -1
  55. package/dist/lib/version.d.ts +1 -0
  56. package/dist/lib/version.js +5 -0
  57. package/dist/lib/wire.d.ts +20 -0
  58. package/dist/lib/wire.js +401 -0
  59. package/dist/models/errors.d.ts +13 -2
  60. package/dist/models/errors.js +31 -4
  61. package/dist/models/operations/addons.d.ts +17 -6
  62. package/dist/models/operations/addons.js +1 -1
  63. package/dist/models/operations/apps.d.ts +4 -6
  64. package/dist/models/operations/apps.js +1 -1
  65. package/dist/models/operations/billing.d.ts +5 -5
  66. package/dist/models/operations/billing.js +1 -1
  67. package/dist/models/operations/currencies.d.ts +27 -10
  68. package/dist/models/operations/currencies.js +1 -1
  69. package/dist/models/operations/customers.d.ts +87 -33
  70. package/dist/models/operations/customers.js +1 -1
  71. package/dist/models/operations/defaults.d.ts +2 -2
  72. package/dist/models/operations/defaults.js +1 -1
  73. package/dist/models/operations/entitlements.d.ts +0 -1
  74. package/dist/models/operations/entitlements.js +1 -1
  75. package/dist/models/operations/events.d.ts +20 -5
  76. package/dist/models/operations/events.js +1 -1
  77. package/dist/models/operations/features.d.ts +24 -9
  78. package/dist/models/operations/features.js +1 -1
  79. package/dist/models/operations/governance.d.ts +3 -3
  80. package/dist/models/operations/governance.js +1 -1
  81. package/dist/models/operations/invoices.d.ts +45 -0
  82. package/dist/models/operations/invoices.js +2 -0
  83. package/dist/models/operations/llmCost.d.ts +16 -5
  84. package/dist/models/operations/llmCost.js +1 -1
  85. package/dist/models/operations/meters.d.ts +29 -9
  86. package/dist/models/operations/meters.js +1 -1
  87. package/dist/models/operations/planAddons.d.ts +7 -7
  88. package/dist/models/operations/planAddons.js +1 -1
  89. package/dist/models/operations/plans.d.ts +14 -6
  90. package/dist/models/operations/plans.js +1 -1
  91. package/dist/models/operations/subscriptions.d.ts +36 -11
  92. package/dist/models/operations/subscriptions.js +1 -1
  93. package/dist/models/operations/tax.d.ts +6 -6
  94. package/dist/models/operations/tax.js +1 -1
  95. package/dist/models/schemas.d.ts +27484 -3125
  96. package/dist/models/schemas.js +6247 -495
  97. package/dist/models/types.d.ts +4548 -1398
  98. package/dist/models/types.js +1 -1
  99. package/dist/sdk/addons.d.ts +60 -1
  100. package/dist/sdk/addons.js +63 -1
  101. package/dist/sdk/apps.d.ts +25 -1
  102. package/dist/sdk/apps.js +28 -1
  103. package/dist/sdk/billing.d.ts +57 -1
  104. package/dist/sdk/billing.js +60 -1
  105. package/dist/sdk/customers.d.ts +213 -2
  106. package/dist/sdk/customers.js +228 -2
  107. package/dist/sdk/defaults.d.ts +10 -1
  108. package/dist/sdk/defaults.js +11 -1
  109. package/dist/sdk/entitlements.d.ts +5 -1
  110. package/dist/sdk/entitlements.js +6 -1
  111. package/dist/sdk/events.d.ts +25 -1
  112. package/dist/sdk/events.js +28 -1
  113. package/dist/sdk/features.d.ts +53 -1
  114. package/dist/sdk/features.js +56 -1
  115. package/dist/sdk/internal.d.ts +180 -0
  116. package/dist/sdk/internal.js +224 -0
  117. package/dist/sdk/llmCost.d.ts +57 -1
  118. package/dist/sdk/llmCost.js +62 -1
  119. package/dist/sdk/meters.d.ts +66 -2
  120. package/dist/sdk/meters.js +71 -2
  121. package/dist/sdk/planAddons.d.ts +46 -1
  122. package/dist/sdk/planAddons.js +49 -1
  123. package/dist/sdk/plans.d.ts +60 -1
  124. package/dist/sdk/plans.js +63 -1
  125. package/dist/sdk/sdk.d.ts +9 -7
  126. package/dist/sdk/sdk.js +11 -10
  127. package/dist/sdk/subscriptions.d.ts +71 -1
  128. package/dist/sdk/subscriptions.js +76 -1
  129. package/dist/sdk/tax.d.ts +34 -1
  130. package/dist/sdk/tax.js +37 -1
  131. package/package.json +31 -6
  132. package/dist/sdk/currencies.d.ts +0 -12
  133. package/dist/sdk/currencies.js +0 -21
  134. package/dist/sdk/governance.d.ts +0 -9
  135. package/dist/sdk/governance.js +0 -12
package/README.md CHANGED
@@ -1,11 +1,12 @@
1
+ <!-- Code generated by @openmeter/typespec-typescript. DO NOT EDIT. -->
2
+
1
3
  # OpenMeter SDK
2
4
 
3
5
  TypeScript client for the OpenMeter API — usage metering and billing for
4
6
  AI and DevTool companies. This package is generated from the OpenMeter
5
7
  TypeSpec definitions and ships fully-typed request and response models.
6
8
 
7
- > [!IMPORTANT]
8
- > This SDK is a work in progress.
9
+ > **Important:** This SDK is a work in progress.
9
10
  >
10
11
  > This SDK targets the [OpenMeter API v3](https://openmeter.io/docs/api/v3),
11
12
  > a rewrite of the OpenMeter API following AIP (API Improvement Proposal)
@@ -15,7 +16,9 @@ TypeSpec definitions and ships fully-typed request and response models.
15
16
 
16
17
  - [Installation](#installation)
17
18
  - [Initialization](#initialization)
19
+ - [Configuration](#configuration)
18
20
  - [Usage](#usage)
21
+ - [Pagination](#pagination)
19
22
  - [Available Resources and Operations](#available-resources-and-operations)
20
23
  - [Events](#events)
21
24
  - [Meters](#meters)
@@ -25,14 +28,19 @@ TypeSpec definitions and ships fully-typed request and response models.
25
28
  - [Apps](#apps)
26
29
  - [Billing](#billing)
27
30
  - [Tax](#tax)
28
- - [Currencies](#currencies)
29
31
  - [Features](#features)
30
32
  - [LLMCost](#llmcost)
31
33
  - [Plans](#plans)
32
34
  - [Addons](#addons)
33
35
  - [PlanAddons](#planaddons)
34
36
  - [Defaults](#defaults)
35
- - [Governance](#governance)
37
+ - [Internal Operations](#internal-operations)
38
+ - [Internal Subscriptions](#internal-subscriptions)
39
+ - [Internal Invoices](#internal-invoices)
40
+ - [Internal Currencies](#internal-currencies)
41
+ - [Internal Governance](#internal-governance)
42
+ - [Runtime Validation (validate option)](#runtime-validation-validate-option)
43
+ - [Zod Schemas (./zod export)](#zod-schemas-zod-export)
36
44
  - [Error Handling](#error-handling)
37
45
  - [Standalone Functions](#standalone-functions)
38
46
 
@@ -79,6 +87,76 @@ const client = new OpenMeter({
79
87
  The `apiKey` may also be a function returning a `string` or
80
88
  `Promise<string>`, so tokens can be refreshed per request.
81
89
 
90
+ ## Configuration
91
+
92
+ `SDKOptions` extends [ky](https://github.com/sindresorhus/ky)'s
93
+ `Options`, so every transport setting ky supports is a top-level client
94
+ option: retry policy, per-attempt timeout (ky defaults to 10 seconds),
95
+ lifecycle hooks, a custom `fetch`, and so on.
96
+
97
+ ```typescript
98
+ import { OpenMeter } from '@openmeter/client'
99
+
100
+ const client = new OpenMeter({
101
+ baseUrl: 'https://openmeter.cloud/api/v3',
102
+ apiKey: process.env.OPENMETER_API_KEY,
103
+ timeout: 30_000,
104
+ hooks: {
105
+ beforeRequest: [
106
+ ({ request }) => {
107
+ console.log(`-> ${request.method} ${request.url}`)
108
+ },
109
+ ],
110
+ },
111
+ fetch: async (input, init) => {
112
+ const start = Date.now()
113
+ const response = await fetch(input, init)
114
+ console.log(`${response.status} in ${Date.now() - start}ms`)
115
+ return response
116
+ },
117
+ })
118
+ ```
119
+
120
+ ky only retries the idempotent methods by default — `get`, `put`,
121
+ `head`, `delete`, `options`, `trace` — never `post`. That means a
122
+ dropped `client.events.ingest` call is not retried on a network error
123
+ or a 5xx response unless you opt in explicitly:
124
+
125
+ ```typescript
126
+ import { OpenMeter } from '@openmeter/client'
127
+
128
+ const client = new OpenMeter({
129
+ baseUrl: 'https://openmeter.cloud/api/v3',
130
+ apiKey: process.env.OPENMETER_API_KEY,
131
+ retry: { limit: 3, methods: ['get', 'put', 'head', 'delete', 'post'] },
132
+ })
133
+ ```
134
+
135
+ This is safe specifically for event ingestion: the event `id` is its
136
+ deduplication key server-side, so resending the same event on retry is
137
+ a no-op rather than a duplicate.
138
+
139
+ Every method also takes a per-request `RequestOptions` as its second
140
+ argument — a curated subset of ky's options (`signal`, `headers`,
141
+ `timeout`, `retry`) applied to that call only:
142
+
143
+ ```typescript
144
+ import { OpenMeter } from '@openmeter/client'
145
+
146
+ const client = new OpenMeter({
147
+ baseUrl: 'https://openmeter.cloud/api/v3',
148
+ apiKey: process.env.OPENMETER_API_KEY,
149
+ })
150
+
151
+ const controller = new AbortController()
152
+ setTimeout(() => controller.abort(), 5_000)
153
+
154
+ const meters = await client.meters.list(undefined, {
155
+ signal: controller.signal,
156
+ headers: { 'X-Request-Id': 'batch-42' },
157
+ })
158
+ ```
159
+
82
160
  ## Usage
83
161
 
84
162
  Every operation is reachable through a fluent, namespaced client and
@@ -96,8 +174,8 @@ const meter = await client.meters.create({
96
174
  name: 'Tokens',
97
175
  key: 'tokens',
98
176
  aggregation: 'sum',
99
- event_type: 'request',
100
- value_property: '$.tokens',
177
+ eventType: 'request',
178
+ valueProperty: '$.tokens',
101
179
  })
102
180
 
103
181
  const meters = await client.meters.list()
@@ -106,6 +184,75 @@ const meters = await client.meters.list()
106
184
  Each method takes the request object as its first argument and an optional
107
185
  per-request options object (`RequestOptions`) as its second.
108
186
 
187
+ Responses return date-time fields as native `Date` objects (every
188
+ `createdAt`/`updatedAt`, meter query row windows, …), and requests accept
189
+ either a `Date` or an RFC 3339 string — a meter query `from`/`to`, an
190
+ ingested event's `time`, filter operands, all alike.
191
+
192
+ ## Pagination
193
+
194
+ Every list operation that returns pages also has an `…All` companion —
195
+ `client.meters.listAll(request?)` alongside `client.meters.list(request?)` —
196
+ that returns an `AsyncIterable` of items instead of one page. It fetches
197
+ each following page lazily, only when the previous page is exhausted, so a
198
+ `break` (or a `return`) partway through never fires a request for a page
199
+ nothing consumes:
200
+
201
+ ```typescript
202
+ import { OpenMeter } from '@openmeter/client'
203
+
204
+ const client = new OpenMeter({
205
+ baseUrl: 'https://openmeter.cloud/api/v3',
206
+ apiKey: process.env.OPENMETER_API_KEY,
207
+ })
208
+
209
+ for await (const meter of client.meters.listAll()) {
210
+ console.log(meter.key)
211
+ }
212
+ ```
213
+
214
+ The request object accepts the same filters, sort, and page size as the
215
+ single-page method — only the page cursor/number itself advances between
216
+ requests:
217
+
218
+ ```typescript
219
+ for await (const meter of client.meters.listAll({ filter: { key: 'api' } })) {
220
+ if (meter.key === 'api-requests') {
221
+ break // stops iterating; no further pages are fetched
222
+ }
223
+ }
224
+ ```
225
+
226
+ Cursor-paginated resources (`events`, credit transactions) work the same
227
+ way:
228
+
229
+ ```typescript
230
+ for await (const event of client.events.listAll()) {
231
+ console.log(event.event.id)
232
+ }
233
+ ```
234
+
235
+ Auto-pagination takes the same optional `RequestOptions` as every other
236
+ method, so one `AbortSignal` cancels the whole iteration, not just the page
237
+ in flight:
238
+
239
+ ```typescript
240
+ const controller = new AbortController()
241
+ setTimeout(() => controller.abort(), 30_000)
242
+
243
+ for await (const meter of client.meters.listAll(undefined, {
244
+ signal: controller.signal,
245
+ })) {
246
+ console.log(meter.key)
247
+ }
248
+ ```
249
+
250
+ Iteration stops after the server’s last page — an empty or short-of-`size`
251
+ page for a page-number resource, or a response with no next cursor for a
252
+ cursor resource. A misbehaving server that never signals the end of the
253
+ list fails fast instead of looping forever: after 10,000 pages the
254
+ iterable throws `PaginationLimitExceededError`.
255
+
109
256
  ## Available Resources and Operations
110
257
 
111
258
  Operations are grouped by resource and exposed as methods on the client.
@@ -120,54 +267,58 @@ The full call path, HTTP route, and a short description are listed below.
120
267
 
121
268
  ### Meters
122
269
 
123
- | Method | HTTP | Description |
124
- | ---------------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
125
- | `client.meters.create` | `POST /openmeter/meters` | Create a meter. |
126
- | `client.meters.get` | `GET /openmeter/meters/{meterId}` | Get a meter by ID. |
127
- | `client.meters.list` | `GET /openmeter/meters` | List meters. |
128
- | `client.meters.update` | `PUT /openmeter/meters/{meterId}` | Update a meter. |
129
- | `client.meters.delete` | `DELETE /openmeter/meters/{meterId}` | Delete a meter. |
130
- | `client.meters.query` | `POST /openmeter/meters/{meterId}/query` | Query a meter for usage. Set `Accept: application/json` (the default) to get a structured JSON response. Set `Accept: text/csv` to download the same data as a CSV file suitable for spreadsheets. The CSV columns, in order, are: `from, to, [subject,] [customer_id, customer_key, customer_name,] <dimensions...>, value` The `subject` column is emitted only when `subject` is in the query's `group_by_dimensions`. The three `customer_*` columns are emitted together only when `customer_id` is in the query's `group_by_dimensions`. |
270
+ | Method | HTTP | Description |
271
+ | ------------------------ | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
272
+ | `client.meters.create` | `POST /openmeter/meters` | Create a meter. |
273
+ | `client.meters.get` | `GET /openmeter/meters/{meterId}` | Get a meter by ID. |
274
+ | `client.meters.list` | `GET /openmeter/meters` | List meters. |
275
+ | `client.meters.update` | `PUT /openmeter/meters/{meterId}` | Update a meter. |
276
+ | `client.meters.delete` | `DELETE /openmeter/meters/{meterId}` | Delete a meter. |
277
+ | `client.meters.query` | `POST /openmeter/meters/{meterId}/query` | Query a meter for usage. Set `Accept: application/json` (the default) to get a structured JSON response. Set `Accept: text/csv` to download the same data as a CSV file suitable for spreadsheets. The CSV columns, in order, are: `from, to, [subject,] [customer_id, customer_key, customer_name,] <dimensions...>, value` The `subject` column is emitted only when `subject` is in the query's `group_by_dimensions`. The three `customer_*` columns are emitted together only when `customer_id` is in the query's `group_by_dimensions`. |
278
+ | `client.meters.queryCsv` | `POST /openmeter/meters/{meterId}/query` | |
131
279
 
132
280
  ### Customers
133
281
 
134
- | Method | HTTP | Description |
135
- | ------------------------------------------------------ | ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
136
- | `client.customers.create` | `POST /openmeter/customers` | |
137
- | `client.customers.get` | `GET /openmeter/customers/{customerId}` | |
138
- | `client.customers.list` | `GET /openmeter/customers` | |
139
- | `client.customers.upsert` | `PUT /openmeter/customers/{customerId}` | |
140
- | `client.customers.delete` | `DELETE /openmeter/customers/{customerId}` | |
141
- | `client.customers.billing.get` | `GET /openmeter/customers/{customerId}/billing` | |
142
- | `client.customers.billing.update` | `PUT /openmeter/customers/{customerId}/billing` | |
143
- | `client.customers.billing.updateAppData` | `PUT /openmeter/customers/{customerId}/billing/app-data` | |
144
- | `client.customers.billing.createStripeCheckoutSession` | `POST /openmeter/customers/{customerId}/billing/stripe/checkout-sessions` | Create a [Stripe Checkout Session](https://docs.stripe.com/payments/checkout) for the customer. Creates a Checkout Session for collecting payment method information from customers. The session operates in "setup" mode, which collects payment details without charging the customer immediately. The collected payment method can be used for future subscription billing. For hosted checkout sessions, redirect customers to the returned URL. For embedded sessions, use the client_secret to initialize Stripe.js in your application. |
145
- | `client.customers.billing.createStripePortalSession` | `POST /openmeter/customers/{customerId}/billing/stripe/portal-sessions` | Create Stripe Customer Portal Session. Useful to redirect the customer to the Stripe Customer Portal to manage their payment methods, change their billing address and access their invoice history. Only returns URL if the customer billing profile is linked to a stripe app and customer. |
146
- | `client.customers.credits.grants.create` | `POST /openmeter/customers/{customerId}/credits/grants` | Create a new credit grant. A credit grant represents an allocation of prepaid credits to a customer. |
147
- | `client.customers.credits.grants.get` | `GET /openmeter/customers/{customerId}/credits/grants/{creditGrantId}` | Get a credit grant. |
148
- | `client.customers.credits.grants.list` | `GET /openmeter/customers/{customerId}/credits/grants` | List credit grants. |
149
- | `client.customers.credits.balance.get` | `GET /openmeter/customers/{customerId}/credits/balance` | Get a credit balance. |
150
- | `client.customers.credits.adjustments.create` | `POST /openmeter/customers/{customerId}/credits/adjustments` | A credit adjustment can be used to make manual adjustments to a customer's credit balance. Supported use-cases: - Usage correction |
151
- | `client.customers.credits.transactions.list` | `GET /openmeter/customers/{customerId}/credits/transactions` | List credit transactions for a customer. Returns an immutable, chronological record of credit movements: funded credits and consumed credits. Transactions are returned in reverse chronological order by default. |
152
- | `client.customers.charges.list` | `GET /openmeter/customers/{customerId}/charges` | List customer charges. Returns the customer's charges that are represented as either flat fee or usage-based charges. |
282
+ | Method | HTTP | Description |
283
+ | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
284
+ | `client.customers.create` | `POST /openmeter/customers` | Create customer |
285
+ | `client.customers.get` | `GET /openmeter/customers/{customerId}` | Get customer |
286
+ | `client.customers.list` | `GET /openmeter/customers` | List customers |
287
+ | `client.customers.upsert` | `PUT /openmeter/customers/{customerId}` | Upsert customer |
288
+ | `client.customers.delete` | `DELETE /openmeter/customers/{customerId}` | Delete customer |
289
+ | `client.customers.billing.get` | `GET /openmeter/customers/{customerId}/billing` | Get customer billing data |
290
+ | `client.customers.billing.update` | `PUT /openmeter/customers/{customerId}/billing` | Update customer billing data |
291
+ | `client.customers.billing.updateAppData` | `PUT /openmeter/customers/{customerId}/billing/app-data` | Update customer billing app data |
292
+ | `client.customers.billing.createStripeCheckoutSession` | `POST /openmeter/customers/{customerId}/billing/stripe/checkout-sessions` | Create a [Stripe Checkout Session](https://docs.stripe.com/payments/checkout) for the customer. Creates a Checkout Session for collecting payment method information from customers. The session operates in "setup" mode, which collects payment details without charging the customer immediately. The collected payment method can be used for future subscription billing. For hosted checkout sessions, redirect customers to the returned URL. For embedded sessions, use the client_secret to initialize Stripe.js in your application. |
293
+ | `client.customers.billing.createStripePortalSession` | `POST /openmeter/customers/{customerId}/billing/stripe/portal-sessions` | Create Stripe Customer Portal Session. Useful to redirect the customer to the Stripe Customer Portal to manage their payment methods, change their billing address and access their invoice history. Only returns URL if the customer billing profile is linked to a stripe app and customer. |
294
+ | `client.customers.credits.grants.create` | `POST /openmeter/customers/{customerId}/credits/grants` | Create a new credit grant. A credit grant represents an allocation of prepaid credits to a customer. |
295
+ | `client.customers.credits.grants.get` | `GET /openmeter/customers/{customerId}/credits/grants/{creditGrantId}` | Get a credit grant. |
296
+ | `client.customers.credits.grants.list` | `GET /openmeter/customers/{customerId}/credits/grants` | List credit grants. |
297
+ | `client.customers.credits.balance.get` | `GET /openmeter/customers/{customerId}/credits/balance` | Get a credit balance. |
298
+ | `client.customers.credits.adjustments.create` | `POST /openmeter/customers/{customerId}/credits/adjustments` | A credit adjustment can be used to make manual adjustments to a customer's credit balance. Supported use-cases: - Usage correction |
299
+ | `client.customers.credits.grants.void` | `POST /openmeter/customers/{customerId}/credits/grants/{creditGrantId}/void` | Void a credit grant, forfeiting the remaining unused balance. Voiding is a forward-looking, irreversible operation. Credits already consumed by usage remain unaffected — only the remaining balance is forfeited. The grant reads as `voided` status afterwards. Payment state is not adjusted when `payment_adjustment` is `none`, so invoice-backed or externally collected payments may still collect the original amount. Only `active` grants can be voided; voiding a pending, expired, or fully consumed grant returns a conflict. Retrying a successful void is an idempotent success. |
300
+ | `client.customers.credits.grants.updateExternalSettlement` | `POST /openmeter/customers/{customerId}/credits/grants/{creditGrantId}/settlement/external` | Update the payment settlement status of an externally funded credit grant. Use this endpoint to synchronize the payment state of an external payment with the system so that revenue recognition and credit availability work as expected. |
301
+ | `client.customers.credits.transactions.list` | `GET /openmeter/customers/{customerId}/credits/transactions` | List credit transactions for a customer. Returns an immutable, chronological record of credit movements: funded credits and consumed credits. Transactions are returned in reverse chronological order by default. |
302
+ | `client.customers.charges.list` | `GET /openmeter/customers/{customerId}/charges` | List customer charges. Returns the customer's charges that are represented as either flat fee or usage-based charges. |
303
+ | `client.customers.charges.create` | `POST /openmeter/customers/{customerId}/charges` | Create customer charge. |
153
304
 
154
305
  ### Entitlements
155
306
 
156
- | Method | HTTP | Description |
157
- | ---------------------------------------- | ---------------------------------------------------------- | ----------- |
158
- | `client.entitlements.listCustomerAccess` | `GET /openmeter/customers/{customerId}/entitlement-access` | |
307
+ | Method | HTTP | Description |
308
+ | ---------------------------------------- | ---------------------------------------------------------- | -------------------------------- |
309
+ | `client.entitlements.listCustomerAccess` | `GET /openmeter/customers/{customerId}/entitlement-access` | List customer entitlement access |
159
310
 
160
311
  ### Subscriptions
161
312
 
162
313
  | Method | HTTP | Description |
163
314
  | -------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
164
- | `client.subscriptions.create` | `POST /openmeter/subscriptions` | |
165
- | `client.subscriptions.list` | `GET /openmeter/subscriptions` | |
166
- | `client.subscriptions.get` | `GET /openmeter/subscriptions/{subscriptionId}` | |
315
+ | `client.subscriptions.create` | `POST /openmeter/subscriptions` | Create subscription |
316
+ | `client.subscriptions.list` | `GET /openmeter/subscriptions` | List subscriptions |
317
+ | `client.subscriptions.get` | `GET /openmeter/subscriptions/{subscriptionId}` | Get subscription |
167
318
  | `client.subscriptions.cancel` | `POST /openmeter/subscriptions/{subscriptionId}/cancel` | Cancels the subscription. Will result in a scheduling conflict if there are other subscriptions scheduled to start after the cancelation time. |
168
319
  | `client.subscriptions.unscheduleCancelation` | `POST /openmeter/subscriptions/{subscriptionId}/unschedule-cancelation` | Unschedules the subscription cancelation. |
169
320
  | `client.subscriptions.change` | `POST /openmeter/subscriptions/{subscriptionId}/change` | Closes a running subscription and starts a new one according to the specification. Can be used for upgrades, downgrades, and plan changes. |
170
- | `client.subscriptions.listAddons` | `GET /openmeter/subscriptions/{subscriptionId}/addons` | List the addons of a subscription. |
321
+ | `client.subscriptions.listAddons` | `GET /openmeter/subscriptions/{subscriptionId}/addons` | List the add-ons of a subscription. |
171
322
  | `client.subscriptions.getAddon` | `GET /openmeter/subscriptions/{subscriptionId}/addons/{subscriptionAddonId}` | Get an add-on association for a subscription. |
172
323
 
173
324
  ### Apps
@@ -189,22 +340,13 @@ The full call path, HTTP route, and a short description are listed below.
189
340
 
190
341
  ### Tax
191
342
 
192
- | Method | HTTP | Description |
193
- | ----------------------- | ----------------------------------------- | ----------- |
194
- | `client.tax.createCode` | `POST /openmeter/tax-codes` | |
195
- | `client.tax.getCode` | `GET /openmeter/tax-codes/{taxCodeId}` | |
196
- | `client.tax.listCodes` | `GET /openmeter/tax-codes` | |
197
- | `client.tax.upsertCode` | `PUT /openmeter/tax-codes/{taxCodeId}` | |
198
- | `client.tax.deleteCode` | `DELETE /openmeter/tax-codes/{taxCodeId}` | |
199
-
200
- ### Currencies
201
-
202
- | Method | HTTP | Description |
203
- | ---------------------------------------- | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
204
- | `client.currencies.list` | `GET /openmeter/currencies` | List currencies supported by the billing system. |
205
- | `client.currencies.createCustomCurrency` | `POST /openmeter/currencies/custom` | Create a custom currency. This operation allows defining your own custom currency for billing purposes. |
206
- | `client.currencies.listCostBases` | `GET /openmeter/currencies/custom/{currencyId}/cost-bases` | List cost bases for a currency. For custom currencies, there can be multiple cost bases with different `effective_from` dates. |
207
- | `client.currencies.createCostBasis` | `POST /openmeter/currencies/custom/{currencyId}/cost-bases` | Create a cost basis for a currency. |
343
+ | Method | HTTP | Description |
344
+ | ----------------------- | ----------------------------------------- | --------------- |
345
+ | `client.tax.createCode` | `POST /openmeter/tax-codes` | Create tax code |
346
+ | `client.tax.getCode` | `GET /openmeter/tax-codes/{taxCodeId}` | Get tax code |
347
+ | `client.tax.listCodes` | `GET /openmeter/tax-codes` | List tax codes |
348
+ | `client.tax.upsertCode` | `PUT /openmeter/tax-codes/{taxCodeId}` | Upsert tax code |
349
+ | `client.tax.deleteCode` | `DELETE /openmeter/tax-codes/{taxCodeId}` | Delete tax code |
208
350
 
209
351
  ### Features
210
352
 
@@ -263,21 +405,122 @@ The full call path, HTTP route, and a short description are listed below.
263
405
 
264
406
  ### Defaults
265
407
 
266
- | Method | HTTP | Description |
267
- | -------------------------------------------- | ----------------------------------- | ----------- |
268
- | `client.defaults.getOrganizationTaxCodes` | `GET /openmeter/defaults/tax-codes` | |
269
- | `client.defaults.updateOrganizationTaxCodes` | `PUT /openmeter/defaults/tax-codes` | |
408
+ | Method | HTTP | Description |
409
+ | -------------------------------------------- | ----------------------------------- | ------------------------------------- |
410
+ | `client.defaults.getOrganizationTaxCodes` | `GET /openmeter/defaults/tax-codes` | Get organization default tax codes |
411
+ | `client.defaults.updateOrganizationTaxCodes` | `PUT /openmeter/defaults/tax-codes` | Update organization default tax codes |
412
+
413
+ ## Internal Operations
414
+
415
+ Operations marked internal in the API definition are exposed under
416
+ `client.internal.*`, quarantined from the customer surface. They are not
417
+ intended for customer use: they may require additional permissions, and
418
+ they can change or be removed without notice or semver consideration.
419
+
420
+ ### Internal Subscriptions
421
+
422
+ | Method | HTTP | Description |
423
+ | ------------------------------------------- | ------------------------------------------------------- | ----------------------------- |
424
+ | `client.internal.subscriptions.createAddon` | `POST /openmeter/subscriptions/{subscriptionId}/addons` | Add add-on to a subscription. |
425
+
426
+ ### Internal Invoices
427
+
428
+ | Method | HTTP | Description |
429
+ | --------------------------------- | ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
430
+ | `client.internal.invoices.list` | `GET /openmeter/billing/invoices` | List billing invoices. Returns a page of invoices. Gathering invoices are never included. Use `filter` to narrow by status, customer, dates, or service period start. Use `sort` to control ordering. |
431
+ | `client.internal.invoices.get` | `GET /openmeter/billing/invoices/{invoiceId}` | Get a billing invoice by ID. Returns the full invoice resource including line items, status details, totals, and workflow configuration snapshot. |
432
+ | `client.internal.invoices.update` | `PUT /openmeter/billing/invoices/{invoiceId}` | Update a billing invoice. Only the mutable fields of the invoice can be edited: description, labels, supplier, customer, workflow settings, and top-level lines. Top-level lines are matched by `id`; lines without an `id` are created, and existing lines omitted from `lines` are deleted. Detailed (child) lines are always computed and cannot be edited directly. Only invoices in draft status can be updated. |
433
+ | `client.internal.invoices.delete` | `DELETE /openmeter/billing/invoices/{invoiceId}` | Delete a billing invoice. Only standard invoices in draft status can be deleted. Deleting an invoice will also delete all associated line items and workflow configuration. |
434
+
435
+ ### Internal Currencies
436
+
437
+ | Method | HTTP | Description |
438
+ | ------------------------------------------------- | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
439
+ | `client.internal.currencies.list` | `GET /openmeter/currencies` | List currencies supported by the billing system. |
440
+ | `client.internal.currencies.createCustomCurrency` | `POST /openmeter/currencies/custom` | Create a custom currency. This operation allows defining your own custom currency for billing purposes. |
441
+ | `client.internal.currencies.listCostBases` | `GET /openmeter/currencies/custom/{currencyId}/cost-bases` | List cost bases for a currency. For custom currencies, there can be multiple cost bases with different `effective_from` dates. |
442
+ | `client.internal.currencies.createCostBasis` | `POST /openmeter/currencies/custom/{currencyId}/cost-bases` | Create a cost basis for a currency. |
443
+
444
+ ### Internal Governance
445
+
446
+ | Method | HTTP | Description |
447
+ | ---------------------------------------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
448
+ | `client.internal.governance.queryAccess` | `POST /openmeter/governance/query` | Query feature access for a list of customers. The endpoint resolves each provided identifier to a customer and returns the access status for the requested features, plus optional credit balance availability. _Designed to be called on a fixed refresh interval and the query response is intended to be cached._ |
449
+
450
+ ## Runtime Validation (validate option)
451
+
452
+ `validate` is off by default. The SDK's normal request/response mapping
453
+ only renames keys and converts dates — it never rejects a payload — so
454
+ an additive server-side change (a new response field, a new enum value)
455
+ never breaks a client running an older SDK version.
456
+
457
+ Set `validate: true` to additionally check the wire payload — the
458
+ request body after mapping to snake_case, and the raw response before
459
+ mapping back — against the generated `…Wire` schemas. Those schemas are
460
+ strict: an unknown field or an unrecognized enum value fails validation
461
+ instead of being silently accepted. That makes `validate` a tool for
462
+ catching SDK/server contract drift in development or CI, not something
463
+ to run in production, where forward compatibility with additive server
464
+ changes matters more than strict rejection.
465
+
466
+ ```typescript
467
+ import { OpenMeter, ValidationError } from '@openmeter/client'
270
468
 
271
- ### Governance
469
+ const client = new OpenMeter({
470
+ baseUrl: 'https://openmeter.cloud/api/v3',
471
+ apiKey: process.env.OPENMETER_API_KEY,
472
+ validate: true,
473
+ })
272
474
 
273
- | Method | HTTP | Description |
274
- | ------------------------------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
275
- | `client.governance.queryAccess` | `POST /openmeter/governance/query` | Query feature access for a list of customers. The endpoint resolves each provided identifier to a customer and returns the access status for the requested features, plus optional credit balance availability. _Designed to be called on a fixed refresh interval and the query response is intended to be cached._ |
475
+ try {
476
+ await client.meters.get({ meterId: 'meter_123' })
477
+ } catch (error) {
478
+ if (error instanceof ValidationError) {
479
+ console.error(error.issues)
480
+ }
481
+ }
482
+ ```
483
+
484
+ The standalone functions surface the same failure as a `Result` instead
485
+ of throwing — check `result.error instanceof ValidationError`.
486
+
487
+ ## Zod Schemas (./zod export)
488
+
489
+ `@openmeter/client/zod` exports every model twice: once shaped like the
490
+ SDK's public surface (camelCase keys, `Date` for date-time fields — the
491
+ same shape `meter.eventType`/`meter.createdAt` have in TypeScript) and
492
+ once as a strict `…Wire` schema shaped like the literal JSON the server
493
+ sends and accepts (snake_case keys, RFC 3339 date-time strings, unknown
494
+ fields rejected) — the same `…Wire` schemas the `validate` option checks
495
+ internally.
496
+
497
+ Use the public schemas to validate a payload the SDK did not produce —
498
+ a webhook body, a cached record, a test fixture — before trusting its
499
+ shape:
500
+
501
+ ```typescript
502
+ import * as schemas from '@openmeter/client/zod'
503
+
504
+ const parsed = schemas.meter.safeParse({
505
+ id: '01HZY3W6VXQK6H3NPC6DFA0PJT',
506
+ name: 'Tokens',
507
+ key: 'tokens',
508
+ aggregation: 'sum',
509
+ eventType: 'request',
510
+ createdAt: new Date(),
511
+ updatedAt: new Date(),
512
+ })
513
+
514
+ if (parsed.success) {
515
+ console.log(parsed.data.eventType)
516
+ }
517
+ ```
276
518
 
277
519
  ## Error Handling
278
520
 
279
- A non-2xx response rejects with an `HTTPError` carrying the problem-details
280
- fields (`status`, `type`, `title`, `url`) from the response.
521
+ A non-2xx response rejects with an `HTTPError` (`error.name === 'HTTPError'`)
522
+ carrying the problem-details fields (`status`, `type`, `title`, `url`)
523
+ from the response.
281
524
 
282
525
  ```typescript
283
526
  import { OpenMeter, HTTPError } from '@openmeter/client'
@@ -296,6 +539,46 @@ try {
296
539
  }
297
540
  ```
298
541
 
542
+ `error.retryAfter` is the delta-seconds form of a numeric `Retry-After`
543
+ header (the common case on 429 and 503 responses) and `undefined`
544
+ otherwise. A 400 Bad Request additionally carries a typed
545
+ `error.invalidParameters` array describing which fields failed
546
+ validation; `error.getField(key)` is an untyped escape hatch for any
547
+ other problem-details extension member:
548
+
549
+ ```typescript
550
+ import { OpenMeter, HTTPError } from '@openmeter/client'
551
+
552
+ const client = new OpenMeter({
553
+ baseUrl: 'https://openmeter.cloud/api/v3',
554
+ apiKey: process.env.OPENMETER_API_KEY,
555
+ })
556
+
557
+ try {
558
+ await client.meters.create({
559
+ name: 'Tokens',
560
+ key: 'tokens',
561
+ aggregation: 'sum',
562
+ eventType: 'request',
563
+ })
564
+ } catch (error) {
565
+ if (error instanceof HTTPError && error.status === 400) {
566
+ for (const param of error.invalidParameters ?? []) {
567
+ console.error(param)
568
+ }
569
+ }
570
+ }
571
+ ```
572
+
573
+ The SDK's other typed errors are `ValidationError` (see
574
+ [Runtime Validation (validate option)](#runtime-validation-validate-option)), `UnsafeIntegerError`
575
+ (an `int64`/`uint64` value exceeds what JSON can represent without
576
+ precision loss), `DepthLimitExceededError` (response data nested deeper
577
+ than the mapper's safety limit), and `PaginationLimitExceededError` (an
578
+ [Pagination](#pagination) iterable exceeded
579
+ its page-count safety limit) — each distinguished the same way, by
580
+ `instanceof` or by `.name`.
581
+
299
582
  ## Standalone Functions
300
583
 
301
584
  Every method is also available as a standalone, tree-shakeable function
@@ -316,3 +599,18 @@ if (result.ok) {
316
599
  console.error(result.error)
317
600
  }
318
601
  ```
602
+
603
+ `ok`, `err`, and `unwrap` — the helpers `Result` is built from — are
604
+ exported too, so a func call can be unwrapped back into a throwing call
605
+ where that is more convenient:
606
+
607
+ ```typescript
608
+ import { Client, funcs, unwrap } from '@openmeter/client'
609
+
610
+ const client = new Client({
611
+ baseUrl: 'https://openmeter.cloud/api/v3',
612
+ apiKey: process.env.OPENMETER_API_KEY,
613
+ })
614
+
615
+ const meters = unwrap(await funcs.listMeters(client))
616
+ ```
package/dist/core.d.ts CHANGED
@@ -7,4 +7,3 @@ export declare class Client {
7
7
  }
8
8
  export declare function http(client: Client): HTTPClient;
9
9
  export type { HTTPClient };
10
- //# sourceMappingURL=core.d.ts.map