diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index 0111ab6c..bf5205ef 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: 2ef535ebda9c7b762888bff09506f8c2 + docChecksum: 683ee88c6d5be9a3060432f6134bb5c7 docVersion: 1.0.0 speakeasyVersion: 1.787.0 generationVersion: 2.914.0 - releaseVersion: 1.3.91 - configChecksum: 1631c8dd4bc97b030a4bdc257c0cbce5 + releaseVersion: 1.3.92 + configChecksum: 7a65dc725fba9fff0d5a558b893bd114 repoURL: https://github.com/OpenRouterTeam/python-sdk.git installationURL: https://github.com/OpenRouterTeam/python-sdk.git published: true persistentEdits: - generation_id: ee23180e-85bc-4c09-874c-a78ddb886c5d - pristine_commit_hash: 25d5492c758de7f31bc1d2caf28b814ef59558e8 - pristine_tree_hash: 52fa6c0e04045073205ed121fc70d8e7c2833544 + generation_id: 9a0f8627-848c-4872-8098-972935503e3e + pristine_commit_hash: 30a7fcace11d7146fe7b2e40ca37084bbb267484 + pristine_tree_hash: fbc9982239e745d4c7e0ab37dfbfbed8e543d345 features: python: acceptHeaders: 3.0.0 @@ -2656,8 +2656,8 @@ trackedFiles: pristine_git_object: eb40e769b6344e2f0bf6432dc726754b072da6a7 docs/components/createguardrailrequest.mdx: id: c1a768f054c0 - last_write_checksum: sha1:a8119bc205b2be6813253126ce9228f570d1a046 - pristine_git_object: 542a99a54459b90798bf3965572d0e4613bd004f + last_write_checksum: sha1:c734d16493928fbe512c39272414cbdfc90e354f + pristine_git_object: 61fdc4540f314290605f62cbdd81bb21889f662d docs/components/createguardrailresponse.mdx: id: 1477eebdf505 last_write_checksum: sha1:76bb1fcafda689e9823bb21541c84e7d0bdb991d @@ -3620,8 +3620,8 @@ trackedFiles: pristine_git_object: 6e17644dffb3aef799758f46d5ac781114b58c1f docs/components/guardrail.mdx: id: 91791d4c83b6 - last_write_checksum: sha1:6ee6ddc800b718dbaa8280fead69fdfb9e6f7267 - pristine_git_object: aabdf6952664ef02c85bc6cf32a8b84ff74c5a3d + last_write_checksum: sha1:5876bb2244f6a45000ed0876a450cf4b28e96433 + pristine_git_object: 3cfe873a62f82be707f2effd48315f9e4b979590 docs/components/guardraildataregion.mdx: id: d3be2a48aa20 last_write_checksum: sha1:81f1c0b515e1c1c13432cae9910ce77cb9991507 @@ -5388,8 +5388,8 @@ trackedFiles: pristine_git_object: 7958f4207c6b7aeb33acdac3f5cb85793d2e605f docs/components/organizationsettings.mdx: id: e6dc72898ebd - last_write_checksum: sha1:f8902782a2b6ad664e27acbd9aef737aee08399a - pristine_git_object: 6a67a56e8a5e3af08f2432768ac3ad1975ea8b84 + last_write_checksum: sha1:6641ba749fdb5eff2e5f94ceb5912290ae8c343c + pristine_git_object: 8f72b45f5325c9acaed20586dbd15f36194e4237 docs/components/outcome.mdx: id: dc555505ef36 last_write_checksum: sha1:5e99185f9d49f3f404ca4e54ef84d0cdbf31546c @@ -7820,8 +7820,8 @@ trackedFiles: pristine_git_object: 786d70e7d86e76b820f222c63993ce80150614a0 docs/components/updateguardrailrequest.mdx: id: 450912b18db6 - last_write_checksum: sha1:06d188e2836d12a14af08453a4e460cd9a386294 - pristine_git_object: 254cdd817c57d459580cbb0d3064e5ba407d71ba + last_write_checksum: sha1:1a804dea815cbe2c46011078f2219186a2ca0ad4 + pristine_git_object: 0639c9f72acce0eaccced2dd005f0e5c8bc4327a docs/components/updateguardrailresponse.mdx: id: e00dc0a0c6e0 last_write_checksum: sha1:1be70185072640936151f861913c2b89a09d4bab @@ -7836,8 +7836,8 @@ trackedFiles: pristine_git_object: 7c7ec75d17b13894bf9c27c84b156b8765398d62 docs/components/updateorganizationsettingsrequest.mdx: id: 38c4ebf7f509 - last_write_checksum: sha1:4b0aa79182315301b6824bd933676a5b2b5bdd3a - pristine_git_object: d46fb370c21fa0d04b29ece85364a693737dfe79 + last_write_checksum: sha1:70c9b33138471d438e9d032c8b669fb40a9f1a51 + pristine_git_object: f252230de349b2ce3c106f41bc177c9d3c469385 docs/components/updateprivateendpointparametersrequest.mdx: id: f28148578ff0 last_write_checksum: sha1:979f224d1db14d9b9e2b4195f1f56747800cd59f @@ -10120,16 +10120,16 @@ trackedFiles: pristine_git_object: 99025e4e653ef972cf511103e851cfd6c72ddda2 docs/sdks/guardrails/README.mdx: id: a0cd4218b8fa - last_write_checksum: sha1:8a7bd8b43337d429726ac461e248aca8100b54cf - pristine_git_object: b5af7242eb24d0be26f7fcc82aaec22a93582670 + last_write_checksum: sha1:9574fe7e79255be96e6b1fd274b8c2eca1d3b7b8 + pristine_git_object: 4db2807c295cd20542519d2732d203ec779370f3 docs/sdks/images/README.mdx: id: 534a6c102c4f last_write_checksum: sha1:82a8bd22fb399fe419076afe29b9234950baf9f9 pristine_git_object: 08c687694efbecf50406ae7929029d39fb121295 docs/sdks/models/README.mdx: id: 58f1ca464e0b - last_write_checksum: sha1:9ab8eac9bda9a892da9a56574b50914a451429ba - pristine_git_object: f7f31f5fc467d46d7d160b9fc914fcc197cd5b6f + last_write_checksum: sha1:8dd63e2796b4ba004b1302600bb7cbfa64d369d9 + pristine_git_object: f430ab33146f45a670b2be6869e57f05d2afe924 docs/sdks/oauth/README.mdx: id: 42b5079343d2 last_write_checksum: sha1:3cde9bcb927f4723ccdb237d9f7a54a50f96abe7 @@ -10140,8 +10140,8 @@ trackedFiles: pristine_git_object: 078a05993b4a2d4abd652033a08e52f44f750fd2 docs/sdks/organization/README.mdx: id: f41b85542db0 - last_write_checksum: sha1:16a89d4805aafa873479dfe2aa051eb3bc88e47f - pristine_git_object: 053e655dd039e6dd37558c4b9af98c3d60ea8989 + last_write_checksum: sha1:96b750021641bd83929ec08dbb67324a7a398f62 + pristine_git_object: 4aff0b689137d2bab9c13a6b4cce5680a5c1ce59 docs/sdks/presets/README.mdx: id: eeb505928d52 last_write_checksum: sha1:d61cbf5df8597879e007f434e8a0f2eb04c24355 @@ -10200,8 +10200,8 @@ trackedFiles: pristine_git_object: 3e38f1a929f7d6b1d6de74604aa87e3d8f010544 pyproject.toml: id: 5d07e7d72637 - last_write_checksum: sha1:bfe3bcd84aa98d465abf3105d94c7fb58057b8e9 - pristine_git_object: d51a2b9e68085f71cb74187be666111362975977 + last_write_checksum: sha1:ae7c1a35526d41795659423dfcda32bdd8a0d8de + pristine_git_object: bf446a40e74b7e9ccd34d4a7843c5c50d5850629 scripts/prepare_readme.py: id: e0c5957a6035 last_write_checksum: sha1:77f44b60b98bc126557ec27391f91dfba764bb54 @@ -10228,8 +10228,8 @@ trackedFiles: pristine_git_object: 86713cfea633e09d33b3d4e65281071fe20e6137 src/openrouter/_version.py: id: d8d15ad6c586 - last_write_checksum: sha1:4247150e2e76e661346779330d8ba77c9e410485 - pristine_git_object: b2b71ec7625493d888418d86197900afe3927036 + last_write_checksum: sha1:e63acea99e91e8d74ef7427d0b14fa71b4a5e912 + pristine_git_object: 27fe009ed0c5f04f72e28e0bcb1be327f488e1e7 src/openrouter/alpha.py: id: 306c4d93308d last_write_checksum: sha1:30f55a360f41376ab194b9ea725fe4e001a5ae1a @@ -11376,8 +11376,8 @@ trackedFiles: pristine_git_object: c575c3dbc1aeeb262172f88c60d0e4eddddf5e21 src/openrouter/components/createguardrailrequest.py: id: 34d69149fb33 - last_write_checksum: sha1:27e7f5d3c168e26855988ff24ce8d25ce39a9d82 - pristine_git_object: 8185633aa3d3df59d410f2bd4e38b402de1f0808 + last_write_checksum: sha1:466b7c4a50eb074ad5a5d2ae5c249bb6b6d26b48 + pristine_git_object: 60395247d1a727bb1b4a3e495356e47b73db0233 src/openrouter/components/createguardrailresponse.py: id: b4e1bdf1de5b last_write_checksum: sha1:ae20a5e7425510c240e5697d847b1cae65940bd6 @@ -11808,8 +11808,8 @@ trackedFiles: pristine_git_object: 1268e32c9058ed4feb7482458a64366c56201676 src/openrouter/components/guardrail.py: id: 67ee78dd06e6 - last_write_checksum: sha1:a1c6a71826af7c0ad5fa1e9ef08871c2b9bed566 - pristine_git_object: 1e8c4fd2799b1f87437771d0e3f323c89ac585e4 + last_write_checksum: sha1:df154988e3a6d5fb565fed5111b9d92e8d754a70 + pristine_git_object: 0591b4f424f4665ba6434960cf8614a548ef94ec src/openrouter/components/guardraildataregion.py: id: 16c31f1446b2 last_write_checksum: sha1:52b5622a7c93a30219108f033ab0e3fbb3a396f7 @@ -12452,8 +12452,8 @@ trackedFiles: pristine_git_object: 42f8fa499c4562efa14803a63a99b99c0acb336e src/openrouter/components/organizationsettings.py: id: 7199bc39a5b2 - last_write_checksum: sha1:76a1350c958daacc067b754d3848234209098dcd - pristine_git_object: aa9d74f68172a52f3fc81bf4e480b145c3022e92 + last_write_checksum: sha1:3ca176c9fa7cc884057972c50e447b9d4b604d83 + pristine_git_object: 30c1a19571dc16a9d8c92081a8ffb56c8a0f9f35 src/openrouter/components/outputadvisorservertoolitem.py: id: aa64bddfa26c last_write_checksum: sha1:9d960f059ee0d737693f9e5561de1e8f377a412c @@ -13400,8 +13400,8 @@ trackedFiles: pristine_git_object: 012b3aaddaeaedda9fc99afa4a817c10fe49239b src/openrouter/components/updateguardrailrequest.py: id: 6a557cd822a0 - last_write_checksum: sha1:a22716af2dc5e2cea5413b44e24146d136b98b2e - pristine_git_object: 3304e76e02b104d35d3cd5124d42345ec4c084ba + last_write_checksum: sha1:95cb72e9a815cff16a229afbfc39cc771da757e4 + pristine_git_object: f3e803ca4e677c1542698512fb68d1c6684b23ef src/openrouter/components/updateguardrailresponse.py: id: 7b068d26ce31 last_write_checksum: sha1:2b63cbb90747f07f775d9a22e80f74c67221fea8 @@ -13416,8 +13416,8 @@ trackedFiles: pristine_git_object: 95abc42170d9ebeadee791d15c2bbc643720f1dc src/openrouter/components/updateorganizationsettingsrequest.py: id: 2d255d9e4ac4 - last_write_checksum: sha1:896ed9e6dd5c9b9df3884fe241a8f36d2e266f1b - pristine_git_object: ee583b9b6f862c2ade099938c4c62d61ea9cbfa2 + last_write_checksum: sha1:6b703da8963b0173865bd4692d53bd53b50b42a0 + pristine_git_object: add97f9dbdd883540c97aaeffb4a9f227097b07e src/openrouter/components/updateprivateendpointparametersrequest.py: id: 5ef821e2e35c last_write_checksum: sha1:af9d883d7a2df9c6e0ce936aa96bdf0267607a82 @@ -13768,8 +13768,8 @@ trackedFiles: pristine_git_object: 8c989db92d681ffe9a956bae5c16c8f09f3627ca src/openrouter/guardrails.py: id: 705839f34e66 - last_write_checksum: sha1:156c955e4e751a229100a3261e297d2898b5d089 - pristine_git_object: fac2d71e27a14bbe4a40fd194e7b1fe38d0a558c + last_write_checksum: sha1:b19c85cfbeab0b2ef2e97b9bb3f16851669860b4 + pristine_git_object: 3718d5c7acd6c821dd85231c05a5c45eb645dc3e src/openrouter/httpclient.py: id: e9311185443d last_write_checksum: sha1:5e55338d6ee9f01ab648cad4380201a8a3da7dd7 @@ -13792,8 +13792,8 @@ trackedFiles: pristine_git_object: 5b741456655ff48919d17ffd552a6410f0587966 src/openrouter/models_.py: id: 4e1ae1fe5b98 - last_write_checksum: sha1:db8830585720bd4e97f3f504d267aad2d4d9b2c8 - pristine_git_object: f880d869b3fd46cd459a71592e61bc7cddb40c64 + last_write_checksum: sha1:988ec8ceacdd596451165a662a9f9c15d32b08e5 + pristine_git_object: 0e5a416145a4ad17419518975c284d2ba7f74bc3 src/openrouter/oauth.py: id: 1948ce27255b last_write_checksum: sha1:d6470de6325431db64b08ff4468fb2d8ea781c6f @@ -14364,8 +14364,8 @@ trackedFiles: pristine_git_object: de47082ac5d1636fbeaa4fe1604fd4e3edcadcc8 src/openrouter/organization.py: id: 6f4c63c416e8 - last_write_checksum: sha1:4e85be9a562415e0e55d62ec34339e0b1325c3d2 - pristine_git_object: ed6685a2de0af075647def8ee786e7da58f627a6 + last_write_checksum: sha1:4186c12b753756d5f78be4143af7ab76b0af18e4 + pristine_git_object: 228602282f43dd94fb7703bb47b45a570c1aa8d2 src/openrouter/presets.py: id: bd0c40379dcd last_write_checksum: sha1:e3eff582e7c9c51cc9c23d4716a419f4a86baa7f @@ -14751,6 +14751,16 @@ examples: application/json: {"error": {"code": 403, "message": "Only management keys can perform this operation"}} "503": application/json: {"error": {"code": 503, "message": "Service temporarily unavailable"}} + "401": + application/json: {"error": {"code": 401, "message": "Missing Authentication header"}} + "404": + application/json: {"error": {"code": 404, "message": "Resource not found"}} + "408": + application/json: {"error": {"code": 408, "message": "Operation timed out. Please try again later."}} + "409": + application/json: {"error": {"code": 409, "message": "Resource conflict. Please try again later."}} + "429": + application/json: {"error": {"code": 429, "message": "Rate limit exceeded"}} listModelsUser: speakeasy-default-list-models-user: parameters: @@ -14770,6 +14780,12 @@ examples: application/json: {"error": {"code": 403, "message": "Only management keys can perform this operation"}} "503": application/json: {"error": {"code": 503, "message": "Service temporarily unavailable"}} + "408": + application/json: {"error": {"code": 408, "message": "Operation timed out. Please try again later."}} + "409": + application/json: {"error": {"code": 409, "message": "Resource conflict. Please try again later."}} + "429": + application/json: {"error": {"code": 429, "message": "Rate limit exceeded"}} listEndpoints: speakeasy-default-list-endpoints: parameters: @@ -18897,4 +18913,4 @@ examples: "502": application/json: {"error": {"code": 502, "message": "Provider returned error"}} examplesVersion: 1.0.2 -releaseNotes: "## Python SDK Changes:\n* `open_router.alpha.decisions.create()`: `request.provider` **Changed**\n* `open_router.tts.create_speech()`: \n * `request.provider.options.particle_ai` **Added**\n* `open_router.stt.create_transcription()`: \n * `request.provider.options.particle_ai` **Added**\n* `open_router.batch.create_batches()`: \n * `request.provider.only[].union(ProviderName).enum(particle_ai)` **Added**\n* `open_router.byok.list()`: \n * `request.provider` **Changed**\n * `response.data[].provider.enum(particle_ai)` **Added**\n* `open_router.byok.create()`: \n * `request.provider.enum(particle_ai)` **Added**\n * `response.data.provider.enum(particle_ai)` **Added**\n* `open_router.byok.get()`: `response.data.provider.enum(particle_ai)` **Added**\n* `open_router.byok.update()`: `response.data.provider.enum(particle_ai)` **Added**\n* `open_router.chat.send()`: `request.provider` **Changed**\n* `open_router.embeddings.generate()`: `request.provider` **Changed**\n* `open_router.endpoints.list_zdr_endpoints()`: `response.data[].provider_name.enum(particle_ai)` **Added**\n* `open_router.endpoints.list()`: `response.data.endpoints[].provider_name.enum(particle_ai)` **Added**\n* `open_router.generations.get_generation()`: `response.data.provider_responses[].provider_name.enum(particle_ai)` **Added**\n* `open_router.images.generate()`: `request.provider` **Changed**\n* `open_router.presets.create_presets_chat_completions()`: `request.provider` **Changed**\n* `open_router.presets.create_presets_messages()`: `request.provider` **Changed**\n* `open_router.presets.create_presets_responses()`: `request.provider` **Changed**\n* `open_router.rerank.rerank()`: `request.provider` **Changed**\n* `open_router.responses.send()`: `request.provider` **Changed**\n* `open_router.beta.responses.send()`: `request.provider` **Changed**\n* `open_router.system_one.create()`: `request.provider` **Changed**\n* `open_router.video_generation.generate()`: \n * `request.provider.options.particle_ai` **Added**\n" +releaseNotes: "## Python SDK Changes:\n* `open_router.guardrails.list()`: `response.data[].enforce_first_party_harness_models` **Added**\n* `open_router.guardrails.create()`: \n * `request.enforce_first_party_harness_models` **Added**\n * `response.data.enforce_first_party_harness_models` **Added**\n* `open_router.guardrails.get()`: `response.data.enforce_first_party_harness_models` **Added**\n* `open_router.guardrails.update()`: \n * `request.enforce_first_party_harness_models` **Added**\n * `response.data.enforce_first_party_harness_models` **Added**\n* `open_router.models.list()`: `error` **Changed**\n* `open_router.models.list_for_user()`: `error` **Changed**\n" diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml index ed73e408..7187d333 100644 --- a/.speakeasy/gen.yaml +++ b/.speakeasy/gen.yaml @@ -36,7 +36,7 @@ generation: documentation: mintlify preApplyUnionDiscriminators: true python: - version: 1.3.91 + version: 1.3.92 additionalDependencies: dev: pytest: '>=8.3' diff --git a/.speakeasy/out.openapi.yaml b/.speakeasy/out.openapi.yaml index b2341ee2..f8a5535a 100644 --- a/.speakeasy/out.openapi.yaml +++ b/.speakeasy/out.openapi.yaml @@ -10086,6 +10086,12 @@ components: type: - 'boolean' - 'null' + enforce_first_party_harness_models: + description: 'Whether coding harnesses list only their vendor''s own models: Codex lists OpenAI models and Claude Code and Claude Desktop list Anthropic models. Affects only the model list those harnesses request from GET /models; a model the client names directly is still routed. Any true across the workspace default, member, and API key guardrails applies.' + example: false + type: + - 'boolean' + - 'null' enforce_zdr: deprecated: true description: 'Deprecated. Use enforce_zdr_anthropic, enforce_zdr_openai, enforce_zdr_google, enforce_zdr_xai, and enforce_zdr_other instead. When provided, its value is copied into any of those per-provider fields that are not explicitly specified on the request.' @@ -13813,6 +13819,12 @@ components: type: - 'boolean' - 'null' + enforce_first_party_harness_models: + description: 'Whether coding harnesses list only their vendor''s own models: Codex lists OpenAI models and Claude Code and Claude Desktop list Anthropic models. Affects only the model list those harnesses request from GET /models; a model the client names directly is still routed. Any true across the workspace default, member, and API key guardrails applies.' + example: false + type: + - 'boolean' + - 'null' enforce_zdr: deprecated: true description: 'Deprecated. Use enforce_zdr_anthropic, enforce_zdr_openai, enforce_zdr_google, enforce_zdr_xai, and enforce_zdr_other instead. When provided, its value is copied into any of those per-provider fields that are not explicitly specified on the request.' @@ -23098,7 +23110,7 @@ components: example: 'org_2dHFtVWx2n56w6HkM0000000000' type: 'string' is_filtered_model_catalog_enabled: - description: 'When true, `GET /api/v1/models` called with one of the organization''s API keys returns only the models that key can use (the `/api/v1/models/user` catalog), and the signed-in dashboard shows the same list. Anonymous requests always receive the public catalog.' + description: 'When true, the signed-in dashboard lists only the models the organization can use. `GET /api/v1/models` called with an API key always returns only the models that key can use, whatever this setting says; anonymous requests receive the public catalog.' example: true type: 'boolean' required: @@ -32129,6 +32141,12 @@ components: type: - 'boolean' - 'null' + enforce_first_party_harness_models: + description: 'Whether coding harnesses list only their vendor''s own models: Codex lists OpenAI models and Claude Code and Claude Desktop list Anthropic models. Affects only the model list those harnesses request from GET /models; a model the client names directly is still routed. Any true across the workspace default, member, and API key guardrails applies.' + example: true + type: + - 'boolean' + - 'null' enforce_zdr: deprecated: true description: 'Deprecated. Use enforce_zdr_anthropic, enforce_zdr_openai, enforce_zdr_google, enforce_zdr_xai, and enforce_zdr_other instead. When provided, its value is copied into any of those per-provider fields that are not explicitly specified on the request.' @@ -32349,7 +32367,7 @@ components: additionalProperties: false properties: is_filtered_model_catalog_enabled: - description: 'When true, `GET /api/v1/models` called with one of the organization''s API keys returns only the models that key can use (the `/api/v1/models/user` catalog), and the signed-in dashboard shows the same list. Anonymous requests always receive the public catalog.' + description: 'When true, the signed-in dashboard lists only the models the organization can use. `GET /api/v1/models` called with an API key always returns only the models that key can use, whatever this setting says; anonymous requests receive the public catalog.' example: true type: 'boolean' required: @@ -44967,6 +44985,16 @@ paths: 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' '403': content: application/json: @@ -44977,6 +45005,46 @@ paths: schema: $ref: '#/components/schemas/ForbiddenResponse' description: 'Forbidden - Authentication successful but insufficient permissions' + '404': + content: + application/json: + example: + error: + code: 404 + message: 'Resource not found' + schema: + $ref: '#/components/schemas/NotFoundResponse' + description: 'Not Found - Resource does not exist' + '408': + content: + application/json: + example: + error: + code: 408 + message: 'Operation timed out. Please try again later.' + schema: + $ref: '#/components/schemas/RequestTimeoutResponse' + description: 'Request Timeout - Operation exceeded time limit' + '409': + content: + application/json: + example: + error: + code: 409 + message: 'Resource conflict. Please try again later.' + schema: + $ref: '#/components/schemas/ConflictResponse' + description: 'Conflict - Resource conflict or concurrent modification' + '429': + content: + application/json: + example: + error: + code: 429 + message: 'Rate limit exceeded' + schema: + $ref: '#/components/schemas/TooManyRequestsResponse' + description: 'Too Many Requests - Rate limit exceeded' '500': content: application/json: @@ -45353,6 +45421,36 @@ paths: schema: $ref: '#/components/schemas/NotFoundResponse' description: 'Not Found - Resource does not exist' + '408': + content: + application/json: + example: + error: + code: 408 + message: 'Operation timed out. Please try again later.' + schema: + $ref: '#/components/schemas/RequestTimeoutResponse' + description: 'Request Timeout - Operation exceeded time limit' + '409': + content: + application/json: + example: + error: + code: 409 + message: 'Resource conflict. Please try again later.' + schema: + $ref: '#/components/schemas/ConflictResponse' + description: 'Conflict - Resource conflict or concurrent modification' + '429': + content: + application/json: + example: + error: + code: 429 + message: 'Rate limit exceeded' + schema: + $ref: '#/components/schemas/TooManyRequestsResponse' + description: 'Too Many Requests - Rate limit exceeded' '500': content: application/json: diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock index 3fb3e704..8b680423 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:704ac32d827ce185a6829dc9c9abce19ea5b404aefe6a1a0751cbee73165f3ff - sourceBlobDigest: sha256:657673833d8224c6934b14b7fd562af787855d4454b57dbf9576499af7d68d5e + sourceRevisionDigest: sha256:961fe90ca2e42e72fb86e11f22da47c0e8e74ec6c7ddf685a736d95a07aa294f + sourceBlobDigest: sha256:d68b5a65adb80192ca07be6d7745a7f1a1f474ef6815a944f65d67cdf4d63683 tags: - latest - 1.0.0 @@ -11,10 +11,10 @@ targets: open-router: source: OpenRouter API sourceNamespace: open-router-chat-completions-api - sourceRevisionDigest: sha256:704ac32d827ce185a6829dc9c9abce19ea5b404aefe6a1a0751cbee73165f3ff - sourceBlobDigest: sha256:657673833d8224c6934b14b7fd562af787855d4454b57dbf9576499af7d68d5e + sourceRevisionDigest: sha256:961fe90ca2e42e72fb86e11f22da47c0e8e74ec6c7ddf685a736d95a07aa294f + sourceBlobDigest: sha256:d68b5a65adb80192ca07be6d7745a7f1a1f474ef6815a944f65d67cdf4d63683 codeSamplesNamespace: open-router-python-code-samples - codeSamplesRevisionDigest: sha256:4a8093b2ed0dc98582ed47778a5dc10e109228df45004c5e3a6a27012c343f85 + codeSamplesRevisionDigest: sha256:eeafc880cbe1fa034df058a9b1cd35a6f644fb701ca612c99b67cf3f6b5ae042 workflow: workflowVersion: 1.0.0 speakeasyVersion: 1.787.0 diff --git a/RELEASES.md b/RELEASES.md index ec5e5707..0bf7216d 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -3679,4 +3679,14 @@ Based on: ### Generated - [python v1.3.91] . ### Releases -- [PyPI v1.3.91] https://pypi.org/project/openrouter/1.3.91 - . \ No newline at end of file +- [PyPI v1.3.91] https://pypi.org/project/openrouter/1.3.91 - . + +## 2026-10-28 20:19:16 +### Changes +Based on: +- OpenAPI Doc +- Speakeasy CLI 1.787.0 (2.914.0) https://github.com/speakeasy-api/speakeasy +### Generated +- [python v1.3.92] . +### Releases +- [PyPI v1.3.92] https://pypi.org/project/openrouter/1.3.92 - . \ No newline at end of file diff --git a/docs/components/createguardrailrequest.mdx b/docs/components/createguardrailrequest.mdx index ca0827c5..1918bf24 100644 --- a/docs/components/createguardrailrequest.mdx +++ b/docs/components/createguardrailrequest.mdx @@ -17,6 +17,7 @@ title: "CreateGuardrailRequest" | `enable_free_model_publication` | *OptionalNullable[bool]* | ➖ | Whether this guardrail allows free endpoints that publish prompts. | false | | `enable_free_model_training` | *OptionalNullable[bool]* | ➖ | Whether this guardrail allows free endpoints that train on request data. | true | | `enable_paid_model_training` | *OptionalNullable[bool]* | ➖ | Whether this guardrail allows paid endpoints that train on request data. | true | +| `enforce_first_party_harness_models` | *OptionalNullable[bool]* | ➖ | Whether coding harnesses list only their vendor's own models: Codex lists OpenAI models and Claude Code and Claude Desktop list Anthropic models. Affects only the model list those harnesses request from GET /models; a model the client names directly is still routed. Any true across the workspace default, member, and API key guardrails applies. | false | | ~~`enforce_zdr`~~ | *OptionalNullable[bool]* | ➖ | : warning: ** DEPRECATED **: This will be removed in a future release, please migrate away from it as soon as possible.

