diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock
index fa33017f..4e0f7c47 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: 3ebd1783ba3cfc3a0c50703a0e68b47c
+ docChecksum: b64b8038ee4885e5d0f067c4c32d0854
docVersion: 1.0.0
speakeasyVersion: 1.787.0
generationVersion: 2.914.0
- releaseVersion: 1.1.24
- configChecksum: 84d0cb0f6d7787cc8b9d87434368c723
+ releaseVersion: 1.1.25
+ configChecksum: a0f975c0103c1b113ff0be95a912fdec
repoURL: https://github.com/OpenRouterTeam/python-sdk.git
installationURL: https://github.com/OpenRouterTeam/python-sdk.git
published: true
persistentEdits:
- generation_id: 55f5a43c-95e5-444d-b73b-1fd3a19b2bb6
- pristine_commit_hash: becb0f2b63d97e0e0f7b2d1ed163272993bc07b8
- pristine_tree_hash: a25dac1fe5f7f9cb37a90f28bb6bf1a1b6abcea3
+ generation_id: 2e8f1b9f-2b27-4c78-b6f5-f0fbefc43ba8
+ pristine_commit_hash: d1180f9a5bbbb3f93a5c3737499e5de0dcd089b5
+ pristine_tree_hash: e714febd611cdf32d9f6d305a54e2c9d7b7365ec
features:
python:
acceptHeaders: 3.0.0
@@ -102,8 +102,8 @@ trackedFiles:
pristine_git_object: dc49d753ad25e6dcf9265946f3a87a8bffd46d4a
docs/components/activityitem.mdx:
id: 20be851aee8a
- last_write_checksum: sha1:03ce9c177882d8b0edbea014961061af81b50360
- pristine_git_object: 0910645c06285f1ef165198c24f6fb9c3b1a8d7c
+ last_write_checksum: sha1:4aef3633b891fc44c92cb8307adb8d3ce3e7cecd
+ pristine_git_object: 595c3f1bcc1bb17e920c06fb11df7dae95b6b858
docs/components/activityresponse.mdx:
id: 5886155bc810
last_write_checksum: sha1:64acd6c3d2db5593d8359474c4e2e31e4db62453
@@ -2138,8 +2138,8 @@ trackedFiles:
pristine_git_object: b876dce8ca019098465106bf05b11c5e0b9536f0
docs/components/generationresponsedata.mdx:
id: 5c92bc415596
- last_write_checksum: sha1:42b5efb0895c5ad283b69d7d03f89468d17caf94
- pristine_git_object: 54187e678e3f2b35786e5f531d42e0c3c67f2d4a
+ last_write_checksum: sha1:bfd323dcacd9548a6fa16ff15a1d5def429fbf71
+ pristine_git_object: d8beea524e93ab8059a7eca00b12316e681252da
docs/components/getbyokkeyresponse.mdx:
id: 451f36940fbd
last_write_checksum: sha1:d5e3f4ef481598c92e4e4842442eeeba8a2627e9
@@ -6074,8 +6074,8 @@ trackedFiles:
pristine_git_object: 2642f99d77ceb5007b1b863028d73c07e48dac67
docs/operations/filter_.mdx:
id: 79b9c7c02d3b
- last_write_checksum: sha1:210f8d87b466cf10785abbd4cb2f9eb2c3e8576e
- pristine_git_object: 3dbded7e52c79b46c586b5b459ef9febaf6f37f1
+ last_write_checksum: sha1:4aa4ba9558d9bdfeef9b73fd78c3c14884c589e4
+ pristine_git_object: 3397e42a132f1de350cf89bdf53c25299ae2d7bb
docs/operations/getanalyticsmetadata.mdx:
id: 7c66572b759d
last_write_checksum: sha1:8ff4758a1a3b63116d55a83821dcb0c8012050f5
@@ -6286,8 +6286,8 @@ trackedFiles:
pristine_git_object: f31e13179ad9060fbebe2fc50ac6d6ca6d5b013a
docs/operations/getuseractivityrequest.mdx:
id: 61b93f5b1403
- last_write_checksum: sha1:684d952b0cad7763ea8c1261ab5b928a3b77bcbc
- pristine_git_object: 6ff32ecb22719b7da65ec863fea77dc94bd30e53
+ last_write_checksum: sha1:bc9beca10caef657dc3d9f1cedd21375ff501cd5
+ pristine_git_object: 421ac1a9f72b5ab4e47bb6d96ad7ad6c942a3654
docs/operations/getvideosglobals.mdx:
id: 54e17c2b195c
last_write_checksum: sha1:e9c91baed62379fa5fa3c78e1047f2a99435157b
@@ -6312,6 +6312,10 @@ trackedFiles:
id: 94405df5bc6d
last_write_checksum: sha1:8411fa2c4566737be150bf3d64bb792f0a3eb650
pristine_git_object: 9d6dfd531f49a6b16998c97e5749cf4ea761dd94
+ docs/operations/groupby.mdx:
+ id: 5c9addfe5341
+ last_write_checksum: sha1:f07eaef53c2338de9c74f947eb8e98875d7dfdd9
+ pristine_git_object: 951d54c9802057d82efc39fa03c90eaf54381eff
docs/operations/headquarters.mdx:
id: 8b6a6ec3c5a7
last_write_checksum: sha1:0dc87fcfec205555e2a9530358f304a3bb9d56d6
@@ -6902,8 +6906,8 @@ trackedFiles:
pristine_git_object: 8541eefab0e7110d9a895d66bebd1779e456a264
docs/operations/value1.mdx:
id: 447e93c2bc33
- last_write_checksum: sha1:b2c81e4b7897f8beaaed9e3891f2a77d57ef1734
- pristine_git_object: 4d269a48eefb02feb81b720b2b21cc298b1d52e8
+ last_write_checksum: sha1:7bd609444ab271023bd5496797ec18383fd2670d
+ pristine_git_object: 329fc8cb9f8922893a29848212bc2a41c31d2835
docs/operations/value2.mdx:
id: ebf32fddf22e
last_write_checksum: sha1:18f440dbfdcb2498771fe53a98b054d4d76f283c
@@ -6926,8 +6930,8 @@ trackedFiles:
pristine_git_object: f265978fdb338b412232349476bf1e874833c9f8
docs/sdks/analytics/README.mdx:
id: 281aa5320be1
- last_write_checksum: sha1:04cc5064d83eda6623841e7052f0fe7de81c833f
- pristine_git_object: 4e5df61630ce21da071bcc35a50a8cca491d6e4f
+ last_write_checksum: sha1:1a3d4c929ad50c2b7f24ced91d0646e6cc9f7d1b
+ pristine_git_object: 18befad2161aca4ee4359420ba14b7affccf7ec9
docs/sdks/apikeys/README.mdx:
id: 27fcaae1c346
last_write_checksum: sha1:b8bd517a7a2960d003ab350130008b402927af6b
@@ -7046,8 +7050,8 @@ trackedFiles:
pristine_git_object: 3e38f1a929f7d6b1d6de74604aa87e3d8f010544
pyproject.toml:
id: 5d07e7d72637
- last_write_checksum: sha1:a8356d256eff93b06f8098df8f72d95c5b7760c4
- pristine_git_object: 726b8caee9917506c0d06dca2de7c22d6f1bda15
+ last_write_checksum: sha1:4f2590600cc9a8f80b0fa62834a250aa36b907a0
+ pristine_git_object: 090b4a16399984f227e292bde258f744a02dc2b7
scripts/prepare_readme.py:
id: e0c5957a6035
last_write_checksum: sha1:77f44b60b98bc126557ec27391f91dfba764bb54
@@ -7074,12 +7078,12 @@ trackedFiles:
pristine_git_object: 86713cfea633e09d33b3d4e65281071fe20e6137
src/openrouter/_version.py:
id: d8d15ad6c586
- last_write_checksum: sha1:00885d78769daff0fb6b4c2c3475bf1ce97011cc
- pristine_git_object: abd485793c13776fe0d799bd8141faa6665ea002
+ last_write_checksum: sha1:04e2257c5d2f97a4d092aa900404c9d28b544c02
+ pristine_git_object: cc1824637bb68d360a6a6cdc1ee0ba171d91c417
src/openrouter/analytics.py:
id: cb406b5aaabb
- last_write_checksum: sha1:9e709b71dd0611056dc0cec6150b578defe32841
- pristine_git_object: ddb44a129e8f45e7524fe5615a23f1ccc70bbe71
+ last_write_checksum: sha1:3ea0f1c73fb9c101b7bc5719da4dd7bf62ff469a
+ pristine_git_object: ddd0b3f6c78a94ed829bb1c6dbf30bbacce7e517
src/openrouter/api_keys.py:
id: 876fac88fff6
last_write_checksum: sha1:ada03aff96976f0570e594a3143595c25ca05f18
@@ -7126,8 +7130,8 @@ trackedFiles:
pristine_git_object: ad39bd9765938465f06b5422706fc867db11e468
src/openrouter/components/activityitem.py:
id: 3bbe7d35f459
- last_write_checksum: sha1:478bb399829efe851d28bf5124f35cd7ca522665
- pristine_git_object: a234e6ddf7aec8c7c3d6bd5e4118015c8fbff274
+ last_write_checksum: sha1:96430ac2c3aab411c5a05f50ee31ad25eea0790f
+ pristine_git_object: 3fecf83b2b307a1a9ef7714d5111ab724abba6a6
src/openrouter/components/activityresponse.py:
id: 0bd8d79c3144
last_write_checksum: sha1:db8e3247cf9eb2c235d32949d36f7ae95870e8ed
@@ -8050,8 +8054,8 @@ trackedFiles:
pristine_git_object: b762f6507fe7c7456df88a9400f82587fd6d63c9
src/openrouter/components/generationresponse.py:
id: 84d4e3e7da8b
- last_write_checksum: sha1:240706a3d8336a4a8e7ebcd815c22949143a245b
- pristine_git_object: 72098fb9ec3dfaca7ad00356a202ab107a96c713
+ last_write_checksum: sha1:b26bce951ba1ce6ffb0779809e4410b03d9b9e6a
+ pristine_git_object: 87454d8cc8cc00e853eb13331c496af8f7d0d0d6
src/openrouter/components/getbyokkeyresponse.py:
id: ca3a8db80018
last_write_checksum: sha1:9b428028a01ffb73915a278096ca51bd1c660326
@@ -9614,8 +9618,8 @@ trackedFiles:
pristine_git_object: 0f62389a8410522fe76eed82c64227903a8605c5
src/openrouter/operations/__init__.py:
id: 9afcea1e7161
- last_write_checksum: sha1:79b687677ed95380c7548ec6ed3e3efa0a32f386
- pristine_git_object: 71aa5c14ab18f683fe648f8a08e8190d6dc894d2
+ last_write_checksum: sha1:10813e43c7af4d49a27bc034ae9c898a347a883c
+ pristine_git_object: 633049645a506d455ecef8e65b8a42edaf36bf42
src/openrouter/operations/bulkaddworkspacemembers.py:
id: e0ed56117619
last_write_checksum: sha1:5c44eb0d40fdece3ac084615f6c6082be4cf1d5a
@@ -9826,8 +9830,8 @@ trackedFiles:
pristine_git_object: a8b610cad3ca3792798e40b31cada48b0ed3845b
src/openrouter/operations/getuseractivity.py:
id: 560a0e01c2c3
- last_write_checksum: sha1:91bbb6f67fd71874baf0c61b8004bfab589385f1
- pristine_git_object: 35ab9ca4d75b4e37483cd379f73afdbaf0b60d3c
+ last_write_checksum: sha1:5de9ab321a939fe40adb6626721fd327890f2850
+ pristine_git_object: e635bfa9d44f1fd9a99a0d86f2752aea6eee4905
src/openrouter/operations/getvideos.py:
id: a5f626467a69
last_write_checksum: sha1:007242bbdda9cb2f7d02fb6a04c5aa000d317a07
@@ -9950,8 +9954,8 @@ trackedFiles:
pristine_git_object: cbdad12f956c5f2a8252b7f6db102f1e83c4e85a
src/openrouter/operations/queryanalytics.py:
id: d76c63ff66f6
- last_write_checksum: sha1:cbaf0ab2bfe18d46e977dc833f6f5ed18a1d8b33
- pristine_git_object: bde10deb1159106ce8fbb977898e38baa414e9a6
+ last_write_checksum: sha1:97c08d2f87fce08adacd1cdccfbd72c34962b03f
+ pristine_git_object: a7e1247756af1bcf04e8ade0ac96744c9c2535c1
src/openrouter/operations/sendchatcompletionrequest.py:
id: d9fee71bb577
last_write_checksum: sha1:0cba4011b8e305270ac30f88cb7ab59b6aefe619
@@ -10306,7 +10310,7 @@ examples:
id: "gen-1234567890"
responses:
"200":
- application/json: {"data": {"api_type": "completions", "app_id": 12345, "cache_discount": null, "cancelled": false, "created_at": "2024-07-15T23:33:19.433273+00:00", "data_region": "global", "external_user": "user-123", "finish_reason": "stop", "generation_time": 1200, "http_referer": "https://openrouter.ai/", "id": "gen-3bhGkxlo4XFrqiabUM7NDtwDzWwG", "is_byok": false, "latency": 1250, "model": "sao10k/l3-stheno-8b", "moderation_latency": 50, "native_finish_reason": "stop", "native_tokens_cached": 3, "native_tokens_completion": 25, "native_tokens_completion_images": 0, "native_tokens_prompt": 10, "native_tokens_reasoning": 5, "num_fetches": 0, "num_input_audio_prompt": 0, "num_media_completion": 0, "num_media_prompt": 1, "num_search_results": 5, "origin": "https://openrouter.ai/", "preset_id": "a9e8d400-592a-494f-908c-375efa66cafd", "provider_name": "Infermatic", "provider_responses": null, "router": "openrouter/auto", "service_tier": "priority", "streamed": true, "tokens_completion": 25, "tokens_prompt": 10, "total_cost": 0.0015, "upstream_id": "chatcmpl-791bcf62-080e-4568-87d0-94c72e3b4946", "upstream_inference_cost": 0.0012, "usage": 0.0015, "user_agent": "Mozilla/5.0", "web_search_engine": "exa"}}
+ application/json: {"data": {"api_type": "completions", "app_id": 12345, "cache_discount": null, "cancelled": false, "created_at": "2024-07-15T23:33:19.433273+00:00", "data_region": "global", "external_user": "user-123", "finish_reason": "stop", "generation_time": 1200, "http_referer": "https://openrouter.ai/", "id": "gen-3bhGkxlo4XFrqiabUM7NDtwDzWwG", "is_byok": false, "latency": 1250, "model": "sao10k/l3-stheno-8b", "moderation_latency": 50, "native_finish_reason": "stop", "native_tokens_cached": 3, "native_tokens_completion": 25, "native_tokens_completion_images": 0, "native_tokens_prompt": 10, "native_tokens_reasoning": 5, "num_fetches": 0, "num_input_audio_prompt": 0, "num_media_completion": 0, "num_media_prompt": 1, "num_search_results": 5, "origin": "https://openrouter.ai/", "preset_id": "a9e8d400-592a-494f-908c-375efa66cafd", "provider_name": "Infermatic", "provider_responses": null, "router": "openrouter/auto", "service_tier": "priority", "streamed": true, "tokens_completion": 25, "tokens_prompt": 10, "total_cost": 0.0015, "upstream_id": "chatcmpl-791bcf62-080e-4568-87d0-94c72e3b4946", "upstream_inference_cost": 0.0012, "usage": 0.0015, "user_agent": "Mozilla/5.0", "web_search_engine": "exa", "workspace_id": "550e8400-e29b-41d4-a716-446655440000"}}
"401":
application/json: {"error": {"code": 401, "message": "Missing Authentication header"}}
"402":
@@ -11822,3 +11826,4 @@ examples:
"500":
application/json: {"error": {"code": 500, "message": "Internal Server Error"}}
examplesVersion: 1.0.2
+releaseNotes: "## Python SDK Changes:\n* `open_router.analytics.get_user_activity()`: \n * `request` **Changed** (Breaking ⚠️)\n * `response.data[].workspace_id` **Added**\n* `open_router.generations.get_generation()`: `response.data.workspace_id` **Added**\n"
diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml
index 4f4ae853..b13bfdd6 100644
--- a/.speakeasy/gen.yaml
+++ b/.speakeasy/gen.yaml
@@ -36,7 +36,7 @@ generation:
documentation: mintlify
preApplyUnionDiscriminators: true
python:
- version: 1.1.24
+ version: 1.1.25
additionalDependencies:
dev: {}
main: {}
diff --git a/.speakeasy/out.openapi.yaml b/.speakeasy/out.openapi.yaml
index a6072722..47abf017 100644
--- a/.speakeasy/out.openapi.yaml
+++ b/.speakeasy/out.openapi.yaml
@@ -116,6 +116,10 @@ components:
example: 0.015
format: 'double'
type: 'number'
+ workspace_id:
+ description: 'ID of the workspace this activity is attributed to. Only present when `group_by=workspace` is passed; the response is then split per workspace. Activity recorded before workspace resolution existed is attributed to the account default workspace.'
+ example: '550e8400-e29b-41d4-a716-446655440000'
+ type: 'string'
required:
- 'date'
- 'model'
@@ -9161,6 +9165,7 @@ components:
usage: 0.0015
user_agent: 'Mozilla/5.0'
web_search_engine: 'exa'
+ workspace_id: '550e8400-e29b-41d4-a716-446655440000'
properties:
data:
description: 'Generation data'
@@ -9431,6 +9436,12 @@ components:
type:
- 'string'
- 'null'
+ workspace_id:
+ description: 'ID of the workspace this generation is attributed to. Null for accounts without workspaces. Generations created before workspace resolution existed are attributed to the account default workspace.'
+ example: '550e8400-e29b-41d4-a716-446655440000'
+ type:
+ - 'string'
+ - 'null'
required:
- 'id'
- 'upstream_id'
@@ -9473,6 +9484,7 @@ components:
- 'user_agent'
- 'http_referer'
- 'data_region'
+ - 'workspace_id'
type: 'object'
required:
- 'data'
@@ -25300,7 +25312,7 @@ openapi: '3.1.0'
paths:
/activity:
get:
- description: 'Returns user activity data grouped by endpoint for the last 30 (completed) UTC days. [Management key](/docs/guides/overview/auth/management-api-keys) required.'
+ description: 'Returns user activity data grouped by endpoint for the last 30 (completed) UTC days. Pass `workspace_id` to scope the response to a single workspace. Pass `group_by=workspace` to split each row per workspace and include `workspace_id` on every item; by default rows are aggregated across workspaces and `workspace_id` is not returned. Activity recorded before workspace resolution existed is permanently attributed to the account default workspace (no backfill is possible). [Management key](/docs/guides/overview/auth/management-api-keys) required.'
operationId: 'getUserActivity'
parameters:
- description: 'Filter by a single UTC date in the last 30 days (YYYY-MM-DD format).'
@@ -25327,6 +25339,24 @@ paths:
description: 'Filter by org member user ID. Only applicable for organization accounts.'
example: 'user_abc123'
type: 'string'
+ - description: 'Set to ''workspace'' to split each row per workspace and include `workspace_id` on every item. Omitted by default, in which case rows are aggregated across workspaces (by date, model, and endpoint) and `workspace_id` is not returned — preserving the historical response shape.'
+ in: 'query'
+ name: 'group_by'
+ required: false
+ schema:
+ description: 'Set to ''workspace'' to split each row per workspace and include `workspace_id` on every item. Omitted by default, in which case rows are aggregated across workspaces (by date, model, and endpoint) and `workspace_id` is not returned — preserving the historical response shape.'
+ enum:
+ - 'workspace'
+ example: 'workspace'
+ type: 'string'
+ - description: 'Filter by workspace ID (UUID). Returns only activity attributed to that workspace. The workspace must belong to the authenticated account.'
+ in: 'query'
+ name: 'workspace_id'
+ required: false
+ schema:
+ description: 'Filter by workspace ID (UUID). Returns only activity attributed to that workspace. The workspace must belong to the authenticated account.'
+ example: '550e8400-e29b-41d4-a716-446655440000'
+ type: 'string'
responses:
'200':
content:
@@ -25400,6 +25430,7 @@ paths:
summary: 'Get user activity grouped by endpoint'
tags:
- 'Analytics'
+ x-speakeasy-max-method-params: 5
parameters:
- $ref: "#/components/parameters/AppIdentifier"
- $ref: "#/components/parameters/AppDisplayName"
@@ -25692,7 +25723,7 @@ paths:
- format: 'double'
type: 'number'
type: 'array'
- description: 'Filter value (scalar or array depending on operator). Several dimensions are enriched in responses (returned as human-readable labels), but filters must use the underlying ID: `api_key_id` — numeric ID (from generation metadata) or key hash (64-char hex from GET /api/v1/keys, resolved server-side); `user` — Clerk user ID (e.g. "user_abc123"), not the display name; `workspace` — workspace UUID, not the workspace name; `app` — numeric app ID, not the app title; `model` — permaslug (e.g. "openai/gpt-4o"), not the display name. Other dimensions (provider, origin, country, etc.) are not enriched and accept the value as returned.'
+ description: 'Filter value (scalar or array depending on operator). Several dimensions are enriched in responses (returned as human-readable labels), but filters must use the underlying ID: `api_key_id` — numeric ID (from generation metadata) or key hash (64-char hex from GET /api/v1/keys, resolved server-side); `user` — Clerk user ID (e.g. "user_abc123"), not the display name; `workspace` — workspace UUID, not the workspace name (filtering or grouping by the account default workspace also covers activity recorded before workspace resolution existed, which is attributed to that default workspace); `app` — numeric app ID, not the app title; `model` — permaslug (e.g. "openai/gpt-4o"), not the display name. Other dimensions (provider, origin, country, etc.) are not enriched and accept the value as returned.'
required:
- 'field'
- 'operator'
diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock
index db709f48..7195ca88 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:6145bc8c07f796b5b6600bc2d72e4add45345bba90ac06bc65d657393d9d3404
- sourceBlobDigest: sha256:b1047454bde05da0913b1ee9d40f84e0075bc4fc529f6b86d6e0376a47ab8c46
+ sourceRevisionDigest: sha256:fb1692459fe3dbf57ff0aa5d947b2a9369ccd13d432dcc8aff822d6ceaf4f352
+ sourceBlobDigest: sha256:b138f591b453eb0d8a5a2c8ca608c238300ed1b16a5dcc63201f0fae746b176a
tags:
- latest
- 1.0.0
@@ -11,10 +11,10 @@ targets:
open-router:
source: OpenRouter API
sourceNamespace: open-router-chat-completions-api
- sourceRevisionDigest: sha256:6145bc8c07f796b5b6600bc2d72e4add45345bba90ac06bc65d657393d9d3404
- sourceBlobDigest: sha256:b1047454bde05da0913b1ee9d40f84e0075bc4fc529f6b86d6e0376a47ab8c46
+ sourceRevisionDigest: sha256:fb1692459fe3dbf57ff0aa5d947b2a9369ccd13d432dcc8aff822d6ceaf4f352
+ sourceBlobDigest: sha256:b138f591b453eb0d8a5a2c8ca608c238300ed1b16a5dcc63201f0fae746b176a
codeSamplesNamespace: open-router-python-code-samples
- codeSamplesRevisionDigest: sha256:4f8ac677bf8ba355ba6cef7a3edf6d0a007497cca141b2a359fab6be5455e780
+ codeSamplesRevisionDigest: sha256:2ad5652c559035e213150f8d4694ab051faabc4ee3e5a6e986c43fb16599e547
workflow:
workflowVersion: 1.0.0
speakeasyVersion: 1.787.0
diff --git a/RELEASES.md b/RELEASES.md
index a632c380..e5951a3a 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1029,4 +1029,14 @@ Based on:
### Generated
- [python v1.1.24] .
### Releases
-- [PyPI v1.1.24] https://pypi.org/project/openrouter/1.1.24 - .
\ No newline at end of file
+- [PyPI v1.1.24] https://pypi.org/project/openrouter/1.1.24 - .
+
+## 2026-08-03 12:43:58
+### Changes
+Based on:
+- OpenAPI Doc
+- Speakeasy CLI 1.787.0 (2.914.0) https://github.com/speakeasy-api/speakeasy
+### Generated
+- [python v1.1.25] .
+### Releases
+- [PyPI v1.1.25] https://pypi.org/project/openrouter/1.1.25 - .
\ No newline at end of file
diff --git a/docs/components/activityitem.mdx b/docs/components/activityitem.mdx
index 0910645c..595c3f1b 100644
--- a/docs/components/activityitem.mdx
+++ b/docs/components/activityitem.mdx
@@ -4,16 +4,17 @@ title: "ActivityItem"
## Fields
-| Field | Type | Required | Description | Example |
-| --------------------------------------------------- | --------------------------------------------------- | --------------------------------------------------- | --------------------------------------------------- | --------------------------------------------------- |
-| `byok_usage_inference` | *float* | :heavy_check_mark: | BYOK inference cost in USD (external credits spent) | 0.012 |
-| `completion_tokens` | *int* | :heavy_check_mark: | Total completion tokens generated | 125 |
-| `date_` | *str* | :heavy_check_mark: | Date of the activity (YYYY-MM-DD format) | 2025-08-24 |
-| `endpoint_id` | *str* | :heavy_check_mark: | Unique identifier for the endpoint | 550e8400-e29b-41d4-a716-446655440000 |
-| `model` | *str* | :heavy_check_mark: | Model slug (e.g., "openai/gpt-4.1") | openai/gpt-4.1 |
-| `model_permaslug` | *str* | :heavy_check_mark: | Model permaslug (e.g., "openai/gpt-4.1-2025-04-14") | openai/gpt-4.1-2025-04-14 |
-| `prompt_tokens` | *int* | :heavy_check_mark: | Total prompt tokens used | 50 |
-| `provider_name` | *str* | :heavy_check_mark: | Name of the provider serving this endpoint | OpenAI |
-| `reasoning_tokens` | *int* | :heavy_check_mark: | Total reasoning tokens used | 25 |
-| `requests` | *int* | :heavy_check_mark: | Number of requests made | 5 |
-| `usage` | *float* | :heavy_check_mark: | Total cost in USD (OpenRouter credits spent) | 0.015 |
\ No newline at end of file
+| Field | Type | Required | Description | Example |
+| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `byok_usage_inference` | *float* | :heavy_check_mark: | BYOK inference cost in USD (external credits spent) | 0.012 |
+| `completion_tokens` | *int* | :heavy_check_mark: | Total completion tokens generated | 125 |
+| `date_` | *str* | :heavy_check_mark: | Date of the activity (YYYY-MM-DD format) | 2025-08-24 |
+| `endpoint_id` | *str* | :heavy_check_mark: | Unique identifier for the endpoint | 550e8400-e29b-41d4-a716-446655440000 |
+| `model` | *str* | :heavy_check_mark: | Model slug (e.g., "openai/gpt-4.1") | openai/gpt-4.1 |
+| `model_permaslug` | *str* | :heavy_check_mark: | Model permaslug (e.g., "openai/gpt-4.1-2025-04-14") | openai/gpt-4.1-2025-04-14 |
+| `prompt_tokens` | *int* | :heavy_check_mark: | Total prompt tokens used | 50 |
+| `provider_name` | *str* | :heavy_check_mark: | Name of the provider serving this endpoint | OpenAI |
+| `reasoning_tokens` | *int* | :heavy_check_mark: | Total reasoning tokens used | 25 |
+| `requests` | *int* | :heavy_check_mark: | Number of requests made | 5 |
+| `usage` | *float* | :heavy_check_mark: | Total cost in USD (OpenRouter credits spent) | 0.015 |
+| `workspace_id` | *Optional[str]* | :heavy_minus_sign: | ID of the workspace this activity is attributed to. Only present when `group_by=workspace` is passed; the response is then split per workspace. Activity recorded before workspace resolution existed is attributed to the account default workspace. | 550e8400-e29b-41d4-a716-446655440000 |
\ No newline at end of file
diff --git a/docs/components/generationresponsedata.mdx b/docs/components/generationresponsedata.mdx
index 54187e67..d8beea52 100644
--- a/docs/components/generationresponsedata.mdx
+++ b/docs/components/generationresponsedata.mdx
@@ -7,49 +7,50 @@ Generation data
## Fields
-| Field | Type | Required | Description | Example |
-| ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
-| `api_type` | [Nullable[components.APIType]](../components/apitype.mdx) | :heavy_check_mark: | Type of API used for the generation | |
-| `app_id` | *Nullable[int]* | :heavy_check_mark: | ID of the app that made the request | 12345 |
-| `cache_discount` | *Nullable[float]* | :heavy_check_mark: | Discount applied due to caching | 0.0002 |
-| `cancelled` | *Nullable[bool]* | :heavy_check_mark: | Whether the generation was cancelled | false |
-| `created_at` | *str* | :heavy_check_mark: | ISO 8601 timestamp of when the generation was created | 2024-07-15T23:33:19.433273+00:00 |
-| `data_region` | [components.DataRegion](../components/dataregion.mdx) | :heavy_check_mark: | The data region this generation was routed through: 'global', 'europe', or 'us'. | global |
-| `external_user` | *Nullable[str]* | :heavy_check_mark: | External user identifier | user-123 |
-| `finish_reason` | *Nullable[str]* | :heavy_check_mark: | Reason the generation finished | stop |
-| `generation_time` | *Nullable[float]* | :heavy_check_mark: | Time taken for generation in milliseconds | 1200 |
-| `http_referer` | *Nullable[str]* | :heavy_check_mark: | Referer header from the request | |
-| `id` | *str* | :heavy_check_mark: | Unique identifier for the generation | gen-3bhGkxlo4XFrqiabUM7NDtwDzWwG |
-| `is_byok` | *bool* | :heavy_check_mark: | Whether this used bring-your-own-key | false |
-| `latency` | *Nullable[float]* | :heavy_check_mark: | Total latency in milliseconds | 1250 |
-| `model` | *str* | :heavy_check_mark: | Model used for the generation | sao10k/l3-stheno-8b |
-| `moderation_latency` | *Nullable[float]* | :heavy_check_mark: | Moderation latency in milliseconds | 50 |
-| `native_finish_reason` | *Nullable[str]* | :heavy_check_mark: | Native finish reason as reported by provider | stop |
-| `native_tokens_cached` | *Nullable[int]* | :heavy_check_mark: | Native cached tokens as reported by provider | 3 |
-| `native_tokens_completion` | *Nullable[int]* | :heavy_check_mark: | Native completion tokens as reported by provider | 25 |
-| `native_tokens_completion_images` | *Nullable[int]* | :heavy_check_mark: | Native completion image tokens as reported by provider | 0 |
-| `native_tokens_prompt` | *Nullable[int]* | :heavy_check_mark: | Native prompt tokens as reported by provider | 10 |
-| `native_tokens_reasoning` | *Nullable[int]* | :heavy_check_mark: | Native reasoning tokens as reported by provider | 5 |
-| `num_fetches` | *Nullable[int]* | :heavy_check_mark: | Number of web fetches performed | 0 |
-| `num_input_audio_prompt` | *Nullable[int]* | :heavy_check_mark: | Number of audio inputs in the prompt | 0 |
-| `num_media_completion` | *Nullable[int]* | :heavy_check_mark: | Number of media items in the completion | 0 |
-| `num_media_prompt` | *Nullable[int]* | :heavy_check_mark: | Number of media items in the prompt | 1 |
-| `num_search_results` | *Nullable[int]* | :heavy_check_mark: | Number of search results included | 5 |
-| `origin` | *str* | :heavy_check_mark: | Origin URL of the request | https://openrouter.ai/ |
-| `preset_id` | *Nullable[str]* | :heavy_check_mark: | ID of the preset used for this generation, null if no preset was used | a9e8d400-592a-494f-908c-375efa66cafd |
-| `provider_name` | *Nullable[str]* | :heavy_check_mark: | Name of the provider that served the request | Infermatic |
-| `provider_responses` | List[[components.ProviderResponse](../components/providerresponse.mdx)] | :heavy_check_mark: | List of provider responses for this generation, including fallback attempts | |
-| `request_id` | *OptionalNullable[str]* | :heavy_minus_sign: | Unique identifier grouping all generations from a single API request | req-1727282430-aBcDeFgHiJkLmNoPqRsT |
-| `response_cache_source_id` | *OptionalNullable[str]* | :heavy_minus_sign: | If this generation was served from response cache, contains the original generation ID. Null otherwise. | |
-| `router` | *Nullable[str]* | :heavy_check_mark: | Router used for the request (e.g., openrouter/auto) | openrouter/auto |
-| `service_tier` | *Nullable[str]* | :heavy_check_mark: | Service tier the upstream provider reported running this request on, or null if it did not report one. | priority |
-| `session_id` | *OptionalNullable[str]* | :heavy_minus_sign: | Session identifier grouping multiple generations in the same session | |
-| `streamed` | *Nullable[bool]* | :heavy_check_mark: | Whether the response was streamed | true |
-| `tokens_completion` | *Nullable[int]* | :heavy_check_mark: | Number of tokens in the completion | 25 |
-| `tokens_prompt` | *Nullable[int]* | :heavy_check_mark: | Number of tokens in the prompt | 10 |
-| `total_cost` | *float* | :heavy_check_mark: | Total cost of the generation in USD | 0.0015 |
-| `upstream_id` | *Nullable[str]* | :heavy_check_mark: | Upstream provider's identifier for this generation | chatcmpl-791bcf62-080e-4568-87d0-94c72e3b4946 |
-| `upstream_inference_cost` | *Nullable[float]* | :heavy_check_mark: | Cost charged by the upstream provider | 0.0012 |
-| `usage` | *float* | :heavy_check_mark: | Usage amount in USD | 0.0015 |
-| `user_agent` | *Nullable[str]* | :heavy_check_mark: | User-Agent header from the request | |
-| `web_search_engine` | *Nullable[str]* | :heavy_check_mark: | The resolved web search engine used for this generation (e.g. exa, firecrawl, parallel) | exa |
\ No newline at end of file
+| Field | Type | Required | Description | Example |
+| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `api_type` | [Nullable[components.APIType]](../components/apitype.mdx) | :heavy_check_mark: | Type of API used for the generation | |
+| `app_id` | *Nullable[int]* | :heavy_check_mark: | ID of the app that made the request | 12345 |
+| `cache_discount` | *Nullable[float]* | :heavy_check_mark: | Discount applied due to caching | 0.0002 |
+| `cancelled` | *Nullable[bool]* | :heavy_check_mark: | Whether the generation was cancelled | false |
+| `created_at` | *str* | :heavy_check_mark: | ISO 8601 timestamp of when the generation was created | 2024-07-15T23:33:19.433273+00:00 |
+| `data_region` | [components.DataRegion](../components/dataregion.mdx) | :heavy_check_mark: | The data region this generation was routed through: 'global', 'europe', or 'us'. | global |
+| `external_user` | *Nullable[str]* | :heavy_check_mark: | External user identifier | user-123 |
+| `finish_reason` | *Nullable[str]* | :heavy_check_mark: | Reason the generation finished | stop |
+| `generation_time` | *Nullable[float]* | :heavy_check_mark: | Time taken for generation in milliseconds | 1200 |
+| `http_referer` | *Nullable[str]* | :heavy_check_mark: | Referer header from the request | |
+| `id` | *str* | :heavy_check_mark: | Unique identifier for the generation | gen-3bhGkxlo4XFrqiabUM7NDtwDzWwG |
+| `is_byok` | *bool* | :heavy_check_mark: | Whether this used bring-your-own-key | false |
+| `latency` | *Nullable[float]* | :heavy_check_mark: | Total latency in milliseconds | 1250 |
+| `model` | *str* | :heavy_check_mark: | Model used for the generation | sao10k/l3-stheno-8b |
+| `moderation_latency` | *Nullable[float]* | :heavy_check_mark: | Moderation latency in milliseconds | 50 |
+| `native_finish_reason` | *Nullable[str]* | :heavy_check_mark: | Native finish reason as reported by provider | stop |
+| `native_tokens_cached` | *Nullable[int]* | :heavy_check_mark: | Native cached tokens as reported by provider | 3 |
+| `native_tokens_completion` | *Nullable[int]* | :heavy_check_mark: | Native completion tokens as reported by provider | 25 |
+| `native_tokens_completion_images` | *Nullable[int]* | :heavy_check_mark: | Native completion image tokens as reported by provider | 0 |
+| `native_tokens_prompt` | *Nullable[int]* | :heavy_check_mark: | Native prompt tokens as reported by provider | 10 |
+| `native_tokens_reasoning` | *Nullable[int]* | :heavy_check_mark: | Native reasoning tokens as reported by provider | 5 |
+| `num_fetches` | *Nullable[int]* | :heavy_check_mark: | Number of web fetches performed | 0 |
+| `num_input_audio_prompt` | *Nullable[int]* | :heavy_check_mark: | Number of audio inputs in the prompt | 0 |
+| `num_media_completion` | *Nullable[int]* | :heavy_check_mark: | Number of media items in the completion | 0 |
+| `num_media_prompt` | *Nullable[int]* | :heavy_check_mark: | Number of media items in the prompt | 1 |
+| `num_search_results` | *Nullable[int]* | :heavy_check_mark: | Number of search results included | 5 |
+| `origin` | *str* | :heavy_check_mark: | Origin URL of the request | https://openrouter.ai/ |
+| `preset_id` | *Nullable[str]* | :heavy_check_mark: | ID of the preset used for this generation, null if no preset was used | a9e8d400-592a-494f-908c-375efa66cafd |
+| `provider_name` | *Nullable[str]* | :heavy_check_mark: | Name of the provider that served the request | Infermatic |
+| `provider_responses` | List[[components.ProviderResponse](../components/providerresponse.mdx)] | :heavy_check_mark: | List of provider responses for this generation, including fallback attempts | |
+| `request_id` | *OptionalNullable[str]* | :heavy_minus_sign: | Unique identifier grouping all generations from a single API request | req-1727282430-aBcDeFgHiJkLmNoPqRsT |
+| `response_cache_source_id` | *OptionalNullable[str]* | :heavy_minus_sign: | If this generation was served from response cache, contains the original generation ID. Null otherwise. | |
+| `router` | *Nullable[str]* | :heavy_check_mark: | Router used for the request (e.g., openrouter/auto) | openrouter/auto |
+| `service_tier` | *Nullable[str]* | :heavy_check_mark: | Service tier the upstream provider reported running this request on, or null if it did not report one. | priority |
+| `session_id` | *OptionalNullable[str]* | :heavy_minus_sign: | Session identifier grouping multiple generations in the same session | |
+| `streamed` | *Nullable[bool]* | :heavy_check_mark: | Whether the response was streamed | true |
+| `tokens_completion` | *Nullable[int]* | :heavy_check_mark: | Number of tokens in the completion | 25 |
+| `tokens_prompt` | *Nullable[int]* | :heavy_check_mark: | Number of tokens in the prompt | 10 |
+| `total_cost` | *float* | :heavy_check_mark: | Total cost of the generation in USD | 0.0015 |
+| `upstream_id` | *Nullable[str]* | :heavy_check_mark: | Upstream provider's identifier for this generation | chatcmpl-791bcf62-080e-4568-87d0-94c72e3b4946 |
+| `upstream_inference_cost` | *Nullable[float]* | :heavy_check_mark: | Cost charged by the upstream provider | 0.0012 |
+| `usage` | *float* | :heavy_check_mark: | Usage amount in USD | 0.0015 |
+| `user_agent` | *Nullable[str]* | :heavy_check_mark: | User-Agent header from the request | |
+| `web_search_engine` | *Nullable[str]* | :heavy_check_mark: | The resolved web search engine used for this generation (e.g. exa, firecrawl, parallel) | exa |
+| `workspace_id` | *Nullable[str]* | :heavy_check_mark: | ID of the workspace this generation is attributed to. Null for accounts without workspaces. Generations created before workspace resolution existed are attributed to the account default workspace. | 550e8400-e29b-41d4-a716-446655440000 |
\ No newline at end of file
diff --git a/docs/operations/filter_.mdx b/docs/operations/filter_.mdx
index 3dbded7e..3397e42a 100644
--- a/docs/operations/filter_.mdx
+++ b/docs/operations/filter_.mdx
@@ -4,8 +4,8 @@ title: "Filter"
## Fields
-| Field | Type | Required | Description | Example |
-| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `field` | *str* | :heavy_check_mark: | Dimension to filter on. Use the /meta endpoint for available dimensions. | model |
-| `operator` | *str* | :heavy_check_mark: | Filter operator | eq |
-| `value` | [operations.Value1](../operations/value1.mdx) | :heavy_check_mark: | Filter value (scalar or array depending on operator). Several dimensions are enriched in responses (returned as human-readable labels), but filters must use the underlying ID: `api_key_id` — numeric ID (from generation metadata) or key hash (64-char hex from GET /api/v1/keys, resolved server-side); `user` — Clerk user ID (e.g. "user_abc123"), not the display name; `workspace` — workspace UUID, not the workspace name; `app` — numeric app ID, not the app title; `model` — permaslug (e.g. "openai/gpt-4o"), not the display name. Other dimensions (provider, origin, country, etc.) are not enriched and accept the value as returned. | |
\ No newline at end of file
+| Field | Type | Required | Description | Example |
+| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `field` | *str* | :heavy_check_mark: | Dimension to filter on. Use the /meta endpoint for available dimensions. | model |
+| `operator` | *str* | :heavy_check_mark: | Filter operator | eq |
+| `value` | [operations.Value1](../operations/value1.mdx) | :heavy_check_mark: | Filter value (scalar or array depending on operator). Several dimensions are enriched in responses (returned as human-readable labels), but filters must use the underlying ID: `api_key_id` — numeric ID (from generation metadata) or key hash (64-char hex from GET /api/v1/keys, resolved server-side); `user` — Clerk user ID (e.g. "user_abc123"), not the display name; `workspace` — workspace UUID, not the workspace name (filtering or grouping by the account default workspace also covers activity recorded before workspace resolution existed, which is attributed to that default workspace); `app` — numeric app ID, not the app title; `model` — permaslug (e.g. "openai/gpt-4o"), not the display name. Other dimensions (provider, origin, country, etc.) are not enriched and accept the value as returned. | |
\ No newline at end of file
diff --git a/docs/operations/getuseractivityrequest.mdx b/docs/operations/getuseractivityrequest.mdx
index 6ff32ecb..421ac1a9 100644
--- a/docs/operations/getuseractivityrequest.mdx
+++ b/docs/operations/getuseractivityrequest.mdx
@@ -4,11 +4,13 @@ title: "GetUserActivityRequest"
## 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.
| |
-| `date_` | *Optional[str]* | :heavy_minus_sign: | Filter by a single UTC date in the last 30 days (YYYY-MM-DD format). | 2025-08-24 |
-| `api_key_hash` | *Optional[str]* | :heavy_minus_sign: | Filter by API key hash (SHA-256 hex string, as returned by the keys API). | abc123def456... |
-| `user_id` | *Optional[str]* | :heavy_minus_sign: | Filter by org member user ID. Only applicable for organization accounts. | user_abc123 |
\ No newline at end of file
+| 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.
| |
+| `date_` | *Optional[str]* | :heavy_minus_sign: | Filter by a single UTC date in the last 30 days (YYYY-MM-DD format). | 2025-08-24 |
+| `api_key_hash` | *Optional[str]* | :heavy_minus_sign: | Filter by API key hash (SHA-256 hex string, as returned by the keys API). | abc123def456... |
+| `user_id` | *Optional[str]* | :heavy_minus_sign: | Filter by org member user ID. Only applicable for organization accounts. | user_abc123 |
+| `group_by` | [Optional[operations.GroupBy]](../operations/groupby.mdx) | :heavy_minus_sign: | Set to 'workspace' to split each row per workspace and include `workspace_id` on every item. Omitted by default, in which case rows are aggregated across workspaces (by date, model, and endpoint) and `workspace_id` is not returned — preserving the historical response shape. | workspace |
+| `workspace_id` | *Optional[str]* | :heavy_minus_sign: | Filter by workspace ID (UUID). Returns only activity attributed to that workspace. The workspace must belong to the authenticated account. | 550e8400-e29b-41d4-a716-446655440000 |
\ No newline at end of file
diff --git a/docs/operations/groupby.mdx b/docs/operations/groupby.mdx
new file mode 100644
index 00000000..951d54c9
--- /dev/null
+++ b/docs/operations/groupby.mdx
@@ -0,0 +1,17 @@
+---
+title: "GroupBy"
+---
+
+Set to 'workspace' to split each row per workspace and include `workspace_id` on every item. Omitted by default, in which case rows are aggregated across workspaces (by date, model, and endpoint) and `workspace_id` is not returned — preserving the historical response shape.
+
+## Example Usage
+
+```python
+from openrouter.operations import GroupBy
+value: GroupBy = "workspace"
+```
+
+
+## Values
+
+- `"workspace"`
diff --git a/docs/operations/value1.mdx b/docs/operations/value1.mdx
index 4d269a48..329fc8cb 100644
--- a/docs/operations/value1.mdx
+++ b/docs/operations/value1.mdx
@@ -2,7 +2,7 @@
title: "Value1"
---
-Filter value (scalar or array depending on operator). Several dimensions are enriched in responses (returned as human-readable labels), but filters must use the underlying ID: `api_key_id` — numeric ID (from generation metadata) or key hash (64-char hex from GET /api/v1/keys, resolved server-side); `user` — Clerk user ID (e.g. "user_abc123"), not the display name; `workspace` — workspace UUID, not the workspace name; `app` — numeric app ID, not the app title; `model` — permaslug (e.g. "openai/gpt-4o"), not the display name. Other dimensions (provider, origin, country, etc.) are not enriched and accept the value as returned.
+Filter value (scalar or array depending on operator). Several dimensions are enriched in responses (returned as human-readable labels), but filters must use the underlying ID: `api_key_id` — numeric ID (from generation metadata) or key hash (64-char hex from GET /api/v1/keys, resolved server-side); `user` — Clerk user ID (e.g. "user_abc123"), not the display name; `workspace` — workspace UUID, not the workspace name (filtering or grouping by the account default workspace also covers activity recorded before workspace resolution existed, which is attributed to that default workspace); `app` — numeric app ID, not the app title; `model` — permaslug (e.g. "openai/gpt-4o"), not the display name. Other dimensions (provider, origin, country, etc.) are not enriched and accept the value as returned.
## Supported Types
diff --git a/docs/sdks/analytics/README.mdx b/docs/sdks/analytics/README.mdx
index 4e5df616..18befad2 100644
--- a/docs/sdks/analytics/README.mdx
+++ b/docs/sdks/analytics/README.mdx
@@ -13,7 +13,7 @@ Analytics and usage endpoints
## get_user_activity
-Returns user activity data grouped by endpoint for the last 30 (completed) UTC days. [Management key](/docs/guides/overview/auth/management-api-keys) required.
+Returns user activity data grouped by endpoint for the last 30 (completed) UTC days. Pass `workspace_id` to scope the response to a single workspace. Pass `group_by=workspace` to split each row per workspace and include `workspace_id` on every item; by default rows are aggregated across workspaces and `workspace_id` is not returned. Activity recorded before workspace resolution existed is permanently attributed to the account default workspace (no backfill is possible). [Management key](/docs/guides/overview/auth/management-api-keys) required.
### Example Usage
@@ -38,15 +38,10 @@ with OpenRouter(
### Parameters
-| Parameter | 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.
| |
-| `date_` | *Optional[str]* | :heavy_minus_sign: | Filter by a single UTC date in the last 30 days (YYYY-MM-DD format). | 2025-08-24 |
-| `api_key_hash` | *Optional[str]* | :heavy_minus_sign: | Filter by API key hash (SHA-256 hex string, as returned by the keys API). | abc123def456... |
-| `user_id` | *Optional[str]* | :heavy_minus_sign: | Filter by org member user ID. Only applicable for organization accounts. | user_abc123 |
-| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.mdx) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | |
+| Parameter | Type | Required | Description |
+| ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
+| `request` | [operations.GetUserActivityRequest](../../operations/getuseractivityrequest.mdx) | :heavy_check_mark: | The request object to use for the request. |
+| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.mdx) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. |
### Response
diff --git a/pyproject.toml b/pyproject.toml
index 726b8cae..090b4a16 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "openrouter"
-version = "1.1.24"
+version = "1.1.25"
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 abd48579..cc182463 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.24"
+__version__: str = "1.1.25"
__openapi_doc_version__: str = "1.0.0"
__gen_version__: str = "2.914.0"
-__user_agent__: str = "speakeasy-sdk/python 1.1.24 2.914.0 1.0.0 openrouter"
+__user_agent__: str = "speakeasy-sdk/python 1.1.25 2.914.0 1.0.0 openrouter"
try:
if __package__ is not None:
diff --git a/src/openrouter/analytics.py b/src/openrouter/analytics.py
index ddb44a12..ddd0b3f6 100644
--- a/src/openrouter/analytics.py
+++ b/src/openrouter/analytics.py
@@ -3,10 +3,10 @@
from .basesdk import BaseSDK
from openrouter import components, errors, operations, utils
from openrouter._hooks import HookContext
-from openrouter.types import OptionalNullable, UNSET
+from openrouter.types import BaseModel, OptionalNullable, UNSET
from openrouter.utils import get_security_from_env
from openrouter.utils.unmarshal_json_response import unmarshal_json_response
-from typing import Any, Mapping, Optional
+from typing import Any, Mapping, Optional, Union, cast
class Analytics(BaseSDK):
@@ -15,12 +15,10 @@ class Analytics(BaseSDK):
def get_user_activity(
self,
*,
- http_referer: Optional[str] = None,
- x_open_router_title: Optional[str] = None,
- x_open_router_categories: Optional[str] = None,
- date_: Optional[str] = None,
- api_key_hash: Optional[str] = None,
- user_id: Optional[str] = None,
+ request: Union[
+ operations.GetUserActivityRequest,
+ operations.GetUserActivityRequestTypedDict,
+ ] = operations.GetUserActivityRequest(),
retries: OptionalNullable[utils.RetryConfig] = UNSET,
server_url: Optional[str] = None,
timeout_ms: Optional[int] = None,
@@ -28,18 +26,9 @@ def get_user_activity(
) -> components.ActivityResponse:
r"""Get user activity grouped by endpoint
- Returns user activity data grouped by endpoint for the last 30 (completed) UTC days. [Management key](/docs/guides/overview/auth/management-api-keys) required.
+ Returns user activity data grouped by endpoint for the last 30 (completed) UTC days. Pass `workspace_id` to scope the response to a single workspace. Pass `group_by=workspace` to split each row per workspace and include `workspace_id` on every item; by default rows are aggregated across workspaces and `workspace_id` is not returned. Activity recorded before workspace resolution existed is permanently attributed to the account default workspace (no backfill is possible). [Management key](/docs/guides/overview/auth/management-api-keys) required.
- :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 date_: Filter by a single UTC date in the last 30 days (YYYY-MM-DD format).
- :param api_key_hash: Filter by API key hash (SHA-256 hex string, as returned by the keys API).
- :param user_id: Filter by org member user ID. Only applicable for organization accounts.
+ :param request: The request object to send.
: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
@@ -55,14 +44,9 @@ def get_user_activity(
else:
base_url = self._get_url(base_url, url_variables)
- request = operations.GetUserActivityRequest(
- http_referer=http_referer,
- x_open_router_title=x_open_router_title,
- x_open_router_categories=x_open_router_categories,
- date_=date_,
- api_key_hash=api_key_hash,
- user_id=user_id,
- )
+ if not isinstance(request, BaseModel):
+ request = utils.unmarshal(request, operations.GetUserActivityRequest)
+ request = cast(operations.GetUserActivityRequest, request)
req = self._build_request(
method="GET",
@@ -159,12 +143,10 @@ def get_user_activity(
async def get_user_activity_async(
self,
*,
- http_referer: Optional[str] = None,
- x_open_router_title: Optional[str] = None,
- x_open_router_categories: Optional[str] = None,
- date_: Optional[str] = None,
- api_key_hash: Optional[str] = None,
- user_id: Optional[str] = None,
+ request: Union[
+ operations.GetUserActivityRequest,
+ operations.GetUserActivityRequestTypedDict,
+ ] = operations.GetUserActivityRequest(),
retries: OptionalNullable[utils.RetryConfig] = UNSET,
server_url: Optional[str] = None,
timeout_ms: Optional[int] = None,
@@ -172,18 +154,9 @@ async def get_user_activity_async(
) -> components.ActivityResponse:
r"""Get user activity grouped by endpoint
- Returns user activity data grouped by endpoint for the last 30 (completed) UTC days. [Management key](/docs/guides/overview/auth/management-api-keys) required.
+ Returns user activity data grouped by endpoint for the last 30 (completed) UTC days. Pass `workspace_id` to scope the response to a single workspace. Pass `group_by=workspace` to split each row per workspace and include `workspace_id` on every item; by default rows are aggregated across workspaces and `workspace_id` is not returned. Activity recorded before workspace resolution existed is permanently attributed to the account default workspace (no backfill is possible). [Management key](/docs/guides/overview/auth/management-api-keys) required.
- :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 date_: Filter by a single UTC date in the last 30 days (YYYY-MM-DD format).
- :param api_key_hash: Filter by API key hash (SHA-256 hex string, as returned by the keys API).
- :param user_id: Filter by org member user ID. Only applicable for organization accounts.
+ :param request: The request object to send.
: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
@@ -199,14 +172,9 @@ async def get_user_activity_async(
else:
base_url = self._get_url(base_url, url_variables)
- request = operations.GetUserActivityRequest(
- http_referer=http_referer,
- x_open_router_title=x_open_router_title,
- x_open_router_categories=x_open_router_categories,
- date_=date_,
- api_key_hash=api_key_hash,
- user_id=user_id,
- )
+ if not isinstance(request, BaseModel):
+ request = utils.unmarshal(request, operations.GetUserActivityRequest)
+ request = cast(operations.GetUserActivityRequest, request)
req = self._build_request_async(
method="GET",
diff --git a/src/openrouter/components/activityitem.py b/src/openrouter/components/activityitem.py
index a234e6dd..3fecf83b 100644
--- a/src/openrouter/components/activityitem.py
+++ b/src/openrouter/components/activityitem.py
@@ -1,9 +1,11 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
-from openrouter.types import BaseModel
+from openrouter.types import BaseModel, UNSET_SENTINEL
import pydantic
-from typing_extensions import Annotated, TypedDict
+from pydantic import model_serializer
+from typing import Optional
+from typing_extensions import Annotated, NotRequired, TypedDict
class ActivityItemTypedDict(TypedDict):
@@ -29,6 +31,8 @@ class ActivityItemTypedDict(TypedDict):
r"""Number of requests made"""
usage: float
r"""Total cost in USD (OpenRouter credits spent)"""
+ workspace_id: NotRequired[str]
+ r"""ID of the workspace this activity is attributed to. Only present when `group_by=workspace` is passed; the response is then split per workspace. Activity recorded before workspace resolution existed is attributed to the account default workspace."""
class ActivityItem(BaseModel):
@@ -65,6 +69,25 @@ class ActivityItem(BaseModel):
usage: float
r"""Total cost in USD (OpenRouter credits spent)"""
+ workspace_id: Optional[str] = None
+ r"""ID of the workspace this activity is attributed to. Only present when `group_by=workspace` is passed; the response is then split per workspace. Activity recorded before workspace resolution existed is attributed to the account default workspace."""
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(["workspace_id"])
+ 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
+
try:
ActivityItem.model_rebuild()
diff --git a/src/openrouter/components/generationresponse.py b/src/openrouter/components/generationresponse.py
index 72098fb9..87454d8c 100644
--- a/src/openrouter/components/generationresponse.py
+++ b/src/openrouter/components/generationresponse.py
@@ -126,6 +126,8 @@ class GenerationResponseDataTypedDict(TypedDict):
r"""User-Agent header from the request"""
web_search_engine: Nullable[str]
r"""The resolved web search engine used for this generation (e.g. exa, firecrawl, parallel)"""
+ workspace_id: Nullable[str]
+ r"""ID of the workspace this generation is attributed to. Null for accounts without workspaces. Generations created before workspace resolution existed are attributed to the account default workspace."""
request_id: NotRequired[Nullable[str]]
r"""Unique identifier grouping all generations from a single API request"""
response_cache_source_id: NotRequired[Nullable[str]]
@@ -260,6 +262,9 @@ class GenerationResponseData(BaseModel):
web_search_engine: Nullable[str]
r"""The resolved web search engine used for this generation (e.g. exa, firecrawl, parallel)"""
+ workspace_id: Nullable[str]
+ r"""ID of the workspace this generation is attributed to. Null for accounts without workspaces. Generations created before workspace resolution existed are attributed to the account default workspace."""
+
request_id: OptionalNullable[str] = UNSET
r"""Unique identifier grouping all generations from a single API request"""
@@ -310,6 +315,7 @@ def serialize_model(self, handler):
"upstream_inference_cost",
"user_agent",
"web_search_engine",
+ "workspace_id",
]
)
serialized = handler(self)
diff --git a/src/openrouter/operations/__init__.py b/src/openrouter/operations/__init__.py
index 71aa5c14..63304964 100644
--- a/src/openrouter/operations/__init__.py
+++ b/src/openrouter/operations/__init__.py
@@ -455,6 +455,7 @@
GetUserActivityGlobalsTypedDict,
GetUserActivityRequest,
GetUserActivityRequestTypedDict,
+ GroupBy,
)
from .getvideos import (
GetVideosGlobals,
@@ -1133,6 +1134,7 @@
"Granularity",
"GranularityName",
"GranularityTypedDict",
+ "GroupBy",
"Headquarters",
"ImageURL",
"ImageURLTypedDict",
@@ -1763,6 +1765,7 @@
"GetUserActivityGlobalsTypedDict": ".getuseractivity",
"GetUserActivityRequest": ".getuseractivity",
"GetUserActivityRequestTypedDict": ".getuseractivity",
+ "GroupBy": ".getuseractivity",
"GetVideosGlobals": ".getvideos",
"GetVideosGlobalsTypedDict": ".getvideos",
"GetVideosRequest": ".getvideos",
diff --git a/src/openrouter/operations/getuseractivity.py b/src/openrouter/operations/getuseractivity.py
index 35ab9ca4..e635bfa9 100644
--- a/src/openrouter/operations/getuseractivity.py
+++ b/src/openrouter/operations/getuseractivity.py
@@ -5,7 +5,7 @@
from openrouter.utils import FieldMetadata, HeaderMetadata, QueryParamMetadata
import pydantic
from pydantic import model_serializer
-from typing import Optional
+from typing import Literal, Optional
from typing_extensions import Annotated, NotRequired, TypedDict
@@ -73,6 +73,10 @@ def serialize_model(self, handler):
return m
+GroupBy = Literal["workspace",]
+r"""Set to 'workspace' to split each row per workspace and include `workspace_id` on every item. Omitted by default, in which case rows are aggregated across workspaces (by date, model, and endpoint) and `workspace_id` is not returned — preserving the historical response shape."""
+
+
class GetUserActivityRequestTypedDict(TypedDict):
http_referer: NotRequired[str]
r"""The app identifier should be your app's URL and is used as the primary identifier for rankings.
@@ -93,6 +97,10 @@ class GetUserActivityRequestTypedDict(TypedDict):
r"""Filter by API key hash (SHA-256 hex string, as returned by the keys API)."""
user_id: NotRequired[str]
r"""Filter by org member user ID. Only applicable for organization accounts."""
+ group_by: NotRequired[GroupBy]
+ r"""Set to 'workspace' to split each row per workspace and include `workspace_id` on every item. Omitted by default, in which case rows are aggregated across workspaces (by date, model, and endpoint) and `workspace_id` is not returned — preserving the historical response shape."""
+ workspace_id: NotRequired[str]
+ r"""Filter by workspace ID (UUID). Returns only activity attributed to that workspace. The workspace must belong to the authenticated account."""
class GetUserActivityRequest(BaseModel):
@@ -143,6 +151,18 @@ class GetUserActivityRequest(BaseModel):
] = None
r"""Filter by org member user ID. Only applicable for organization accounts."""
+ group_by: Annotated[
+ Optional[GroupBy],
+ FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
+ ] = None
+ r"""Set to 'workspace' to split each row per workspace and include `workspace_id` on every item. Omitted by default, in which case rows are aggregated across workspaces (by date, model, and endpoint) and `workspace_id` is not returned — preserving the historical response shape."""
+
+ workspace_id: Annotated[
+ Optional[str],
+ FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
+ ] = None
+ r"""Filter by workspace ID (UUID). Returns only activity attributed to that workspace. The workspace must belong to the authenticated account."""
+
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(
@@ -153,6 +173,8 @@ def serialize_model(self, handler):
"date",
"api_key_hash",
"user_id",
+ "group_by",
+ "workspace_id",
]
)
serialized = handler(self)
diff --git a/src/openrouter/operations/queryanalytics.py b/src/openrouter/operations/queryanalytics.py
index bde10deb..a7e12477 100644
--- a/src/openrouter/operations/queryanalytics.py
+++ b/src/openrouter/operations/queryanalytics.py
@@ -179,11 +179,11 @@ class ClassifierFilters(BaseModel):
Value1TypedDict = TypeAliasType(
"Value1TypedDict", Union[str, float, List[Value2TypedDict]]
)
-r"""Filter value (scalar or array depending on operator). Several dimensions are enriched in responses (returned as human-readable labels), but filters must use the underlying ID: `api_key_id` — numeric ID (from generation metadata) or key hash (64-char hex from GET /api/v1/keys, resolved server-side); `user` — Clerk user ID (e.g. \"user_abc123\"), not the display name; `workspace` — workspace UUID, not the workspace name; `app` — numeric app ID, not the app title; `model` — permaslug (e.g. \"openai/gpt-4o\"), not the display name. Other dimensions (provider, origin, country, etc.) are not enriched and accept the value as returned."""
+r"""Filter value (scalar or array depending on operator). Several dimensions are enriched in responses (returned as human-readable labels), but filters must use the underlying ID: `api_key_id` — numeric ID (from generation metadata) or key hash (64-char hex from GET /api/v1/keys, resolved server-side); `user` — Clerk user ID (e.g. \"user_abc123\"), not the display name; `workspace` — workspace UUID, not the workspace name (filtering or grouping by the account default workspace also covers activity recorded before workspace resolution existed, which is attributed to that default workspace); `app` — numeric app ID, not the app title; `model` — permaslug (e.g. \"openai/gpt-4o\"), not the display name. Other dimensions (provider, origin, country, etc.) are not enriched and accept the value as returned."""
Value1 = TypeAliasType("Value1", Union[str, float, List[Value2]])
-r"""Filter value (scalar or array depending on operator). Several dimensions are enriched in responses (returned as human-readable labels), but filters must use the underlying ID: `api_key_id` — numeric ID (from generation metadata) or key hash (64-char hex from GET /api/v1/keys, resolved server-side); `user` — Clerk user ID (e.g. \"user_abc123\"), not the display name; `workspace` — workspace UUID, not the workspace name; `app` — numeric app ID, not the app title; `model` — permaslug (e.g. \"openai/gpt-4o\"), not the display name. Other dimensions (provider, origin, country, etc.) are not enriched and accept the value as returned."""
+r"""Filter value (scalar or array depending on operator). Several dimensions are enriched in responses (returned as human-readable labels), but filters must use the underlying ID: `api_key_id` — numeric ID (from generation metadata) or key hash (64-char hex from GET /api/v1/keys, resolved server-side); `user` — Clerk user ID (e.g. \"user_abc123\"), not the display name; `workspace` — workspace UUID, not the workspace name (filtering or grouping by the account default workspace also covers activity recorded before workspace resolution existed, which is attributed to that default workspace); `app` — numeric app ID, not the app title; `model` — permaslug (e.g. \"openai/gpt-4o\"), not the display name. Other dimensions (provider, origin, country, etc.) are not enriched and accept the value as returned."""
class FilterTypedDict(TypedDict):
@@ -192,7 +192,7 @@ class FilterTypedDict(TypedDict):
operator: str
r"""Filter operator"""
value: Value1TypedDict
- r"""Filter value (scalar or array depending on operator). Several dimensions are enriched in responses (returned as human-readable labels), but filters must use the underlying ID: `api_key_id` — numeric ID (from generation metadata) or key hash (64-char hex from GET /api/v1/keys, resolved server-side); `user` — Clerk user ID (e.g. \"user_abc123\"), not the display name; `workspace` — workspace UUID, not the workspace name; `app` — numeric app ID, not the app title; `model` — permaslug (e.g. \"openai/gpt-4o\"), not the display name. Other dimensions (provider, origin, country, etc.) are not enriched and accept the value as returned."""
+ r"""Filter value (scalar or array depending on operator). Several dimensions are enriched in responses (returned as human-readable labels), but filters must use the underlying ID: `api_key_id` — numeric ID (from generation metadata) or key hash (64-char hex from GET /api/v1/keys, resolved server-side); `user` — Clerk user ID (e.g. \"user_abc123\"), not the display name; `workspace` — workspace UUID, not the workspace name (filtering or grouping by the account default workspace also covers activity recorded before workspace resolution existed, which is attributed to that default workspace); `app` — numeric app ID, not the app title; `model` — permaslug (e.g. \"openai/gpt-4o\"), not the display name. Other dimensions (provider, origin, country, etc.) are not enriched and accept the value as returned."""
class Filter(BaseModel):
@@ -203,7 +203,7 @@ class Filter(BaseModel):
r"""Filter operator"""
value: Value1
- r"""Filter value (scalar or array depending on operator). Several dimensions are enriched in responses (returned as human-readable labels), but filters must use the underlying ID: `api_key_id` — numeric ID (from generation metadata) or key hash (64-char hex from GET /api/v1/keys, resolved server-side); `user` — Clerk user ID (e.g. \"user_abc123\"), not the display name; `workspace` — workspace UUID, not the workspace name; `app` — numeric app ID, not the app title; `model` — permaslug (e.g. \"openai/gpt-4o\"), not the display name. Other dimensions (provider, origin, country, etc.) are not enriched and accept the value as returned."""
+ r"""Filter value (scalar or array depending on operator). Several dimensions are enriched in responses (returned as human-readable labels), but filters must use the underlying ID: `api_key_id` — numeric ID (from generation metadata) or key hash (64-char hex from GET /api/v1/keys, resolved server-side); `user` — Clerk user ID (e.g. \"user_abc123\"), not the display name; `workspace` — workspace UUID, not the workspace name (filtering or grouping by the account default workspace also covers activity recorded before workspace resolution existed, which is attributed to that default workspace); `app` — numeric app ID, not the app title; `model` — permaslug (e.g. \"openai/gpt-4o\"), not the display name. Other dimensions (provider, origin, country, etc.) are not enriched and accept the value as returned."""
Direction = Union[
diff --git a/uv.lock b/uv.lock
index 0997b176..ac3d967e 100644
--- a/uv.lock
+++ b/uv.lock
@@ -213,7 +213,7 @@ wheels = [
[[package]]
name = "openrouter"
-version = "1.1.24"
+version = "1.1.25"
source = { editable = "." }
dependencies = [
{ name = "httpcore" },