diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock
index 0cd65693..c79024c7 100644
--- a/.speakeasy/gen.lock
+++ b/.speakeasy/gen.lock
@@ -1,19 +1,19 @@
lockVersion: 2.0.0
id: c48cf606-fb42-4a45-9c23-8f0555307828
management:
- docChecksum: 4bd025f53fc2580c1adab2dec1499dca
+ docChecksum: be7c11dcf47add5989f403c393b004f7
docVersion: 1.0.0
speakeasyVersion: 1.787.0
generationVersion: 2.914.0
- releaseVersion: 1.1.26
- configChecksum: 4df5753b337f38beefa79b8bfef8319b
+ releaseVersion: 1.1.27
+ configChecksum: cd57c8a0de51b8a03c8b09310929f01e
repoURL: https://github.com/OpenRouterTeam/python-sdk.git
installationURL: https://github.com/OpenRouterTeam/python-sdk.git
published: true
persistentEdits:
- generation_id: 59507816-56c7-4f0b-90d2-dc5e846961fc
- pristine_commit_hash: 120785b8533df4719a69079a96abe7c26ee4cdc8
- pristine_tree_hash: 3ffd1100c8437295e3f7442d4ee25fecb720cf38
+ generation_id: 2bd77237-503a-4a76-a70e-c30ff7216a4d
+ pristine_commit_hash: 29dd98cf236ec587c0af26a6ee59169e4e4e24be
+ pristine_tree_hash: 6d691315fc84cf5072331ad8a3b838389435d1b0
features:
python:
acceptHeaders: 3.0.0
@@ -2164,6 +2164,10 @@ trackedFiles:
id: 59edec5c97d1
last_write_checksum: sha1:e60a199f393362e0182d4b5aa6218294e6c1af48
pristine_git_object: 3031bf1129e51ad652a31b7142154b49fcc4560f
+ docs/components/getworkspacebudgetresponse.mdx:
+ id: 9a7d2b80e512
+ last_write_checksum: sha1:a299ce75f8736a4d572a06a48e54e00854a63f0b
+ pristine_git_object: 2974de1ffe849cdfc1720bb7e3431a89ac4c9b14
docs/components/getworkspaceresponse.mdx:
id: c8d0c4683019
last_write_checksum: sha1:5d10c3c4510cdc869a740deee62c31e9d2b02cc9
@@ -6320,6 +6324,14 @@ trackedFiles:
id: 751150df8456
last_write_checksum: sha1:dd91989f271487fe03882f979e24cbd19ef1d306
pristine_git_object: 1b1c087538b67ecc69a464735f5af7bfbf777c1e
+ docs/operations/getworkspacebudgetglobals.mdx:
+ id: 364bec52e3ae
+ last_write_checksum: sha1:48f79d1434f1ce76ff36d9f86f84771f61254b3c
+ pristine_git_object: 9aa76f556ce0cdac2fa0c3755f4da8b5fc2db3c1
+ docs/operations/getworkspacebudgetrequest.mdx:
+ id: 55fa8569d4ab
+ last_write_checksum: sha1:1a609b03011bb7c2adadee5296b81d0594a786e9
+ pristine_git_object: 1e5648b8df0a67d2fd9f7da643dacf63b87fcbfb
docs/operations/getworkspaceglobals.mdx:
id: 50abe112c1f4
last_write_checksum: sha1:c01276f8bf7cc4708cd3e6eeea83c4ac9d97ccf6
@@ -7066,16 +7078,16 @@ trackedFiles:
pristine_git_object: f277730478c66312d0e4bbb21fae715a9fcf14b9
docs/sdks/workspaces/README.mdx:
id: 0c75d023ef6b
- last_write_checksum: sha1:f517770e2ba836c7a0f9238dd950829207c5b1ca
- pristine_git_object: 8fc6605c4a67012d439d41aea244c29a333ba787
+ last_write_checksum: sha1:7c5a7d137506704b9afa3d0b93323c0998df5cda
+ pristine_git_object: 9a25256ed9125277444c2d762415eab9a430f1c6
py.typed:
id: 258c3ed47ae4
last_write_checksum: sha1:8efc425ffe830805ffcc0f3055871bdcdc542c60
pristine_git_object: 3e38f1a929f7d6b1d6de74604aa87e3d8f010544
pyproject.toml:
id: 5d07e7d72637
- last_write_checksum: sha1:aa22090e0b0c3844eabb41d5c20ff9f2437a3565
- pristine_git_object: 21b18c4152e6a4ff00490287b5d5d878dda1f8a7
+ last_write_checksum: sha1:a264d9007e08b3eae1c2386bafd532997cef58f4
+ pristine_git_object: 7e513fdef9903e80c52e5722af29177e5be59a12
scripts/prepare_readme.py:
id: e0c5957a6035
last_write_checksum: sha1:77f44b60b98bc126557ec27391f91dfba764bb54
@@ -7102,8 +7114,8 @@ trackedFiles:
pristine_git_object: 86713cfea633e09d33b3d4e65281071fe20e6137
src/openrouter/_version.py:
id: d8d15ad6c586
- last_write_checksum: sha1:27705f13028414481341cd7909e975d4a5b560f2
- pristine_git_object: e7538015b3cbee72d2f456e80b219849ddc5508e
+ last_write_checksum: sha1:d58a79dc88238c0e3e3fe18d9e4dc5a4f537f159
+ pristine_git_object: ace1bde4d196b0fb748a67f2dd51ee2b17331927
src/openrouter/analytics.py:
id: cb406b5aaabb
last_write_checksum: sha1:3ea0f1c73fb9c101b7bc5719da4dd7bf62ff469a
@@ -7146,8 +7158,8 @@ trackedFiles:
pristine_git_object: ad3d247954547814054c01989a2dff3d12b3e4e1
src/openrouter/components/__init__.py:
id: 81754e97b3f4
- last_write_checksum: sha1:b0e873a60c008b4ef8336c155354ee8805dcb76a
- pristine_git_object: 5659a9d1b2a765d579e4b89a13f36163b355b97a
+ last_write_checksum: sha1:6c39e9051ff665be30ed2c1e7e7f64ed272a5622
+ pristine_git_object: 2a8ad9e6785f77e990e9b1818d7d68eae15757ce
src/openrouter/components/aabenchmarkentry.py:
id: e2e0f0b48c82
last_write_checksum: sha1:fab4d9a24d2cea937bb749d46c5f83941e99d65c
@@ -8104,6 +8116,10 @@ trackedFiles:
id: f6dd9e0daa9e
last_write_checksum: sha1:0b1ba09ad5da624c4fdbd1bff5d8919e55133cb9
pristine_git_object: cfca9a058673bf7db640c2cec6d8dfc4f87837bd
+ src/openrouter/components/getworkspacebudgetresponse.py:
+ id: 5ae557de0b72
+ last_write_checksum: sha1:49ee6ebadd481997bf9285d709847e5db8c0911c
+ pristine_git_object: b013b7e50d1573b98fe3f4f2fb08c8494a3e449a
src/openrouter/components/getworkspaceresponse.py:
id: d993d0c4c3da
last_write_checksum: sha1:918535730d1c352bcc8fd2342e1c4cea89bc357f
@@ -9658,8 +9674,8 @@ trackedFiles:
pristine_git_object: 0f62389a8410522fe76eed82c64227903a8605c5
src/openrouter/operations/__init__.py:
id: 9afcea1e7161
- last_write_checksum: sha1:10813e43c7af4d49a27bc034ae9c898a347a883c
- pristine_git_object: 633049645a506d455ecef8e65b8a42edaf36bf42
+ last_write_checksum: sha1:7462feea63bad287e4382464c6a5bf24b401eaa2
+ pristine_git_object: 37c3c8ce47455812f19b303f0b4d34738ee1237a
src/openrouter/operations/bulkaddworkspacemembers.py:
id: e0ed56117619
last_write_checksum: sha1:5c44eb0d40fdece3ac084615f6c6082be4cf1d5a
@@ -9880,6 +9896,10 @@ trackedFiles:
id: 2ead327ab15e
last_write_checksum: sha1:3dff8a41dc00770f6233f94b8233655f8310bc49
pristine_git_object: 1075e4c49f582db35eb921aa25d2b2baeb803dd3
+ src/openrouter/operations/getworkspacebudget.py:
+ id: 1873b593f56e
+ last_write_checksum: sha1:099b2e1c71882774ddd7a998bd47fafffcc3b483
+ pristine_git_object: 54a57c8768e85a76803a6a4002c48a7040b11a85
src/openrouter/operations/list.py:
id: 3ced31e3804e
last_write_checksum: sha1:5db489d16b321c49808ca3da9100839a72903f67
@@ -10174,8 +10194,8 @@ trackedFiles:
pristine_git_object: 6460765cd23146b66e8b3b85bafd83ccf18d21c6
src/openrouter/workspaces.py:
id: cd6c533b1802
- last_write_checksum: sha1:2a0bb110a1b5b9e9fcbca3f46dd4451b3e861cd3
- pristine_git_object: 015ceeebf877ef713bc7257dd47d01ee2c4d144c
+ last_write_checksum: sha1:273ca910cf9ea52419cfc681410fbf00b47adbd8
+ pristine_git_object: d302cb5a478a949511c6de8bbf4260a3d0cfd536
examples:
createResponses:
speakeasy-default-create-responses:
@@ -11635,6 +11655,8 @@ examples:
application/json: {"error": {"code": 404, "message": "Resource not found"}}
"500":
application/json: {"error": {"code": 500, "message": "Internal Server Error"}}
+ "400":
+ application/json: {"error": {"code": 400, "message": "Invalid request parameters"}}
upsertWorkspaceBudget:
speakeasy-default-upsert-workspace-budget:
parameters:
@@ -11865,9 +11887,25 @@ examples:
application/json: {"error": {"code": 404, "message": "Resource not found"}}
"500":
application/json: {"error": {"code": 500, "message": "Internal Server Error"}}
+ getWorkspaceBudget:
+ speakeasy-default-get-workspace-budget:
+ parameters:
+ path:
+ id: "production"
+ interval: "monthly"
+ responses:
+ "200":
+ application/json: {"data": {"created_at": "2025-08-24T10:30:00Z", "id": "770e8400-e29b-41d4-a716-446655440000", "limit_usd": 100, "reset_interval": "monthly", "updated_at": "2025-08-24T15:45:00Z", "workspace_id": "550e8400-e29b-41d4-a716-446655440000"}}
+ "400":
+ application/json: {"error": {"code": 400, "message": "Invalid request parameters"}}
+ "401":
+ application/json: {"error": {"code": 401, "message": "Missing Authentication header"}}
+ "404":
+ application/json: {"error": {"code": 404, "message": "Resource not found"}}
+ "500":
+ application/json: {"error": {"code": 500, "message": "Internal Server Error"}}
examplesVersion: 1.0.2
releaseNotes: |
## Python SDK Changes:
- * `open_router.tts.create_speech()`: `request.input_references` **Added**
- * `open_router.endpoints.list_zdr_endpoints()`: `response.data[].supports_voice_cloning` **Added**
- * `open_router.endpoints.list()`: `response.data.endpoints[].supports_voice_cloning` **Added**
+ * `open_router.workspaces.get_budget()`: **Added**
+ * `open_router.workspaces.delete_budget()`: `error.status[400]` **Added**
diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml
index 6c24f901..a5f7dba1 100644
--- a/.speakeasy/gen.yaml
+++ b/.speakeasy/gen.yaml
@@ -36,7 +36,7 @@ generation:
documentation: mintlify
preApplyUnionDiscriminators: true
python:
- version: 1.1.26
+ version: 1.1.27
additionalDependencies:
dev: {}
main: {}
diff --git a/.speakeasy/out.openapi.yaml b/.speakeasy/out.openapi.yaml
index ab6410d8..2f1ef8bd 100644
--- a/.speakeasy/out.openapi.yaml
+++ b/.speakeasy/out.openapi.yaml
@@ -9635,6 +9635,28 @@ components:
required:
- 'data'
type: 'object'
+ GetWorkspaceBudgetResponse:
+ example:
+ data:
+ created_at: '2025-08-24T10:30:00Z'
+ id: '770e8400-e29b-41d4-a716-446655440000'
+ limit_usd: 100
+ reset_interval: 'monthly'
+ updated_at: '2025-08-24T15:45:00Z'
+ workspace_id: '550e8400-e29b-41d4-a716-446655440000'
+ include_byok_in_budgets: true
+ properties:
+ data:
+ allOf:
+ - $ref: '#/components/schemas/WorkspaceBudget'
+ - description: 'The budget for the requested interval'
+ include_byok_in_budgets:
+ description: 'Whether BYOK (bring-your-own-key) spend is included when enforcing the workspace''s budgets. This is a workspace-wide setting that applies to all budget intervals (daily, weekly, monthly, and lifetime).'
+ example: true
+ type: 'boolean'
+ required:
+ - 'data'
+ type: 'object'
GetWorkspaceResponse:
example:
data:
@@ -37462,6 +37484,16 @@ paths:
schema:
$ref: '#/components/schemas/DeleteWorkspaceBudgetResponse'
description: 'Budget deleted successfully'
+ '400':
+ content:
+ application/json:
+ example:
+ error:
+ code: 400
+ message: 'Invalid request parameters'
+ schema:
+ $ref: '#/components/schemas/BadRequestResponse'
+ description: 'Bad Request - Invalid request parameters or malformed input'
'401':
content:
application/json:
@@ -37496,6 +37528,86 @@ paths:
tags:
- 'Workspaces'
x-speakeasy-name-override: 'deleteBudget'
+ get:
+ description: 'Retrieve the budget for a given interval. [Management key](/docs/guides/overview/auth/management-api-keys) required.'
+ operationId: 'getWorkspaceBudget'
+ parameters:
+ - description: 'The workspace ID (UUID) or slug'
+ in: 'path'
+ name: 'id'
+ required: true
+ schema:
+ description: 'The workspace ID (UUID) or slug'
+ example: 'production'
+ minLength: 1
+ type: 'string'
+ - description: 'Budget reset interval. Use "lifetime" for a one-time budget that never resets.'
+ example: 'monthly'
+ in: 'path'
+ name: 'interval'
+ required: true
+ schema:
+ $ref: '#/components/schemas/WorkspaceBudgetInterval'
+ responses:
+ '200':
+ content:
+ application/json:
+ example:
+ data:
+ created_at: '2025-08-24T10:30:00Z'
+ id: '770e8400-e29b-41d4-a716-446655440000'
+ limit_usd: 100
+ reset_interval: 'monthly'
+ updated_at: '2025-08-24T15:45:00Z'
+ workspace_id: '550e8400-e29b-41d4-a716-446655440000'
+ include_byok_in_budgets: true
+ schema:
+ $ref: '#/components/schemas/GetWorkspaceBudgetResponse'
+ description: 'Budget retrieved successfully'
+ '400':
+ content:
+ application/json:
+ example:
+ error:
+ code: 400
+ message: 'Invalid request parameters'
+ schema:
+ $ref: '#/components/schemas/BadRequestResponse'
+ description: 'Bad Request - Invalid request parameters or malformed input'
+ '401':
+ content:
+ application/json:
+ example:
+ error:
+ code: 401
+ message: 'Missing Authentication header'
+ schema:
+ $ref: '#/components/schemas/UnauthorizedResponse'
+ description: 'Unauthorized - Authentication required or invalid credentials'
+ '404':
+ content:
+ application/json:
+ example:
+ error:
+ code: 404
+ message: 'Resource not found'
+ schema:
+ $ref: '#/components/schemas/NotFoundResponse'
+ description: 'Not Found - Resource does not exist'
+ '500':
+ content:
+ application/json:
+ example:
+ error:
+ code: 500
+ message: 'Internal Server Error'
+ schema:
+ $ref: '#/components/schemas/InternalServerResponse'
+ description: 'Internal Server Error - Unexpected server error'
+ summary: 'Get a workspace budget'
+ tags:
+ - 'Workspaces'
+ x-speakeasy-name-override: 'getBudget'
put:
description: 'Create or update the budget for a given interval. Budget limits must strictly decrease as the interval narrows (lifetime > monthly > weekly > daily). The optional `include_byok_in_budgets` flag is a workspace-wide setting: when provided it applies to every budget interval for the workspace, not just the interval in this request. Note that a change made here is applied to budget enforcement immediately, but an already-open workspace settings page in the web dashboard may keep showing the previous value until it is reloaded. [Management key](/docs/guides/overview/auth/management-api-keys) required.'
operationId: 'upsertWorkspaceBudget'
diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock
index dd1f2696..fbb5cbdc 100644
--- a/.speakeasy/workflow.lock
+++ b/.speakeasy/workflow.lock
@@ -2,8 +2,8 @@ speakeasyVersion: 1.787.0
sources:
OpenRouter API:
sourceNamespace: open-router-chat-completions-api
- sourceRevisionDigest: sha256:f1344cdf479044bc22ce6c0e6b8d5e967069bce83ca7dd363b54c28cd148fb95
- sourceBlobDigest: sha256:9631f74074cfdeca4f58e1f195991bccbf8053252aada6bdbdd29baa8217ff08
+ sourceRevisionDigest: sha256:f89a07d7220907360b9ac5ecea709b3307e39d9ab5bf499fe78541628d17f37c
+ sourceBlobDigest: sha256:439eb2fb58b83d4959ec1bddce024c1a426f31d3b6d21f130383a9c6d611b17f
tags:
- latest
- 1.0.0
@@ -11,10 +11,10 @@ targets:
open-router:
source: OpenRouter API
sourceNamespace: open-router-chat-completions-api
- sourceRevisionDigest: sha256:f1344cdf479044bc22ce6c0e6b8d5e967069bce83ca7dd363b54c28cd148fb95
- sourceBlobDigest: sha256:9631f74074cfdeca4f58e1f195991bccbf8053252aada6bdbdd29baa8217ff08
+ sourceRevisionDigest: sha256:f89a07d7220907360b9ac5ecea709b3307e39d9ab5bf499fe78541628d17f37c
+ sourceBlobDigest: sha256:439eb2fb58b83d4959ec1bddce024c1a426f31d3b6d21f130383a9c6d611b17f
codeSamplesNamespace: open-router-python-code-samples
- codeSamplesRevisionDigest: sha256:7ab6893fadfccf77a50b9b75a78da89433261a20515c86ac3daa2cdd75e78cda
+ codeSamplesRevisionDigest: sha256:5e817705b5cab5aa1a246b2d529ca39c280a66a80484e15a8e9708faf9190f89
workflow:
workflowVersion: 1.0.0
speakeasyVersion: 1.787.0
diff --git a/RELEASES.md b/RELEASES.md
index 8968f184..25db371f 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1049,4 +1049,14 @@ Based on:
### Generated
- [python v1.1.26] .
### Releases
-- [PyPI v1.1.26] https://pypi.org/project/openrouter/1.1.26 - .
\ No newline at end of file
+- [PyPI v1.1.26] https://pypi.org/project/openrouter/1.1.26 - .
+
+## 2026-08-04 06:55:49
+### Changes
+Based on:
+- OpenAPI Doc
+- Speakeasy CLI 1.787.0 (2.914.0) https://github.com/speakeasy-api/speakeasy
+### Generated
+- [python v1.1.27] .
+### Releases
+- [PyPI v1.1.27] https://pypi.org/project/openrouter/1.1.27 - .
\ No newline at end of file
diff --git a/docs/components/getworkspacebudgetresponse.mdx b/docs/components/getworkspacebudgetresponse.mdx
new file mode 100644
index 00000000..2974de1f
--- /dev/null
+++ b/docs/components/getworkspacebudgetresponse.mdx
@@ -0,0 +1,10 @@
+---
+title: "GetWorkspaceBudgetResponse"
+---
+
+## Fields
+
+| Field | Type | Required | Description | Example |
+| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `data` | [components.WorkspaceBudget](../components/workspacebudget.mdx) | :heavy_check_mark: | N/A | \{
"created_at": "2025-08-24T10:30:00Z",
"id": "770e8400-e29b-41d4-a716-446655440000",
"limit_usd": 100,
"reset_interval": "monthly",
"updated_at": "2025-08-24T15:45:00Z",
"workspace_id": "550e8400-e29b-41d4-a716-446655440000"
} |
+| `include_byok_in_budgets` | *Optional[bool]* | :heavy_minus_sign: | Whether BYOK (bring-your-own-key) spend is included when enforcing the workspace's budgets. This is a workspace-wide setting that applies to all budget intervals (daily, weekly, monthly, and lifetime). | true |
\ No newline at end of file
diff --git a/docs/operations/getworkspacebudgetglobals.mdx b/docs/operations/getworkspacebudgetglobals.mdx
new file mode 100644
index 00000000..9aa76f55
--- /dev/null
+++ b/docs/operations/getworkspacebudgetglobals.mdx
@@ -0,0 +1,11 @@
+---
+title: "GetWorkspaceBudgetGlobals"
+---
+
+## Fields
+
+| Field | Type | Required | Description |
+| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
|
+| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
|
+| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
|
\ No newline at end of file
diff --git a/docs/operations/getworkspacebudgetrequest.mdx b/docs/operations/getworkspacebudgetrequest.mdx
new file mode 100644
index 00000000..1e5648b8
--- /dev/null
+++ b/docs/operations/getworkspacebudgetrequest.mdx
@@ -0,0 +1,13 @@
+---
+title: "GetWorkspaceBudgetRequest"
+---
+
+## Fields
+
+| Field | Type | Required | Description | Example |
+| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| |
+| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| |
+| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| |
+| `id` | *str* | :heavy_check_mark: | The workspace ID (UUID) or slug | production |
+| `interval` | [components.WorkspaceBudgetInterval](../components/workspacebudgetinterval.mdx) | :heavy_check_mark: | Budget reset interval. Use "lifetime" for a one-time budget that never resets. | monthly |
\ No newline at end of file
diff --git a/docs/sdks/workspaces/README.mdx b/docs/sdks/workspaces/README.mdx
index 8fc6605c..9a25256e 100644
--- a/docs/sdks/workspaces/README.mdx
+++ b/docs/sdks/workspaces/README.mdx
@@ -16,6 +16,7 @@ Workspaces endpoints
* [update](#update) - Update a workspace
* [list_budgets](#list_budgets) - List workspace budgets
* [delete_budget](#delete_budget) - Delete a workspace budget
+* [get_budget](#get_budget) - Get a workspace budget
* [set_budget](#set_budget) - Create or update a workspace budget
* [list_members](#list_members) - List workspace members
* [bulk_add_members](#bulk_add_members) - Bulk add members to a workspace
@@ -381,6 +382,57 @@ with OpenRouter(
| Error Type | Status Code | Content Type |
| ---------------------------------- | ---------------------------------- | ---------------------------------- |
+| errors.BadRequestResponseError | 400 | application/json |
+| errors.UnauthorizedResponseError | 401 | application/json |
+| errors.NotFoundResponseError | 404 | application/json |
+| errors.InternalServerResponseError | 500 | application/json |
+| errors.OpenRouterDefaultError | 4XX, 5XX | \*/\* |
+
+## get_budget
+
+Retrieve the budget for a given interval. [Management key](/docs/guides/overview/auth/management-api-keys) required.
+
+### Example Usage
+
+```python
+from openrouter import OpenRouter
+import os
+
+
+with OpenRouter(
+ http_referer="",
+ x_open_router_title="",
+ x_open_router_categories="",
+ api_key=os.getenv("OPENROUTER_API_KEY", ""),
+) as open_router:
+
+ res = open_router.workspaces.get_budget(id="production", interval="monthly")
+
+ # Handle response
+ print(res)
+
+```
+
+### Parameters
+
+| Parameter | Type | Required | Description | Example |
+| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `id` | *str* | :heavy_check_mark: | The workspace ID (UUID) or slug | production |
+| `interval` | [components.WorkspaceBudgetInterval](../../components/workspacebudgetinterval.mdx) | :heavy_check_mark: | Budget reset interval. Use "lifetime" for a one-time budget that never resets. | monthly |
+| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| |
+| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| |
+| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| |
+| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.mdx) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | |
+
+### Response
+
+**[components.GetWorkspaceBudgetResponse](../../components/getworkspacebudgetresponse.mdx)**
+
+### Errors
+
+| Error Type | Status Code | Content Type |
+| ---------------------------------- | ---------------------------------- | ---------------------------------- |
+| errors.BadRequestResponseError | 400 | application/json |
| errors.UnauthorizedResponseError | 401 | application/json |
| errors.NotFoundResponseError | 404 | application/json |
| errors.InternalServerResponseError | 500 | application/json |
diff --git a/pyproject.toml b/pyproject.toml
index 21b18c41..7e513fde 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "openrouter"
-version = "1.1.26"
+version = "1.1.27"
description = "Official Python Client SDK for OpenRouter."
authors = [{ name = "OpenRouter" },]
readme = "README-PYPI.md"
diff --git a/src/openrouter/_version.py b/src/openrouter/_version.py
index e7538015..ace1bde4 100644
--- a/src/openrouter/_version.py
+++ b/src/openrouter/_version.py
@@ -3,10 +3,10 @@
import importlib.metadata
__title__: str = "openrouter"
-__version__: str = "1.1.26"
+__version__: str = "1.1.27"
__openapi_doc_version__: str = "1.0.0"
__gen_version__: str = "2.914.0"
-__user_agent__: str = "speakeasy-sdk/python 1.1.26 2.914.0 1.0.0 openrouter"
+__user_agent__: str = "speakeasy-sdk/python 1.1.27 2.914.0 1.0.0 openrouter"
try:
if __package__ is not None:
diff --git a/src/openrouter/components/__init__.py b/src/openrouter/components/__init__.py
index 5659a9d1..2a8ad9e6 100644
--- a/src/openrouter/components/__init__.py
+++ b/src/openrouter/components/__init__.py
@@ -1181,6 +1181,10 @@
GetScimGroupMappingResponse,
GetScimGroupMappingResponseTypedDict,
)
+ from .getworkspacebudgetresponse import (
+ GetWorkspaceBudgetResponse,
+ GetWorkspaceBudgetResponseTypedDict,
+ )
from .getworkspaceresponse import (
GetWorkspaceResponse,
GetWorkspaceResponseTypedDict,
@@ -3866,6 +3870,8 @@
"GetPresetVersionResponseTypedDict",
"GetScimGroupMappingResponse",
"GetScimGroupMappingResponseTypedDict",
+ "GetWorkspaceBudgetResponse",
+ "GetWorkspaceBudgetResponseTypedDict",
"GetWorkspaceResponse",
"GetWorkspaceResponseTypedDict",
"Guardrail",
@@ -6067,6 +6073,8 @@
"GetPresetVersionResponseTypedDict": ".getpresetversionresponse",
"GetScimGroupMappingResponse": ".getscimgroupmappingresponse",
"GetScimGroupMappingResponseTypedDict": ".getscimgroupmappingresponse",
+ "GetWorkspaceBudgetResponse": ".getworkspacebudgetresponse",
+ "GetWorkspaceBudgetResponseTypedDict": ".getworkspacebudgetresponse",
"GetWorkspaceResponse": ".getworkspaceresponse",
"GetWorkspaceResponseTypedDict": ".getworkspaceresponse",
"Guardrail": ".guardrail",
diff --git a/src/openrouter/components/getworkspacebudgetresponse.py b/src/openrouter/components/getworkspacebudgetresponse.py
new file mode 100644
index 00000000..b013b7e5
--- /dev/null
+++ b/src/openrouter/components/getworkspacebudgetresponse.py
@@ -0,0 +1,37 @@
+"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
+
+from __future__ import annotations
+from .workspacebudget import WorkspaceBudget, WorkspaceBudgetTypedDict
+from openrouter.types import BaseModel, UNSET_SENTINEL
+from pydantic import model_serializer
+from typing import Optional
+from typing_extensions import NotRequired, TypedDict
+
+
+class GetWorkspaceBudgetResponseTypedDict(TypedDict):
+ data: WorkspaceBudgetTypedDict
+ include_byok_in_budgets: NotRequired[bool]
+ r"""Whether BYOK (bring-your-own-key) spend is included when enforcing the workspace's budgets. This is a workspace-wide setting that applies to all budget intervals (daily, weekly, monthly, and lifetime)."""
+
+
+class GetWorkspaceBudgetResponse(BaseModel):
+ data: WorkspaceBudget
+
+ include_byok_in_budgets: Optional[bool] = None
+ r"""Whether BYOK (bring-your-own-key) spend is included when enforcing the workspace's budgets. This is a workspace-wide setting that applies to all budget intervals (daily, weekly, monthly, and lifetime)."""
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(["include_byok_in_budgets"])
+ serialized = handler(self)
+ m = {}
+
+ for n, f in type(self).model_fields.items():
+ k = f.alias or n
+ val = serialized.get(k, serialized.get(n))
+
+ if val != UNSET_SENTINEL:
+ if val is not None or k not in optional_fields:
+ m[k] = val
+
+ return m
diff --git a/src/openrouter/operations/__init__.py b/src/openrouter/operations/__init__.py
index 63304964..37c3c8ce 100644
--- a/src/openrouter/operations/__init__.py
+++ b/src/openrouter/operations/__init__.py
@@ -469,6 +469,12 @@
GetWorkspaceRequest,
GetWorkspaceRequestTypedDict,
)
+ from .getworkspacebudget import (
+ GetWorkspaceBudgetGlobals,
+ GetWorkspaceBudgetGlobalsTypedDict,
+ GetWorkspaceBudgetRequest,
+ GetWorkspaceBudgetRequestTypedDict,
+ )
from .list import (
ListData,
ListDataTypedDict,
@@ -1127,6 +1133,10 @@
"GetVideosGlobalsTypedDict",
"GetVideosRequest",
"GetVideosRequestTypedDict",
+ "GetWorkspaceBudgetGlobals",
+ "GetWorkspaceBudgetGlobalsTypedDict",
+ "GetWorkspaceBudgetRequest",
+ "GetWorkspaceBudgetRequestTypedDict",
"GetWorkspaceGlobals",
"GetWorkspaceGlobalsTypedDict",
"GetWorkspaceRequest",
@@ -1774,6 +1784,10 @@
"GetWorkspaceGlobalsTypedDict": ".getworkspace",
"GetWorkspaceRequest": ".getworkspace",
"GetWorkspaceRequestTypedDict": ".getworkspace",
+ "GetWorkspaceBudgetGlobals": ".getworkspacebudget",
+ "GetWorkspaceBudgetGlobalsTypedDict": ".getworkspacebudget",
+ "GetWorkspaceBudgetRequest": ".getworkspacebudget",
+ "GetWorkspaceBudgetRequestTypedDict": ".getworkspacebudget",
"ListData": ".list",
"ListDataTypedDict": ".list",
"ListGlobals": ".list",
diff --git a/src/openrouter/operations/getworkspacebudget.py b/src/openrouter/operations/getworkspacebudget.py
new file mode 100644
index 00000000..54a57c87
--- /dev/null
+++ b/src/openrouter/operations/getworkspacebudget.py
@@ -0,0 +1,155 @@
+"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
+
+from __future__ import annotations
+from openrouter.components import (
+ workspacebudgetinterval as components_workspacebudgetinterval,
+)
+from openrouter.types import BaseModel, UNSET_SENTINEL
+from openrouter.utils import FieldMetadata, HeaderMetadata, PathParamMetadata
+import pydantic
+from pydantic import model_serializer
+from typing import Optional
+from typing_extensions import Annotated, NotRequired, TypedDict
+
+
+class GetWorkspaceBudgetGlobalsTypedDict(TypedDict):
+ http_referer: NotRequired[str]
+ r"""The app identifier should be your app's URL and is used as the primary identifier for rankings.
+ This is used to track API usage per application.
+
+ """
+ x_open_router_title: NotRequired[str]
+ r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard.
+
+ """
+ x_open_router_categories: NotRequired[str]
+ r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings.
+
+ """
+
+
+class GetWorkspaceBudgetGlobals(BaseModel):
+ http_referer: Annotated[
+ Optional[str],
+ pydantic.Field(alias="HTTP-Referer"),
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
+ ] = None
+ r"""The app identifier should be your app's URL and is used as the primary identifier for rankings.
+ This is used to track API usage per application.
+
+ """
+
+ x_open_router_title: Annotated[
+ Optional[str],
+ pydantic.Field(alias="X-OpenRouter-Title"),
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
+ ] = None
+ r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard.
+
+ """
+
+ x_open_router_categories: Annotated[
+ Optional[str],
+ pydantic.Field(alias="X-OpenRouter-Categories"),
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
+ ] = None
+ r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings.
+
+ """
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(
+ ["HTTP-Referer", "X-OpenRouter-Title", "X-OpenRouter-Categories"]
+ )
+ serialized = handler(self)
+ m = {}
+
+ for n, f in type(self).model_fields.items():
+ k = f.alias or n
+ val = serialized.get(k, serialized.get(n))
+
+ if val != UNSET_SENTINEL:
+ if val is not None or k not in optional_fields:
+ m[k] = val
+
+ return m
+
+
+class GetWorkspaceBudgetRequestTypedDict(TypedDict):
+ id: str
+ r"""The workspace ID (UUID) or slug"""
+ interval: components_workspacebudgetinterval.WorkspaceBudgetInterval
+ r"""Budget reset interval. Use \"lifetime\" for a one-time budget that never resets."""
+ http_referer: NotRequired[str]
+ r"""The app identifier should be your app's URL and is used as the primary identifier for rankings.
+ This is used to track API usage per application.
+
+ """
+ x_open_router_title: NotRequired[str]
+ r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard.
+
+ """
+ x_open_router_categories: NotRequired[str]
+ r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings.
+
+ """
+
+
+class GetWorkspaceBudgetRequest(BaseModel):
+ id: Annotated[
+ str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))
+ ]
+ r"""The workspace ID (UUID) or slug"""
+
+ interval: Annotated[
+ components_workspacebudgetinterval.WorkspaceBudgetInterval,
+ FieldMetadata(path=PathParamMetadata(style="simple", explode=False)),
+ ]
+ r"""Budget reset interval. Use \"lifetime\" for a one-time budget that never resets."""
+
+ http_referer: Annotated[
+ Optional[str],
+ pydantic.Field(alias="HTTP-Referer"),
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
+ ] = None
+ r"""The app identifier should be your app's URL and is used as the primary identifier for rankings.
+ This is used to track API usage per application.
+
+ """
+
+ x_open_router_title: Annotated[
+ Optional[str],
+ pydantic.Field(alias="X-OpenRouter-Title"),
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
+ ] = None
+ r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard.
+
+ """
+
+ x_open_router_categories: Annotated[
+ Optional[str],
+ pydantic.Field(alias="X-OpenRouter-Categories"),
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
+ ] = None
+ r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings.
+
+ """
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(
+ ["HTTP-Referer", "X-OpenRouter-Title", "X-OpenRouter-Categories"]
+ )
+ serialized = handler(self)
+ m = {}
+
+ for n, f in type(self).model_fields.items():
+ k = f.alias or n
+ val = serialized.get(k, serialized.get(n))
+
+ if val != UNSET_SENTINEL:
+ if val is not None or k not in optional_fields:
+ m[k] = val
+
+ return m
diff --git a/src/openrouter/workspaces.py b/src/openrouter/workspaces.py
index 015ceeeb..d302cb5a 100644
--- a/src/openrouter/workspaces.py
+++ b/src/openrouter/workspaces.py
@@ -1941,6 +1941,11 @@ def delete_budget(
return unmarshal_json_response(
components.DeleteWorkspaceBudgetResponse, http_res
)
+ if utils.match_response(http_res, "400", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.BadRequestResponseErrorData, http_res
+ )
+ raise errors.BadRequestResponseError(response_data, http_res)
if utils.match_response(http_res, "401", "application/json"):
response_data = unmarshal_json_response(
errors.UnauthorizedResponseErrorData, http_res
@@ -2074,6 +2079,287 @@ async def delete_budget_async(
return unmarshal_json_response(
components.DeleteWorkspaceBudgetResponse, http_res
)
+ if utils.match_response(http_res, "400", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.BadRequestResponseErrorData, http_res
+ )
+ raise errors.BadRequestResponseError(response_data, http_res)
+ if utils.match_response(http_res, "401", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.UnauthorizedResponseErrorData, http_res
+ )
+ raise errors.UnauthorizedResponseError(response_data, http_res)
+ if utils.match_response(http_res, "404", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.NotFoundResponseErrorData, http_res
+ )
+ raise errors.NotFoundResponseError(response_data, http_res)
+ if utils.match_response(http_res, "500", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.InternalServerResponseErrorData, http_res
+ )
+ raise errors.InternalServerResponseError(response_data, http_res)
+ if utils.match_response(http_res, "4XX", "*"):
+ http_res_text = await utils.stream_to_text_async(http_res)
+ raise errors.OpenRouterDefaultError(
+ "API error occurred", http_res, http_res_text
+ )
+ if utils.match_response(http_res, "5XX", "*"):
+ http_res_text = await utils.stream_to_text_async(http_res)
+ raise errors.OpenRouterDefaultError(
+ "API error occurred", http_res, http_res_text
+ )
+
+ raise errors.OpenRouterDefaultError("Unexpected response received", http_res)
+
+ def get_budget(
+ self,
+ *,
+ id: str,
+ interval: components.WorkspaceBudgetInterval,
+ http_referer: Optional[str] = None,
+ x_open_router_title: Optional[str] = None,
+ x_open_router_categories: Optional[str] = None,
+ retries: OptionalNullable[utils.RetryConfig] = UNSET,
+ server_url: Optional[str] = None,
+ timeout_ms: Optional[int] = None,
+ http_headers: Optional[Mapping[str, str]] = None,
+ ) -> components.GetWorkspaceBudgetResponse:
+ r"""Get a workspace budget
+
+ Retrieve the budget for a given interval. [Management key](/docs/guides/overview/auth/management-api-keys) required.
+
+ :param id: The workspace ID (UUID) or slug
+ :param interval: Budget reset interval. Use \"lifetime\" for a one-time budget that never resets.
+ :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings.
+ This is used to track API usage per application.
+
+ :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard.
+
+ :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings.
+
+ :param retries: Override the default retry configuration for this method
+ :param server_url: Override the default server URL for this method
+ :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
+ :param http_headers: Additional headers to set or replace on requests.
+ """
+ base_url = None
+ url_variables = None
+ if timeout_ms is None:
+ timeout_ms = self.sdk_configuration.timeout_ms
+
+ if server_url is not None:
+ base_url = server_url
+ else:
+ base_url = self._get_url(base_url, url_variables)
+
+ request = operations.GetWorkspaceBudgetRequest(
+ http_referer=http_referer,
+ x_open_router_title=x_open_router_title,
+ x_open_router_categories=x_open_router_categories,
+ id=id,
+ interval=interval,
+ )
+
+ req = self._build_request(
+ method="GET",
+ path="/workspaces/{id}/budgets/{interval}",
+ base_url=base_url,
+ url_variables=url_variables,
+ request=request,
+ request_body_required=False,
+ request_has_path_params=True,
+ request_has_query_params=True,
+ user_agent_header="user-agent",
+ accept_header_value="application/json",
+ http_headers=http_headers,
+ _globals=operations.GetWorkspaceBudgetGlobals(
+ http_referer=self.sdk_configuration.globals.http_referer,
+ x_open_router_title=self.sdk_configuration.globals.x_open_router_title,
+ x_open_router_categories=self.sdk_configuration.globals.x_open_router_categories,
+ ),
+ security=self.sdk_configuration.security,
+ allow_empty_value=None,
+ timeout_ms=timeout_ms,
+ )
+
+ if retries == UNSET:
+ if self.sdk_configuration.retry_config is not UNSET:
+ retries = self.sdk_configuration.retry_config
+ else:
+ retries = utils.RetryConfig(
+ "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True
+ )
+
+ retry_config = None
+ if isinstance(retries, utils.RetryConfig):
+ retry_config = (retries, ["5XX"])
+
+ http_res = self.do_request(
+ hook_ctx=HookContext(
+ config=self.sdk_configuration,
+ base_url=base_url or "",
+ operation_id="getWorkspaceBudget",
+ oauth2_scopes=None,
+ security_source=get_security_from_env(
+ self.sdk_configuration.security, components.Security
+ ),
+ tags=["Workspaces"],
+ extensions=None,
+ ),
+ request=req,
+ is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
+ retry_config=retry_config,
+ )
+
+ response_data: Any = None
+ if utils.match_response(http_res, "200", "application/json"):
+ return unmarshal_json_response(
+ components.GetWorkspaceBudgetResponse, http_res
+ )
+ if utils.match_response(http_res, "400", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.BadRequestResponseErrorData, http_res
+ )
+ raise errors.BadRequestResponseError(response_data, http_res)
+ if utils.match_response(http_res, "401", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.UnauthorizedResponseErrorData, http_res
+ )
+ raise errors.UnauthorizedResponseError(response_data, http_res)
+ if utils.match_response(http_res, "404", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.NotFoundResponseErrorData, http_res
+ )
+ raise errors.NotFoundResponseError(response_data, http_res)
+ if utils.match_response(http_res, "500", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.InternalServerResponseErrorData, http_res
+ )
+ raise errors.InternalServerResponseError(response_data, http_res)
+ if utils.match_response(http_res, "4XX", "*"):
+ http_res_text = utils.stream_to_text(http_res)
+ raise errors.OpenRouterDefaultError(
+ "API error occurred", http_res, http_res_text
+ )
+ if utils.match_response(http_res, "5XX", "*"):
+ http_res_text = utils.stream_to_text(http_res)
+ raise errors.OpenRouterDefaultError(
+ "API error occurred", http_res, http_res_text
+ )
+
+ raise errors.OpenRouterDefaultError("Unexpected response received", http_res)
+
+ async def get_budget_async(
+ self,
+ *,
+ id: str,
+ interval: components.WorkspaceBudgetInterval,
+ http_referer: Optional[str] = None,
+ x_open_router_title: Optional[str] = None,
+ x_open_router_categories: Optional[str] = None,
+ retries: OptionalNullable[utils.RetryConfig] = UNSET,
+ server_url: Optional[str] = None,
+ timeout_ms: Optional[int] = None,
+ http_headers: Optional[Mapping[str, str]] = None,
+ ) -> components.GetWorkspaceBudgetResponse:
+ r"""Get a workspace budget
+
+ Retrieve the budget for a given interval. [Management key](/docs/guides/overview/auth/management-api-keys) required.
+
+ :param id: The workspace ID (UUID) or slug
+ :param interval: Budget reset interval. Use \"lifetime\" for a one-time budget that never resets.
+ :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings.
+ This is used to track API usage per application.
+
+ :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard.
+
+ :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings.
+
+ :param retries: Override the default retry configuration for this method
+ :param server_url: Override the default server URL for this method
+ :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
+ :param http_headers: Additional headers to set or replace on requests.
+ """
+ base_url = None
+ url_variables = None
+ if timeout_ms is None:
+ timeout_ms = self.sdk_configuration.timeout_ms
+
+ if server_url is not None:
+ base_url = server_url
+ else:
+ base_url = self._get_url(base_url, url_variables)
+
+ request = operations.GetWorkspaceBudgetRequest(
+ http_referer=http_referer,
+ x_open_router_title=x_open_router_title,
+ x_open_router_categories=x_open_router_categories,
+ id=id,
+ interval=interval,
+ )
+
+ req = self._build_request_async(
+ method="GET",
+ path="/workspaces/{id}/budgets/{interval}",
+ base_url=base_url,
+ url_variables=url_variables,
+ request=request,
+ request_body_required=False,
+ request_has_path_params=True,
+ request_has_query_params=True,
+ user_agent_header="user-agent",
+ accept_header_value="application/json",
+ http_headers=http_headers,
+ _globals=operations.GetWorkspaceBudgetGlobals(
+ http_referer=self.sdk_configuration.globals.http_referer,
+ x_open_router_title=self.sdk_configuration.globals.x_open_router_title,
+ x_open_router_categories=self.sdk_configuration.globals.x_open_router_categories,
+ ),
+ security=self.sdk_configuration.security,
+ allow_empty_value=None,
+ timeout_ms=timeout_ms,
+ )
+
+ if retries == UNSET:
+ if self.sdk_configuration.retry_config is not UNSET:
+ retries = self.sdk_configuration.retry_config
+ else:
+ retries = utils.RetryConfig(
+ "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True
+ )
+
+ retry_config = None
+ if isinstance(retries, utils.RetryConfig):
+ retry_config = (retries, ["5XX"])
+
+ http_res = await self.do_request_async(
+ hook_ctx=HookContext(
+ config=self.sdk_configuration,
+ base_url=base_url or "",
+ operation_id="getWorkspaceBudget",
+ oauth2_scopes=None,
+ security_source=get_security_from_env(
+ self.sdk_configuration.security, components.Security
+ ),
+ tags=["Workspaces"],
+ extensions=None,
+ ),
+ request=req,
+ is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
+ retry_config=retry_config,
+ )
+
+ response_data: Any = None
+ if utils.match_response(http_res, "200", "application/json"):
+ return unmarshal_json_response(
+ components.GetWorkspaceBudgetResponse, http_res
+ )
+ if utils.match_response(http_res, "400", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.BadRequestResponseErrorData, http_res
+ )
+ raise errors.BadRequestResponseError(response_data, http_res)
if utils.match_response(http_res, "401", "application/json"):
response_data = unmarshal_json_response(
errors.UnauthorizedResponseErrorData, http_res
diff --git a/uv.lock b/uv.lock
index 0df521a4..f06b50fa 100644
--- a/uv.lock
+++ b/uv.lock
@@ -213,7 +213,7 @@ wheels = [
[[package]]
name = "openrouter"
-version = "1.1.26"
+version = "1.1.27"
source = { editable = "." }
dependencies = [
{ name = "httpcore" },