Deprecated. Use enforce_zdr_anthropic, enforce_zdr_openai, enforce_zdr_google, enforce_zdr_xai, and enforce_zdr_other instead. When provided, its value is copied into any of those per-provider fields that are not explicitly specified on the request. | false | | `enforce_zdr_anthropic` | *OptionalNullable[bool]* | ➖ | Whether to enforce zero data retention for Anthropic models. Falls back to enforce_zdr when not provided. | false | | `enforce_zdr_google` | *OptionalNullable[bool]* | ➖ | Whether to enforce zero data retention for Google models. Falls back to enforce_zdr when not provided. | false | diff --git a/docs/components/guardrail.mdx b/docs/components/guardrail.mdx index 18e5bbb3..5f21740c 100644 --- a/docs/components/guardrail.mdx +++ b/docs/components/guardrail.mdx @@ -18,6 +18,7 @@ title: "Guardrail" | `enable_free_model_publication` | *OptionalNullable[bool]* | ➖ | Whether this guardrail allows free endpoints that publish prompts. | false | | `enable_free_model_training` | *OptionalNullable[bool]* | ➖ | Whether this guardrail allows free endpoints that train on request data. | true | | `enable_paid_model_training` | *OptionalNullable[bool]* | ➖ | Whether this guardrail allows paid endpoints that train on request data. | true | +| `enforce_first_party_harness_models` | *OptionalNullable[bool]* | ➖ | Whether coding harnesses list only their vendor's own models: Codex lists OpenAI models and Claude Code and Claude Desktop list Anthropic models. Affects only the model list those harnesses request from GET /models; a model the client names directly is still routed. Any true across the workspace default, member, and API key guardrails applies. | false | | ~~`enforce_zdr`~~ | *OptionalNullable[bool]* | ➖ | : warning: ** DEPRECATED **: This will be removed in a future release, please migrate away from it as soon as possible.

Deprecated. Use enforce_zdr_anthropic, enforce_zdr_openai, enforce_zdr_google, enforce_zdr_xai, and enforce_zdr_other instead. When provided, its value is copied into any of those per-provider fields that are not explicitly specified on the request. | false | | `enforce_zdr_anthropic` | *OptionalNullable[bool]* | ➖ | Whether to enforce zero data retention for Anthropic models. Falls back to enforce_zdr when not provided. | false | | `enforce_zdr_google` | *OptionalNullable[bool]* | ➖ | Whether to enforce zero data retention for Google models. Falls back to enforce_zdr when not provided. | false | diff --git a/docs/components/organizationsettings.mdx b/docs/components/organizationsettings.mdx index c8e3952d..bc7031fb 100644 --- a/docs/components/organizationsettings.mdx +++ b/docs/components/organizationsettings.mdx @@ -4,7 +4,7 @@ title: "OrganizationSettings" ## Fields -| Field | Type | Required | Description | Example | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `id` | *str* | ✅ | ID of the organization the settings belong to | org_2dHFtVWx2n56w6HkM0000000000 | -| `is_filtered_model_catalog_enabled` | *bool* | ✅ | When true, `GET /api/v1/models` called with one of the organization's API keys returns only the models that key can use (the `/api/v1/models/user` catalog), and the signed-in dashboard shows the same list. Anonymous requests always receive the public catalog. | true | \ No newline at end of file +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `id` | *str* | ✅ | ID of the organization the settings belong to | org_2dHFtVWx2n56w6HkM0000000000 | +| `is_filtered_model_catalog_enabled` | *bool* | ✅ | When true, the signed-in dashboard lists only the models the organization can use. `GET /api/v1/models` called with an API key always returns only the models that key can use, whatever this setting says; anonymous requests receive the public catalog. | true | \ No newline at end of file diff --git a/docs/components/updateguardrailrequest.mdx b/docs/components/updateguardrailrequest.mdx index 3ee3318d..68129c7d 100644 --- a/docs/components/updateguardrailrequest.mdx +++ b/docs/components/updateguardrailrequest.mdx @@ -17,6 +17,7 @@ title: "UpdateGuardrailRequest" | `enable_free_model_publication` | *OptionalNullable[bool]* | ➖ | Whether this guardrail allows free endpoints that publish prompts. | false | | `enable_free_model_training` | *OptionalNullable[bool]* | ➖ | Whether this guardrail allows free endpoints that train on request data. | true | | `enable_paid_model_training` | *OptionalNullable[bool]* | ➖ | Whether this guardrail allows paid endpoints that train on request data. | true | +| `enforce_first_party_harness_models` | *OptionalNullable[bool]* | ➖ | Whether coding harnesses list only their vendor's own models: Codex lists OpenAI models and Claude Code and Claude Desktop list Anthropic models. Affects only the model list those harnesses request from GET /models; a model the client names directly is still routed. Any true across the workspace default, member, and API key guardrails applies. | true | | ~~`enforce_zdr`~~ | *OptionalNullable[bool]* | ➖ | : warning: ** DEPRECATED **: This will be removed in a future release, please migrate away from it as soon as possible.

Deprecated. Use enforce_zdr_anthropic, enforce_zdr_openai, enforce_zdr_google, enforce_zdr_xai, and enforce_zdr_other instead. When provided, its value is copied into any of those per-provider fields that are not explicitly specified on the request. | true | | `enforce_zdr_anthropic` | *OptionalNullable[bool]* | ➖ | Whether to enforce zero data retention for Anthropic models. Falls back to enforce_zdr when not provided. | true | | `enforce_zdr_google` | *OptionalNullable[bool]* | ➖ | Whether to enforce zero data retention for Google models. Falls back to enforce_zdr when not provided. | true | diff --git a/docs/components/updateorganizationsettingsrequest.mdx b/docs/components/updateorganizationsettingsrequest.mdx index 81d79079..d830f073 100644 --- a/docs/components/updateorganizationsettingsrequest.mdx +++ b/docs/components/updateorganizationsettingsrequest.mdx @@ -4,6 +4,6 @@ title: "UpdateOrganizationSettingsRequest" ## Fields -| Field | Type | Required | Description | Example | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `is_filtered_model_catalog_enabled` | *bool* | ✅ | When true, `GET /api/v1/models` called with one of the organization's API keys returns only the models that key can use (the `/api/v1/models/user` catalog), and the signed-in dashboard shows the same list. Anonymous requests always receive the public catalog. | true | \ No newline at end of file +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `is_filtered_model_catalog_enabled` | *bool* | ✅ | When true, the signed-in dashboard lists only the models the organization can use. `GET /api/v1/models` called with an API key always returns only the models that key can use, whatever this setting says; anonymous requests receive the public catalog. | true | \ No newline at end of file diff --git a/docs/sdks/guardrails/README.mdx b/docs/sdks/guardrails/README.mdx index 9bf93fdb..e0bdd51a 100644 --- a/docs/sdks/guardrails/README.mdx +++ b/docs/sdks/guardrails/README.mdx @@ -126,6 +126,7 @@ with OpenRouter( | `enable_free_model_publication` | *OptionalNullable[bool]* | ➖ | Whether this guardrail allows free endpoints that publish prompts. | false | | `enable_free_model_training` | *OptionalNullable[bool]* | ➖ | Whether this guardrail allows free endpoints that train on request data. | true | | `enable_paid_model_training` | *OptionalNullable[bool]* | ➖ | Whether this guardrail allows paid endpoints that train on request data. | true | +| `enforce_first_party_harness_models` | *OptionalNullable[bool]* | ➖ | Whether coding harnesses list only their vendor's own models: Codex lists OpenAI models and Claude Code and Claude Desktop list Anthropic models. Affects only the model list those harnesses request from GET /models; a model the client names directly is still routed. Any true across the workspace default, member, and API key guardrails applies. | false | | `enforce_zdr` | *OptionalNullable[bool]* | ➖ | : warning: ** DEPRECATED **: This will be removed in a future release, please migrate away from it as soon as possible.

Deprecated. Use enforce_zdr_anthropic, enforce_zdr_openai, enforce_zdr_google, enforce_zdr_xai, and enforce_zdr_other instead. When provided, its value is copied into any of those per-provider fields that are not explicitly specified on the request. | false | | `enforce_zdr_anthropic` | *OptionalNullable[bool]* | ➖ | Whether to enforce zero data retention for Anthropic models. Falls back to enforce_zdr when not provided. | false | | `enforce_zdr_google` | *OptionalNullable[bool]* | ➖ | Whether to enforce zero data retention for Google models. Falls back to enforce_zdr when not provided. | false | @@ -296,6 +297,7 @@ with OpenRouter( | `enable_free_model_publication` | *OptionalNullable[bool]* | ➖ | Whether this guardrail allows free endpoints that publish prompts. | false | | `enable_free_model_training` | *OptionalNullable[bool]* | ➖ | Whether this guardrail allows free endpoints that train on request data. | true | | `enable_paid_model_training` | *OptionalNullable[bool]* | ➖ | Whether this guardrail allows paid endpoints that train on request data. | true | +| `enforce_first_party_harness_models` | *OptionalNullable[bool]* | ➖ | Whether coding harnesses list only their vendor's own models: Codex lists OpenAI models and Claude Code and Claude Desktop list Anthropic models. Affects only the model list those harnesses request from GET /models; a model the client names directly is still routed. Any true across the workspace default, member, and API key guardrails applies. | true | | `enforce_zdr` | *OptionalNullable[bool]* | ➖ | : warning: ** DEPRECATED **: This will be removed in a future release, please migrate away from it as soon as possible.

Deprecated. Use enforce_zdr_anthropic, enforce_zdr_openai, enforce_zdr_google, enforce_zdr_xai, and enforce_zdr_other instead. When provided, its value is copied into any of those per-provider fields that are not explicitly specified on the request. | true | | `enforce_zdr_anthropic` | *OptionalNullable[bool]* | ➖ | Whether to enforce zero data retention for Anthropic models. Falls back to enforce_zdr when not provided. | true | | `enforce_zdr_google` | *OptionalNullable[bool]* | ➖ | Whether to enforce zero data retention for Google models. Falls back to enforce_zdr when not provided. | true | diff --git a/docs/sdks/models/README.mdx b/docs/sdks/models/README.mdx index 39351b89..a10e813c 100644 --- a/docs/sdks/models/README.mdx +++ b/docs/sdks/models/README.mdx @@ -137,7 +137,12 @@ with OpenRouter( | Error Type | Status Code | Content Type | | -------------------------------------- | -------------------------------------- | -------------------------------------- | | errors.BadRequestResponseError | 400 | application/json | +| errors.UnauthorizedResponseError | 401 | application/json | | errors.ForbiddenResponseError | 403 | application/json | +| errors.NotFoundResponseError | 404 | application/json | +| errors.RequestTimeoutResponseError | 408 | application/json | +| errors.ConflictResponseError | 409 | application/json | +| errors.TooManyRequestsResponseError | 429 | application/json | | errors.InternalServerResponseError | 500 | application/json | | errors.ServiceUnavailableResponseError | 503 | application/json | | errors.OpenRouterDefaultError | 4XX, 5XX | \*/\* | @@ -243,6 +248,9 @@ with OpenRouter( | errors.UnauthorizedResponseError | 401 | application/json | | errors.ForbiddenResponseError | 403 | application/json | | errors.NotFoundResponseError | 404 | application/json | +| errors.RequestTimeoutResponseError | 408 | application/json | +| errors.ConflictResponseError | 409 | application/json | +| errors.TooManyRequestsResponseError | 429 | application/json | | errors.InternalServerResponseError | 500 | application/json | | errors.ServiceUnavailableResponseError | 503 | application/json | | errors.OpenRouterDefaultError | 4XX, 5XX | \*/\* | \ No newline at end of file diff --git a/docs/sdks/organization/README.mdx b/docs/sdks/organization/README.mdx index dbc3a028..b2289731 100644 --- a/docs/sdks/organization/README.mdx +++ b/docs/sdks/organization/README.mdx @@ -140,13 +140,13 @@ with OpenRouter( ### Parameters -| Parameter | Type | Required | Description | Example | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `is_filtered_model_catalog_enabled` | *bool* | ✅ | When true, `GET /api/v1/models` called with one of the organization's API keys returns only the models that key can use (the `/api/v1/models/user` catalog), and the signed-in dashboard shows the same list. Anonymous requests always receive the public catalog. | true | -| `http_referer` | *Optional[str]* | ➖ | 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]* | ➖ | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| | -| `x_open_router_categories` | *Optional[str]* | ➖ | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| | -| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.mdx) | ➖ | Configuration to override the default retry behavior of the client. | | +| Parameter | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `is_filtered_model_catalog_enabled` | *bool* | ✅ | When true, the signed-in dashboard lists only the models the organization can use. `GET /api/v1/models` called with an API key always returns only the models that key can use, whatever this setting says; anonymous requests receive the public catalog. | true | +| `http_referer` | *Optional[str]* | ➖ | 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]* | ➖ | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| | +| `x_open_router_categories` | *Optional[str]* | ➖ | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.mdx) | ➖ | Configuration to override the default retry behavior of the client. | | ### Response diff --git a/pyproject.toml b/pyproject.toml index d51a2b9e..bf446a40 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "openrouter" -version = "1.3.91" +version = "1.3.92" 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 b2b71ec7..27fe009e 100644 --- a/src/openrouter/_version.py +++ b/src/openrouter/_version.py @@ -3,10 +3,10 @@ import importlib.metadata __title__: str = "openrouter" -__version__: str = "1.3.91" +__version__: str = "1.3.92" __openapi_doc_version__: str = "1.0.0" __gen_version__: str = "2.914.0" -__user_agent__: str = "speakeasy-sdk/python 1.3.91 2.914.0 1.0.0 openrouter" +__user_agent__: str = "speakeasy-sdk/python 1.3.92 2.914.0 1.0.0 openrouter" try: if __package__ is not None: diff --git a/src/openrouter/components/createguardrailrequest.py b/src/openrouter/components/createguardrailrequest.py index 8185633a..60395247 100644 --- a/src/openrouter/components/createguardrailrequest.py +++ b/src/openrouter/components/createguardrailrequest.py @@ -48,6 +48,8 @@ class CreateGuardrailRequestTypedDict(TypedDict): r"""Whether this guardrail allows free endpoints that train on request data.""" enable_paid_model_training: NotRequired[Nullable[bool]] r"""Whether this guardrail allows paid endpoints that train on request data.""" + enforce_first_party_harness_models: NotRequired[Nullable[bool]] + r"""Whether coding harnesses list only their vendor's own models: Codex lists OpenAI models and Claude Code and Claude Desktop list Anthropic models. Affects only the model list those harnesses request from GET /models; a model the client names directly is still routed. Any true across the workspace default, member, and API key guardrails applies.""" enforce_zdr: NotRequired[Nullable[bool]] r"""Deprecated. Use enforce_zdr_anthropic, enforce_zdr_openai, enforce_zdr_google, enforce_zdr_xai, and enforce_zdr_other instead. When provided, its value is copied into any of those per-provider fields that are not explicitly specified on the request.""" enforce_zdr_anthropic: NotRequired[Nullable[bool]] @@ -113,6 +115,9 @@ class CreateGuardrailRequest(BaseModel): enable_paid_model_training: OptionalNullable[bool] = UNSET r"""Whether this guardrail allows paid endpoints that train on request data.""" + enforce_first_party_harness_models: OptionalNullable[bool] = UNSET + r"""Whether coding harnesses list only their vendor's own models: Codex lists OpenAI models and Claude Code and Claude Desktop list Anthropic models. Affects only the model list those harnesses request from GET /models; a model the client names directly is still routed. Any true across the workspace default, member, and API key guardrails applies.""" + enforce_zdr: Annotated[ OptionalNullable[bool], pydantic.Field( @@ -169,6 +174,7 @@ def serialize_model(self, handler): "enable_free_model_publication", "enable_free_model_training", "enable_paid_model_training", + "enforce_first_party_harness_models", "enforce_zdr", "enforce_zdr_anthropic", "enforce_zdr_google", @@ -196,6 +202,7 @@ def serialize_model(self, handler): "enable_free_model_publication", "enable_free_model_training", "enable_paid_model_training", + "enforce_first_party_harness_models", "enforce_zdr", "enforce_zdr_anthropic", "enforce_zdr_google", diff --git a/src/openrouter/components/guardrail.py b/src/openrouter/components/guardrail.py index 1e8c4fd2..0591b4f4 100644 --- a/src/openrouter/components/guardrail.py +++ b/src/openrouter/components/guardrail.py @@ -56,6 +56,8 @@ class GuardrailTypedDict(TypedDict): r"""Whether this guardrail allows free endpoints that train on request data.""" enable_paid_model_training: NotRequired[Nullable[bool]] r"""Whether this guardrail allows paid endpoints that train on request data.""" + enforce_first_party_harness_models: NotRequired[Nullable[bool]] + r"""Whether coding harnesses list only their vendor's own models: Codex lists OpenAI models and Claude Code and Claude Desktop list Anthropic models. Affects only the model list those harnesses request from GET /models; a model the client names directly is still routed. Any true across the workspace default, member, and API key guardrails applies.""" enforce_zdr: NotRequired[Nullable[bool]] r"""Deprecated. Use enforce_zdr_anthropic, enforce_zdr_openai, enforce_zdr_google, enforce_zdr_xai, and enforce_zdr_other instead. When provided, its value is copied into any of those per-provider fields that are not explicitly specified on the request.""" enforce_zdr_anthropic: NotRequired[Nullable[bool]] @@ -129,6 +131,9 @@ class Guardrail(BaseModel): enable_paid_model_training: OptionalNullable[bool] = UNSET r"""Whether this guardrail allows paid endpoints that train on request data.""" + enforce_first_party_harness_models: OptionalNullable[bool] = UNSET + r"""Whether coding harnesses list only their vendor's own models: Codex lists OpenAI models and Claude Code and Claude Desktop list Anthropic models. Affects only the model list those harnesses request from GET /models; a model the client names directly is still routed. Any true across the workspace default, member, and API key guardrails applies.""" + enforce_zdr: Annotated[ OptionalNullable[bool], pydantic.Field( @@ -182,6 +187,7 @@ def serialize_model(self, handler): "enable_free_model_publication", "enable_free_model_training", "enable_paid_model_training", + "enforce_first_party_harness_models", "enforce_zdr", "enforce_zdr_anthropic", "enforce_zdr_google", @@ -208,6 +214,7 @@ def serialize_model(self, handler): "enable_free_model_publication", "enable_free_model_training", "enable_paid_model_training", + "enforce_first_party_harness_models", "enforce_zdr", "enforce_zdr_anthropic", "enforce_zdr_google", diff --git a/src/openrouter/components/organizationsettings.py b/src/openrouter/components/organizationsettings.py index aa9d74f6..30c1a195 100644 --- a/src/openrouter/components/organizationsettings.py +++ b/src/openrouter/components/organizationsettings.py @@ -9,7 +9,7 @@ class OrganizationSettingsTypedDict(TypedDict): id: str r"""ID of the organization the settings belong to""" is_filtered_model_catalog_enabled: bool - r"""When true, `GET /api/v1/models` called with one of the organization's API keys returns only the models that key can use (the `/api/v1/models/user` catalog), and the signed-in dashboard shows the same list. Anonymous requests always receive the public catalog.""" + r"""When true, the signed-in dashboard lists only the models the organization can use. `GET /api/v1/models` called with an API key always returns only the models that key can use, whatever this setting says; anonymous requests receive the public catalog.""" class OrganizationSettings(BaseModel): @@ -17,4 +17,4 @@ class OrganizationSettings(BaseModel): r"""ID of the organization the settings belong to""" is_filtered_model_catalog_enabled: bool - r"""When true, `GET /api/v1/models` called with one of the organization's API keys returns only the models that key can use (the `/api/v1/models/user` catalog), and the signed-in dashboard shows the same list. Anonymous requests always receive the public catalog.""" + r"""When true, the signed-in dashboard lists only the models the organization can use. `GET /api/v1/models` called with an API key always returns only the models that key can use, whatever this setting says; anonymous requests receive the public catalog.""" diff --git a/src/openrouter/components/updateguardrailrequest.py b/src/openrouter/components/updateguardrailrequest.py index 3304e76e..f3e803ca 100644 --- a/src/openrouter/components/updateguardrailrequest.py +++ b/src/openrouter/components/updateguardrailrequest.py @@ -46,6 +46,8 @@ class UpdateGuardrailRequestTypedDict(TypedDict): r"""Whether this guardrail allows free endpoints that train on request data.""" enable_paid_model_training: NotRequired[Nullable[bool]] r"""Whether this guardrail allows paid endpoints that train on request data.""" + enforce_first_party_harness_models: NotRequired[Nullable[bool]] + r"""Whether coding harnesses list only their vendor's own models: Codex lists OpenAI models and Claude Code and Claude Desktop list Anthropic models. Affects only the model list those harnesses request from GET /models; a model the client names directly is still routed. Any true across the workspace default, member, and API key guardrails applies.""" enforce_zdr: NotRequired[Nullable[bool]] r"""Deprecated. Use enforce_zdr_anthropic, enforce_zdr_openai, enforce_zdr_google, enforce_zdr_xai, and enforce_zdr_other instead. When provided, its value is copied into any of those per-provider fields that are not explicitly specified on the request.""" enforce_zdr_anthropic: NotRequired[Nullable[bool]] @@ -108,6 +110,9 @@ class UpdateGuardrailRequest(BaseModel): enable_paid_model_training: OptionalNullable[bool] = UNSET r"""Whether this guardrail allows paid endpoints that train on request data.""" + enforce_first_party_harness_models: OptionalNullable[bool] = UNSET + r"""Whether coding harnesses list only their vendor's own models: Codex lists OpenAI models and Claude Code and Claude Desktop list Anthropic models. Affects only the model list those harnesses request from GET /models; a model the client names directly is still routed. Any true across the workspace default, member, and API key guardrails applies.""" + enforce_zdr: Annotated[ OptionalNullable[bool], pydantic.Field( @@ -164,6 +169,7 @@ def serialize_model(self, handler): "enable_free_model_publication", "enable_free_model_training", "enable_paid_model_training", + "enforce_first_party_harness_models", "enforce_zdr", "enforce_zdr_anthropic", "enforce_zdr_google", @@ -191,6 +197,7 @@ def serialize_model(self, handler): "enable_free_model_publication", "enable_free_model_training", "enable_paid_model_training", + "enforce_first_party_harness_models", "enforce_zdr", "enforce_zdr_anthropic", "enforce_zdr_google", diff --git a/src/openrouter/components/updateorganizationsettingsrequest.py b/src/openrouter/components/updateorganizationsettingsrequest.py index ee583b9b..add97f9d 100644 --- a/src/openrouter/components/updateorganizationsettingsrequest.py +++ b/src/openrouter/components/updateorganizationsettingsrequest.py @@ -7,9 +7,9 @@ class UpdateOrganizationSettingsRequestTypedDict(TypedDict): is_filtered_model_catalog_enabled: bool - r"""When true, `GET /api/v1/models` called with one of the organization's API keys returns only the models that key can use (the `/api/v1/models/user` catalog), and the signed-in dashboard shows the same list. Anonymous requests always receive the public catalog.""" + r"""When true, the signed-in dashboard lists only the models the organization can use. `GET /api/v1/models` called with an API key always returns only the models that key can use, whatever this setting says; anonymous requests receive the public catalog.""" class UpdateOrganizationSettingsRequest(BaseModel): is_filtered_model_catalog_enabled: bool - r"""When true, `GET /api/v1/models` called with one of the organization's API keys returns only the models that key can use (the `/api/v1/models/user` catalog), and the signed-in dashboard shows the same list. Anonymous requests always receive the public catalog.""" + r"""When true, the signed-in dashboard lists only the models the organization can use. `GET /api/v1/models` called with an API key always returns only the models that key can use, whatever this setting says; anonymous requests receive the public catalog.""" diff --git a/src/openrouter/guardrails.py b/src/openrouter/guardrails.py index fac2d71e..3718d5c7 100644 --- a/src/openrouter/guardrails.py +++ b/src/openrouter/guardrails.py @@ -390,6 +390,7 @@ def create( enable_free_model_publication: OptionalNullable[bool] = UNSET, enable_free_model_training: OptionalNullable[bool] = UNSET, enable_paid_model_training: OptionalNullable[bool] = UNSET, + enforce_first_party_harness_models: OptionalNullable[bool] = UNSET, enforce_zdr: OptionalNullable[bool] = UNSET, enforce_zdr_anthropic: OptionalNullable[bool] = UNSET, enforce_zdr_google: OptionalNullable[bool] = UNSET, @@ -430,6 +431,7 @@ def create( :param enable_free_model_publication: Whether this guardrail allows free endpoints that publish prompts. :param enable_free_model_training: Whether this guardrail allows free endpoints that train on request data. :param enable_paid_model_training: Whether this guardrail allows paid endpoints that train on request data. + :param enforce_first_party_harness_models: Whether coding harnesses list only their vendor's own models: Codex lists OpenAI models and Claude Code and Claude Desktop list Anthropic models. Affects only the model list those harnesses request from GET /models; a model the client names directly is still routed. Any true across the workspace default, member, and API key guardrails applies. :param enforce_zdr: Deprecated. Use enforce_zdr_anthropic, enforce_zdr_openai, enforce_zdr_google, enforce_zdr_xai, and enforce_zdr_other instead. When provided, its value is copied into any of those per-provider fields that are not explicitly specified on the request. :param enforce_zdr_anthropic: Whether to enforce zero data retention for Anthropic models. Falls back to enforce_zdr when not provided. :param enforce_zdr_google: Whether to enforce zero data retention for Google models. Falls back to enforce_zdr when not provided. @@ -486,6 +488,7 @@ def create( enable_free_model_publication=enable_free_model_publication, enable_free_model_training=enable_free_model_training, enable_paid_model_training=enable_paid_model_training, + enforce_first_party_harness_models=enforce_first_party_harness_models, enforce_zdr=enforce_zdr, enforce_zdr_anthropic=enforce_zdr_anthropic, enforce_zdr_google=enforce_zdr_google, @@ -630,6 +633,7 @@ async def create_async( enable_free_model_publication: OptionalNullable[bool] = UNSET, enable_free_model_training: OptionalNullable[bool] = UNSET, enable_paid_model_training: OptionalNullable[bool] = UNSET, + enforce_first_party_harness_models: OptionalNullable[bool] = UNSET, enforce_zdr: OptionalNullable[bool] = UNSET, enforce_zdr_anthropic: OptionalNullable[bool] = UNSET, enforce_zdr_google: OptionalNullable[bool] = UNSET, @@ -670,6 +674,7 @@ async def create_async( :param enable_free_model_publication: Whether this guardrail allows free endpoints that publish prompts. :param enable_free_model_training: Whether this guardrail allows free endpoints that train on request data. :param enable_paid_model_training: Whether this guardrail allows paid endpoints that train on request data. + :param enforce_first_party_harness_models: Whether coding harnesses list only their vendor's own models: Codex lists OpenAI models and Claude Code and Claude Desktop list Anthropic models. Affects only the model list those harnesses request from GET /models; a model the client names directly is still routed. Any true across the workspace default, member, and API key guardrails applies. :param enforce_zdr: Deprecated. Use enforce_zdr_anthropic, enforce_zdr_openai, enforce_zdr_google, enforce_zdr_xai, and enforce_zdr_other instead. When provided, its value is copied into any of those per-provider fields that are not explicitly specified on the request. :param enforce_zdr_anthropic: Whether to enforce zero data retention for Anthropic models. Falls back to enforce_zdr when not provided. :param enforce_zdr_google: Whether to enforce zero data retention for Google models. Falls back to enforce_zdr when not provided. @@ -726,6 +731,7 @@ async def create_async( enable_free_model_publication=enable_free_model_publication, enable_free_model_training=enable_free_model_training, enable_paid_model_training=enable_paid_model_training, + enforce_first_party_harness_models=enforce_first_party_harness_models, enforce_zdr=enforce_zdr, enforce_zdr_anthropic=enforce_zdr_anthropic, enforce_zdr_google=enforce_zdr_google, @@ -1402,6 +1408,7 @@ def update( enable_free_model_publication: OptionalNullable[bool] = UNSET, enable_free_model_training: OptionalNullable[bool] = UNSET, enable_paid_model_training: OptionalNullable[bool] = UNSET, + enforce_first_party_harness_models: OptionalNullable[bool] = UNSET, enforce_zdr: OptionalNullable[bool] = UNSET, enforce_zdr_anthropic: OptionalNullable[bool] = UNSET, enforce_zdr_google: OptionalNullable[bool] = UNSET, @@ -1442,6 +1449,7 @@ def update( :param enable_free_model_publication: Whether this guardrail allows free endpoints that publish prompts. :param enable_free_model_training: Whether this guardrail allows free endpoints that train on request data. :param enable_paid_model_training: Whether this guardrail allows paid endpoints that train on request data. + :param enforce_first_party_harness_models: Whether coding harnesses list only their vendor's own models: Codex lists OpenAI models and Claude Code and Claude Desktop list Anthropic models. Affects only the model list those harnesses request from GET /models; a model the client names directly is still routed. Any true across the workspace default, member, and API key guardrails applies. :param enforce_zdr: Deprecated. Use enforce_zdr_anthropic, enforce_zdr_openai, enforce_zdr_google, enforce_zdr_xai, and enforce_zdr_other instead. When provided, its value is copied into any of those per-provider fields that are not explicitly specified on the request. :param enforce_zdr_anthropic: Whether to enforce zero data retention for Anthropic models. Falls back to enforce_zdr when not provided. :param enforce_zdr_google: Whether to enforce zero data retention for Google models. Falls back to enforce_zdr when not provided. @@ -1499,6 +1507,7 @@ def update( enable_free_model_publication=enable_free_model_publication, enable_free_model_training=enable_free_model_training, enable_paid_model_training=enable_paid_model_training, + enforce_first_party_harness_models=enforce_first_party_harness_models, enforce_zdr=enforce_zdr, enforce_zdr_anthropic=enforce_zdr_anthropic, enforce_zdr_google=enforce_zdr_google, @@ -1652,6 +1661,7 @@ async def update_async( enable_free_model_publication: OptionalNullable[bool] = UNSET, enable_free_model_training: OptionalNullable[bool] = UNSET, enable_paid_model_training: OptionalNullable[bool] = UNSET, + enforce_first_party_harness_models: OptionalNullable[bool] = UNSET, enforce_zdr: OptionalNullable[bool] = UNSET, enforce_zdr_anthropic: OptionalNullable[bool] = UNSET, enforce_zdr_google: OptionalNullable[bool] = UNSET, @@ -1692,6 +1702,7 @@ async def update_async( :param enable_free_model_publication: Whether this guardrail allows free endpoints that publish prompts. :param enable_free_model_training: Whether this guardrail allows free endpoints that train on request data. :param enable_paid_model_training: Whether this guardrail allows paid endpoints that train on request data. + :param enforce_first_party_harness_models: Whether coding harnesses list only their vendor's own models: Codex lists OpenAI models and Claude Code and Claude Desktop list Anthropic models. Affects only the model list those harnesses request from GET /models; a model the client names directly is still routed. Any true across the workspace default, member, and API key guardrails applies. :param enforce_zdr: Deprecated. Use enforce_zdr_anthropic, enforce_zdr_openai, enforce_zdr_google, enforce_zdr_xai, and enforce_zdr_other instead. When provided, its value is copied into any of those per-provider fields that are not explicitly specified on the request. :param enforce_zdr_anthropic: Whether to enforce zero data retention for Anthropic models. Falls back to enforce_zdr when not provided. :param enforce_zdr_google: Whether to enforce zero data retention for Google models. Falls back to enforce_zdr when not provided. @@ -1749,6 +1760,7 @@ async def update_async( enable_free_model_publication=enable_free_model_publication, enable_free_model_training=enable_free_model_training, enable_paid_model_training=enable_paid_model_training, + enforce_first_party_harness_models=enforce_first_party_harness_models, enforce_zdr=enforce_zdr, enforce_zdr_anthropic=enforce_zdr_anthropic, enforce_zdr_google=enforce_zdr_google, diff --git a/src/openrouter/models_.py b/src/openrouter/models_.py index f880d869..0e5a4161 100644 --- a/src/openrouter/models_.py +++ b/src/openrouter/models_.py @@ -519,11 +519,36 @@ def next_func() -> Optional[operations.GetModelsResponse]: 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, "403", "application/json"): response_data = unmarshal_json_response( errors.ForbiddenResponseErrorData, http_res ) raise errors.ForbiddenResponseError(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, "408", "application/json"): + response_data = unmarshal_json_response( + errors.RequestTimeoutResponseErrorData, http_res + ) + raise errors.RequestTimeoutResponseError(response_data, http_res) + if utils.match_response(http_res, "409", "application/json"): + response_data = unmarshal_json_response( + errors.ConflictResponseErrorData, http_res + ) + raise errors.ConflictResponseError(response_data, http_res) + if utils.match_response(http_res, "429", "application/json"): + response_data = unmarshal_json_response( + errors.TooManyRequestsResponseErrorData, http_res + ) + raise errors.TooManyRequestsResponseError(response_data, http_res) if utils.match_response(http_res, "500", "application/json"): response_data = unmarshal_json_response( errors.InternalServerResponseErrorData, http_res @@ -794,11 +819,36 @@ async def empty_result(): 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, "403", "application/json"): response_data = unmarshal_json_response( errors.ForbiddenResponseErrorData, http_res ) raise errors.ForbiddenResponseError(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, "408", "application/json"): + response_data = unmarshal_json_response( + errors.RequestTimeoutResponseErrorData, http_res + ) + raise errors.RequestTimeoutResponseError(response_data, http_res) + if utils.match_response(http_res, "409", "application/json"): + response_data = unmarshal_json_response( + errors.ConflictResponseErrorData, http_res + ) + raise errors.ConflictResponseError(response_data, http_res) + if utils.match_response(http_res, "429", "application/json"): + response_data = unmarshal_json_response( + errors.TooManyRequestsResponseErrorData, http_res + ) + raise errors.TooManyRequestsResponseError(response_data, http_res) if utils.match_response(http_res, "500", "application/json"): response_data = unmarshal_json_response( errors.InternalServerResponseErrorData, http_res @@ -1236,6 +1286,21 @@ def next_func() -> Optional[operations.ListModelsUserResponse]: errors.NotFoundResponseErrorData, http_res ) raise errors.NotFoundResponseError(response_data, http_res) + if utils.match_response(http_res, "408", "application/json"): + response_data = unmarshal_json_response( + errors.RequestTimeoutResponseErrorData, http_res + ) + raise errors.RequestTimeoutResponseError(response_data, http_res) + if utils.match_response(http_res, "409", "application/json"): + response_data = unmarshal_json_response( + errors.ConflictResponseErrorData, http_res + ) + raise errors.ConflictResponseError(response_data, http_res) + if utils.match_response(http_res, "429", "application/json"): + response_data = unmarshal_json_response( + errors.TooManyRequestsResponseErrorData, http_res + ) + raise errors.TooManyRequestsResponseError(response_data, http_res) if utils.match_response(http_res, "500", "application/json"): response_data = unmarshal_json_response( errors.InternalServerResponseErrorData, http_res @@ -1424,6 +1489,21 @@ async def empty_result(): errors.NotFoundResponseErrorData, http_res ) raise errors.NotFoundResponseError(response_data, http_res) + if utils.match_response(http_res, "408", "application/json"): + response_data = unmarshal_json_response( + errors.RequestTimeoutResponseErrorData, http_res + ) + raise errors.RequestTimeoutResponseError(response_data, http_res) + if utils.match_response(http_res, "409", "application/json"): + response_data = unmarshal_json_response( + errors.ConflictResponseErrorData, http_res + ) + raise errors.ConflictResponseError(response_data, http_res) + if utils.match_response(http_res, "429", "application/json"): + response_data = unmarshal_json_response( + errors.TooManyRequestsResponseErrorData, http_res + ) + raise errors.TooManyRequestsResponseError(response_data, http_res) if utils.match_response(http_res, "500", "application/json"): response_data = unmarshal_json_response( errors.InternalServerResponseErrorData, http_res diff --git a/src/openrouter/organization.py b/src/openrouter/organization.py index ed6685a2..22860228 100644 --- a/src/openrouter/organization.py +++ b/src/openrouter/organization.py @@ -634,7 +634,7 @@ def update_settings( Update the settings of the organization associated with the authenticated management key. [Management key](/docs/guides/overview/auth/management-api-keys) required. - :param is_filtered_model_catalog_enabled: When true, `GET /api/v1/models` called with one of the organization's API keys returns only the models that key can use (the `/api/v1/models/user` catalog), and the signed-in dashboard shows the same list. Anonymous requests always receive the public catalog. + :param is_filtered_model_catalog_enabled: When true, the signed-in dashboard lists only the models the organization can use. `GET /api/v1/models` called with an API key always returns only the models that key can use, whatever this setting says; anonymous requests receive the public catalog. :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. @@ -783,7 +783,7 @@ async def update_settings_async( Update the settings of the organization associated with the authenticated management key. [Management key](/docs/guides/overview/auth/management-api-keys) required. - :param is_filtered_model_catalog_enabled: When true, `GET /api/v1/models` called with one of the organization's API keys returns only the models that key can use (the `/api/v1/models/user` catalog), and the signed-in dashboard shows the same list. Anonymous requests always receive the public catalog. + :param is_filtered_model_catalog_enabled: When true, the signed-in dashboard lists only the models the organization can use. `GET /api/v1/models` called with an API key always returns only the models that key can use, whatever this setting says; anonymous requests receive the public catalog. :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. diff --git a/uv.lock b/uv.lock index d14e6974..8f4d921b 100644 --- a/uv.lock +++ b/uv.lock @@ -231,7 +231,7 @@ wheels = [ [[package]] name = "openrouter" -version = "1.3.91" +version = "1.3.92" source = { editable = "." } dependencies = [ { name = "httpcore" },