diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index 81219d48..1f3bee59 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: 8d66cbc3cfd2e7025585831c83519a81 + docChecksum: ce5f8d5996391569ed1a685721f7046c docVersion: 1.0.0 speakeasyVersion: 1.787.0 generationVersion: 2.914.0 - releaseVersion: 1.1.119 - configChecksum: 40337010eb197dfba7772005df02c9d3 + releaseVersion: 1.1.120 + configChecksum: 8357d85eb9f5bac84298c0e227a6b984 repoURL: https://github.com/OpenRouterTeam/python-sdk.git installationURL: https://github.com/OpenRouterTeam/python-sdk.git published: true persistentEdits: - generation_id: d3759cae-8d5c-4171-a425-8c2a349d4e4a - pristine_commit_hash: bd2f9eb6bd8e1c4f8e629fbdb730f131bcc7aa36 - pristine_tree_hash: 26f19ced7941d9fff89a5d2453ac7c57d596fb3e + generation_id: 879edd87-e0e3-485b-83f6-9b19a99c9830 + pristine_commit_hash: fb33c12a82fe10127a23bb2621acecac1dfeab9f + pristine_tree_hash: 32c744f7564cd3e8014d258525cef3e97c325ef9 features: python: acceptHeaders: 3.0.0 @@ -6266,8 +6266,8 @@ trackedFiles: pristine_git_object: 9ec01bf61826e888c544e698af19baaa8c51980a docs/operations/createkeysrequestbody.mdx: id: 77bb49febf62 - last_write_checksum: sha1:4281640ddfeb7fadc0b40c1e5798f0f33f5c4536 - pristine_git_object: 03d2690cbbd53496929b2ccd879640e95a6e70ed + last_write_checksum: sha1:67822e93facc2b4956ca1c78a69dc67937886bda + pristine_git_object: b07f924076b7262a3de54f708f12cd0ee87eab5b docs/operations/createkeysresponse.mdx: id: 08e825fab080 last_write_checksum: sha1:268c49a74956884d1e3b3495fdf6ee6c7383e323 @@ -6516,6 +6516,10 @@ trackedFiles: id: 64162c7ece40 last_write_checksum: sha1:ab0c02f32ff39de1f3da9604432708878cc932c6 pristine_git_object: 2642f99d77ceb5007b1b863028d73c07e48dac67 + docs/operations/external.mdx: + id: d59b0279f5bf + last_write_checksum: sha1:94be7eccbfd2658d1f5f7672977b572273a366cf + pristine_git_object: a9bac3e77677e7cc51aafe2a58c3d60f4e3cf15d docs/operations/filter_.mdx: id: 79b9c7c02d3b last_write_checksum: sha1:11626213ca5220d3013304af7d34d8b7c0c79f85 @@ -7438,8 +7442,8 @@ trackedFiles: pristine_git_object: c1634706646332455817340f5891b4b5c9c6d16c docs/sdks/apikeys/README.mdx: id: 27fcaae1c346 - last_write_checksum: sha1:7a69e05e81dcd98f56875f9e98e9af5047ec3a32 - pristine_git_object: b1ed0d38565e444b87a7c64c4675a888c00ea9ea + last_write_checksum: sha1:3b8ddf3e038f2dc75d60c4936f270543950020a2 + pristine_git_object: 05cb8497207bd506ac4d84c53a5977e110114806 docs/sdks/benchmarks/README.mdx: id: 5b483a6770ba last_write_checksum: sha1:885b70fcbd2be60f51a2f58e133fd6452eb21600 @@ -7554,8 +7558,8 @@ trackedFiles: pristine_git_object: 3e38f1a929f7d6b1d6de74604aa87e3d8f010544 pyproject.toml: id: 5d07e7d72637 - last_write_checksum: sha1:56fe290e2eb62505ca606a14870c251c65b397b4 - pristine_git_object: c888733edb984115721da78647439d9a37fcfe0c + last_write_checksum: sha1:2765676781474b4d3b41566bb0c4ea7d587b226b + pristine_git_object: 8a72681c7b253c3d9226466f122b38d098eed74d scripts/prepare_readme.py: id: e0c5957a6035 last_write_checksum: sha1:77f44b60b98bc126557ec27391f91dfba764bb54 @@ -7582,16 +7586,16 @@ trackedFiles: pristine_git_object: 86713cfea633e09d33b3d4e65281071fe20e6137 src/openrouter/_version.py: id: d8d15ad6c586 - last_write_checksum: sha1:809e487597022e0800957114a0be4210261a4b0b - pristine_git_object: 18a2bfe926c463cdfe989b6b03d57298076e5291 + last_write_checksum: sha1:18c1a65cc4fadc02dba9801979adfe6f0078b39b + pristine_git_object: 649f736d9a9057d5204c17e6ac936b088de48beb src/openrouter/analytics.py: id: cb406b5aaabb last_write_checksum: sha1:1e0004d8d1d5d797e2b54cd1cabeb7f9489d08e9 pristine_git_object: 9587309db4d5e25a00131a48788456139c25e4c0 src/openrouter/api_keys.py: id: 876fac88fff6 - last_write_checksum: sha1:ea783a6c3f2fa4478fbccf41bb8eddf8c638cff6 - pristine_git_object: 9f12e9eb70e531679af1f3d64c081aec4b961853 + last_write_checksum: sha1:5c198eef830a56d6030573a073bf0e349a0d8289 + pristine_git_object: 94dd64726b491afb7913f00e8c90d94ef58d1115 src/openrouter/basesdk.py: id: c5733c5a1e12 last_write_checksum: sha1:65769ff2cb5473f85b364c6213a0ddc8c68644ea @@ -10286,8 +10290,8 @@ trackedFiles: pristine_git_object: 5c553b76ab24d9eaef51c3bf6d85aa74391e335e src/openrouter/operations/__init__.py: id: 9afcea1e7161 - last_write_checksum: sha1:1c4c409bc631b080407fcf9977af36eedab52a87 - pristine_git_object: b76c802abec1ef1bb8fa2625772374243d75f281 + last_write_checksum: sha1:c7fed411d14dc37465fc61bf1fe78f9ba3b18ce2 + pristine_git_object: ceac9dee376e4d8c832b3ff4a6cc6e3bec7eb5f4 src/openrouter/operations/bulkaddworkspacemembers.py: id: e0ed56117619 last_write_checksum: sha1:5c44eb0d40fdece3ac084615f6c6082be4cf1d5a @@ -10346,8 +10350,8 @@ trackedFiles: pristine_git_object: 8216a656ec1412a034878e257bd9de9e94fa8da1 src/openrouter/operations/createkeys.py: id: 64ad31fdaa6c - last_write_checksum: sha1:146edc8153a6ee74f1b8a6cdbd2a6c91733f11d8 - pristine_git_object: 510645f76bbdcc2a8f754f5527d14ae3d0a5a16c + last_write_checksum: sha1:92e122bf7ca252e6cc1f4200cbcd6ded9a0d35a7 + pristine_git_object: 2fe95efbdbba0908f586d84148fad57b3b8a498e src/openrouter/operations/createoauthtoken.py: id: 02e1c061780d last_write_checksum: sha1:006884cfeeecfede1434f194460b7189cae89de1 @@ -12713,5 +12717,4 @@ examples: examplesVersion: 1.0.2 releaseNotes: | ## Python SDK Changes: - * `open_router.o_auth.list_oauth_jwks()`: **Added** - * `open_router.o_auth.create_oauth_token()`: **Added** + * `open_router.api_keys.create()`: `request.external` **Added** diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml index 81ab11dd..4d6dfb98 100644 --- a/.speakeasy/gen.yaml +++ b/.speakeasy/gen.yaml @@ -36,7 +36,7 @@ generation: documentation: mintlify preApplyUnionDiscriminators: true python: - version: 1.1.119 + version: 1.1.120 additionalDependencies: dev: {} main: {} diff --git a/.speakeasy/out.openapi.yaml b/.speakeasy/out.openapi.yaml index ca3868cf..fa830f16 100644 --- a/.speakeasy/out.openapi.yaml +++ b/.speakeasy/out.openapi.yaml @@ -34696,7 +34696,7 @@ paths: - 'API Keys' x-speakeasy-name-override: 'list' post: - description: 'Create a new API key for the authenticated user. The plaintext `key` is returned only in this response. Treat it as a write-only, sensitive value; it cannot be retrieved later. Authenticate with a [management key](/docs/guides/overview/auth/management-api-keys), or with a Connect client secret.' + description: 'Create a new API key for the authenticated user. The plaintext `key` is returned only in this response. Treat it as a write-only, sensitive value; it cannot be retrieved later. Authenticate with a [management key](/docs/guides/overview/auth/management-api-keys). The optional `external` object associates the key with a partner-defined user and lookup key.' operationId: 'createKeys' requestBody: content: @@ -34729,6 +34729,23 @@ paths: type: - 'string' - 'null' + external: + description: 'Optional partner-defined identity associated with the created API key.' + properties: + api_key: + description: 'Optional partner-supplied API key with a minimum length of 32 characters and sufficient entropy. Stored as a SHA-256 hash and never returned.' + maxLength: 512 + minLength: 32 + type: 'string' + user: + description: 'Partner''s end-user identifier for attribution.' + example: 'partner-user-123' + maxLength: 512 + minLength: 1 + type: 'string' + required: + - 'user' + type: 'object' include_byok_in_limit: description: 'Whether to include BYOK usage in the limit' example: true @@ -35053,7 +35070,7 @@ paths: - $ref: "#/components/parameters/AppCategories" /keys/{hash}: delete: - description: 'Delete an existing API key. Authenticate with a [management key](/docs/guides/overview/auth/management-api-keys), or with a Connect client secret. A client secret reaches only the keys that same client created; any other key responds as if it does not exist.' + description: 'Delete an existing API key. Authenticate with a [management key](/docs/guides/overview/auth/management-api-keys).' operationId: 'deleteKeys' parameters: - description: 'The hash identifier of the API key to delete' @@ -35403,7 +35420,7 @@ paths: - 'API Keys' x-speakeasy-name-override: 'get' patch: - description: 'Update an existing API key. Authenticate with a [management key](/docs/guides/overview/auth/management-api-keys), or with a Connect client secret. A client secret reaches only the keys that same client created; any other key responds as if it does not exist.' + description: 'Update an existing API key. Authenticate with a [management key](/docs/guides/overview/auth/management-api-keys).' operationId: 'updateKeys' parameters: - description: 'The hash identifier of the API key to update' diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock index c5d81444..0d6766f6 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:548d52c5c213dc69da9a5075de144d2d234ae4a761b51515b9fb197d414e23b7 - sourceBlobDigest: sha256:6f8a3a2bf9e6a014f1c0fe5e85415d4ba182afa6a3fadd5224480bf80f10bc51 + sourceRevisionDigest: sha256:390305318c4533d383dc9c88de415c2542a7caf6ac9bc01db93781a99a394bdc + sourceBlobDigest: sha256:7c6b932ad65bf10271c6384063c1d55781f75fefa9780aff01f32c3155162943 tags: - latest - 1.0.0 @@ -11,10 +11,10 @@ targets: open-router: source: OpenRouter API sourceNamespace: open-router-chat-completions-api - sourceRevisionDigest: sha256:548d52c5c213dc69da9a5075de144d2d234ae4a761b51515b9fb197d414e23b7 - sourceBlobDigest: sha256:6f8a3a2bf9e6a014f1c0fe5e85415d4ba182afa6a3fadd5224480bf80f10bc51 + sourceRevisionDigest: sha256:390305318c4533d383dc9c88de415c2542a7caf6ac9bc01db93781a99a394bdc + sourceBlobDigest: sha256:7c6b932ad65bf10271c6384063c1d55781f75fefa9780aff01f32c3155162943 codeSamplesNamespace: open-router-python-code-samples - codeSamplesRevisionDigest: sha256:b1caf408f8f4dbb6d7b94fb09bb1cc248275f7f241a09146682d20efe1e299b6 + codeSamplesRevisionDigest: sha256:40c3ec0b19f0e0bf2aa8d48616aafb27e782f71ffef33a5ffc765829ff9bf46e workflow: workflowVersion: 1.0.0 speakeasyVersion: 1.787.0 diff --git a/RELEASES.md b/RELEASES.md index c876fe36..9078e941 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1979,4 +1979,14 @@ Based on: ### Generated - [python v1.1.119] . ### Releases -- [PyPI v1.1.119] https://pypi.org/project/openrouter/1.1.119 - . \ No newline at end of file +- [PyPI v1.1.119] https://pypi.org/project/openrouter/1.1.119 - . + +## 2026-09-03 01:22:00 +### Changes +Based on: +- OpenAPI Doc +- Speakeasy CLI 1.787.0 (2.914.0) https://github.com/speakeasy-api/speakeasy +### Generated +- [python v1.1.120] . +### Releases +- [PyPI v1.1.120] https://pypi.org/project/openrouter/1.1.120 - . \ No newline at end of file diff --git a/docs/operations/createkeysrequestbody.mdx b/docs/operations/createkeysrequestbody.mdx index 03d2690c..b07f9240 100644 --- a/docs/operations/createkeysrequestbody.mdx +++ b/docs/operations/createkeysrequestbody.mdx @@ -8,6 +8,7 @@ title: "CreateKeysRequestBody" | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `creator_user_id` | *OptionalNullable[str]* | :heavy_minus_sign: | Optional user ID of the key creator. Only meaningful for organization-owned keys where a specific member is creating the key. | user_2dHFtVWx2n56w6HkM0000000000 | | `expires_at` | [date](https://docs.python.org/3/library/datetime.html#date-objects) | :heavy_minus_sign: | Optional ISO 8601 UTC expiration timestamp. Must include seconds (YYYY-MM-DDTHH:MM:SSZ; fractional seconds allowed); minute-precision timestamps are rejected. | 2027-12-31T23:59:59Z | +| `external` | [Optional[operations.External]](../operations/external.mdx) | :heavy_minus_sign: | Optional partner-defined identity associated with the created API key. | | | `include_byok_in_limit` | *Optional[bool]* | :heavy_minus_sign: | Whether to include BYOK usage in the limit | true | | `limit` | *OptionalNullable[float]* | :heavy_minus_sign: | Optional spending limit for the API key in USD | 50 | | `limit_reset` | [OptionalNullable[operations.CreateKeysLimitReset]](../operations/createkeyslimitreset.mdx) | :heavy_minus_sign: | Type of limit reset for the API key (daily, weekly, monthly, or null for no reset). Resets happen automatically at midnight UTC, and weeks are Monday through Sunday. | monthly | diff --git a/docs/operations/external.mdx b/docs/operations/external.mdx new file mode 100644 index 00000000..a9bac3e7 --- /dev/null +++ b/docs/operations/external.mdx @@ -0,0 +1,13 @@ +--- +title: "External" +--- + +Optional partner-defined identity associated with the created API key. + + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | +| `api_key` | *Optional[str]* | :heavy_minus_sign: | Optional partner-supplied API key with a minimum length of 32 characters and sufficient entropy. Stored as a SHA-256 hash and never returned. | | +| `user` | *str* | :heavy_check_mark: | Partner's end-user identifier for attribution. | partner-user-123 | \ No newline at end of file diff --git a/docs/sdks/apikeys/README.mdx b/docs/sdks/apikeys/README.mdx index b1ed0d38..05cb8497 100644 --- a/docs/sdks/apikeys/README.mdx +++ b/docs/sdks/apikeys/README.mdx @@ -115,7 +115,7 @@ with OpenRouter( ## create -Create a new API key for the authenticated user. The plaintext `key` is returned only in this response. Treat it as a write-only, sensitive value; it cannot be retrieved later. Authenticate with a [management key](/docs/guides/overview/auth/management-api-keys), or with a Connect client secret. +Create a new API key for the authenticated user. The plaintext `key` is returned only in this response. Treat it as a write-only, sensitive value; it cannot be retrieved later. Authenticate with a [management key](/docs/guides/overview/auth/management-api-keys). The optional `external` object associates the key with a partner-defined user and lookup key. ### Example Usage @@ -149,6 +149,7 @@ with OpenRouter( | `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.
| | | `creator_user_id` | *OptionalNullable[str]* | :heavy_minus_sign: | Optional user ID of the key creator. Only meaningful for organization-owned keys where a specific member is creating the key. | user_2dHFtVWx2n56w6HkM0000000000 | | `expires_at` | [date](https://docs.python.org/3/library/datetime.html#date-objects) | :heavy_minus_sign: | Optional ISO 8601 UTC expiration timestamp. Must include seconds (YYYY-MM-DDTHH:MM:SSZ; fractional seconds allowed); minute-precision timestamps are rejected. | 2027-12-31T23:59:59Z | +| `external` | [Optional[operations.External]](../../operations/external.mdx) | :heavy_minus_sign: | Optional partner-defined identity associated with the created API key. | | | `include_byok_in_limit` | *Optional[bool]* | :heavy_minus_sign: | Whether to include BYOK usage in the limit | true | | `limit` | *OptionalNullable[float]* | :heavy_minus_sign: | Optional spending limit for the API key in USD | 50 | | `limit_reset` | [OptionalNullable[operations.CreateKeysLimitReset]](../../operations/createkeyslimitreset.mdx) | :heavy_minus_sign: | Type of limit reset for the API key (daily, weekly, monthly, or null for no reset). Resets happen automatically at midnight UTC, and weeks are Monday through Sunday. | monthly | @@ -172,7 +173,7 @@ with OpenRouter( ## delete -Delete an existing API key. Authenticate with a [management key](/docs/guides/overview/auth/management-api-keys), or with a Connect client secret. A client secret reaches only the keys that same client created; any other key responds as if it does not exist. +Delete an existing API key. Authenticate with a [management key](/docs/guides/overview/auth/management-api-keys). ### Example Usage @@ -270,7 +271,7 @@ with OpenRouter( ## update -Update an existing API key. Authenticate with a [management key](/docs/guides/overview/auth/management-api-keys), or with a Connect client secret. A client secret reaches only the keys that same client created; any other key responds as if it does not exist. +Update an existing API key. Authenticate with a [management key](/docs/guides/overview/auth/management-api-keys). ### Example Usage diff --git a/pyproject.toml b/pyproject.toml index c888733e..8a72681c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "openrouter" -version = "1.1.119" +version = "1.1.120" 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 18a2bfe9..649f736d 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.119" +__version__: str = "1.1.120" __openapi_doc_version__: str = "1.0.0" __gen_version__: str = "2.914.0" -__user_agent__: str = "speakeasy-sdk/python 1.1.119 2.914.0 1.0.0 openrouter" +__user_agent__: str = "speakeasy-sdk/python 1.1.120 2.914.0 1.0.0 openrouter" try: if __package__ is not None: diff --git a/src/openrouter/api_keys.py b/src/openrouter/api_keys.py index 9f12e9eb..94dd6472 100644 --- a/src/openrouter/api_keys.py +++ b/src/openrouter/api_keys.py @@ -7,7 +7,7 @@ from openrouter.types import 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 class APIKeys(BaseSDK): @@ -540,6 +540,9 @@ def create( x_open_router_categories: Optional[str] = None, creator_user_id: OptionalNullable[str] = UNSET, expires_at: OptionalNullable[datetime] = UNSET, + external: Optional[ + Union[operations.External, operations.ExternalTypedDict] + ] = None, include_byok_in_limit: Optional[bool] = None, limit: OptionalNullable[float] = UNSET, limit_reset: OptionalNullable[operations.CreateKeysLimitReset] = UNSET, @@ -551,7 +554,7 @@ def create( ) -> operations.CreateKeysResponse: r"""Create a new API key - Create a new API key for the authenticated user. The plaintext `key` is returned only in this response. Treat it as a write-only, sensitive value; it cannot be retrieved later. Authenticate with a [management key](/docs/guides/overview/auth/management-api-keys), or with a Connect client secret. + Create a new API key for the authenticated user. The plaintext `key` is returned only in this response. Treat it as a write-only, sensitive value; it cannot be retrieved later. Authenticate with a [management key](/docs/guides/overview/auth/management-api-keys). The optional `external` object associates the key with a partner-defined user and lookup key. :param name: Name for the new API key :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings. @@ -563,6 +566,7 @@ def create( :param creator_user_id: Optional user ID of the key creator. Only meaningful for organization-owned keys where a specific member is creating the key. :param expires_at: Optional ISO 8601 UTC expiration timestamp. Must include seconds (YYYY-MM-DDTHH:MM:SSZ; fractional seconds allowed); minute-precision timestamps are rejected. + :param external: Optional partner-defined identity associated with the created API key. :param include_byok_in_limit: Whether to include BYOK usage in the limit :param limit: Optional spending limit for the API key in USD :param limit_reset: Type of limit reset for the API key (daily, weekly, monthly, or null for no reset). Resets happen automatically at midnight UTC, and weeks are Monday through Sunday. @@ -589,6 +593,9 @@ def create( request_body=operations.CreateKeysRequestBody( creator_user_id=creator_user_id, expires_at=expires_at, + external=utils.get_pydantic_model( + external, Optional[operations.External] + ), include_byok_in_limit=include_byok_in_limit, limit=limit, limit_reset=limit_reset, @@ -705,6 +712,9 @@ async def create_async( x_open_router_categories: Optional[str] = None, creator_user_id: OptionalNullable[str] = UNSET, expires_at: OptionalNullable[datetime] = UNSET, + external: Optional[ + Union[operations.External, operations.ExternalTypedDict] + ] = None, include_byok_in_limit: Optional[bool] = None, limit: OptionalNullable[float] = UNSET, limit_reset: OptionalNullable[operations.CreateKeysLimitReset] = UNSET, @@ -716,7 +726,7 @@ async def create_async( ) -> operations.CreateKeysResponse: r"""Create a new API key - Create a new API key for the authenticated user. The plaintext `key` is returned only in this response. Treat it as a write-only, sensitive value; it cannot be retrieved later. Authenticate with a [management key](/docs/guides/overview/auth/management-api-keys), or with a Connect client secret. + Create a new API key for the authenticated user. The plaintext `key` is returned only in this response. Treat it as a write-only, sensitive value; it cannot be retrieved later. Authenticate with a [management key](/docs/guides/overview/auth/management-api-keys). The optional `external` object associates the key with a partner-defined user and lookup key. :param name: Name for the new API key :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings. @@ -728,6 +738,7 @@ async def create_async( :param creator_user_id: Optional user ID of the key creator. Only meaningful for organization-owned keys where a specific member is creating the key. :param expires_at: Optional ISO 8601 UTC expiration timestamp. Must include seconds (YYYY-MM-DDTHH:MM:SSZ; fractional seconds allowed); minute-precision timestamps are rejected. + :param external: Optional partner-defined identity associated with the created API key. :param include_byok_in_limit: Whether to include BYOK usage in the limit :param limit: Optional spending limit for the API key in USD :param limit_reset: Type of limit reset for the API key (daily, weekly, monthly, or null for no reset). Resets happen automatically at midnight UTC, and weeks are Monday through Sunday. @@ -754,6 +765,9 @@ async def create_async( request_body=operations.CreateKeysRequestBody( creator_user_id=creator_user_id, expires_at=expires_at, + external=utils.get_pydantic_model( + external, Optional[operations.External] + ), include_byok_in_limit=include_byok_in_limit, limit=limit, limit_reset=limit_reset, @@ -875,7 +889,7 @@ def delete( ) -> operations.DeleteKeysResponse: r"""Delete an API key - Delete an existing API key. Authenticate with a [management key](/docs/guides/overview/auth/management-api-keys), or with a Connect client secret. A client secret reaches only the keys that same client created; any other key responds as if it does not exist. + Delete an existing API key. Authenticate with a [management key](/docs/guides/overview/auth/management-api-keys). :param hash: The hash identifier of the API key to delete :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings. @@ -1008,7 +1022,7 @@ async def delete_async( ) -> operations.DeleteKeysResponse: r"""Delete an API key - Delete an existing API key. Authenticate with a [management key](/docs/guides/overview/auth/management-api-keys), or with a Connect client secret. A client secret reaches only the keys that same client created; any other key responds as if it does not exist. + Delete an existing API key. Authenticate with a [management key](/docs/guides/overview/auth/management-api-keys). :param hash: The hash identifier of the API key to delete :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings. @@ -1412,7 +1426,7 @@ def update( ) -> operations.UpdateKeysResponse: r"""Update an API key - Update an existing API key. Authenticate with a [management key](/docs/guides/overview/auth/management-api-keys), or with a Connect client secret. A client secret reaches only the keys that same client created; any other key responds as if it does not exist. + Update an existing API key. Authenticate with a [management key](/docs/guides/overview/auth/management-api-keys). :param hash: The hash identifier of the API key to update :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings. @@ -1574,7 +1588,7 @@ async def update_async( ) -> operations.UpdateKeysResponse: r"""Update an API key - Update an existing API key. Authenticate with a [management key](/docs/guides/overview/auth/management-api-keys), or with a Connect client secret. A client secret reaches only the keys that same client created; any other key responds as if it does not exist. + Update an existing API key. Authenticate with a [management key](/docs/guides/overview/auth/management-api-keys). :param hash: The hash identifier of the API key to update :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings. diff --git a/src/openrouter/operations/__init__.py b/src/openrouter/operations/__init__.py index b76c802a..ceac9dee 100644 --- a/src/openrouter/operations/__init__.py +++ b/src/openrouter/operations/__init__.py @@ -148,6 +148,8 @@ CreateKeysRequestTypedDict, CreateKeysResponse, CreateKeysResponseTypedDict, + External, + ExternalTypedDict, ) from .createoauthtoken import ( CreateOauthTokenGlobals, @@ -1082,6 +1084,8 @@ "ExchangeAuthCodeForAPIKeyRequestTypedDict", "ExchangeAuthCodeForAPIKeyResponse", "ExchangeAuthCodeForAPIKeyResponseTypedDict", + "External", + "ExternalTypedDict", "Filter", "FilterTypedDict", "GetAnalyticsMetaData", @@ -1624,6 +1628,8 @@ "CreateKeysRequestTypedDict": ".createkeys", "CreateKeysResponse": ".createkeys", "CreateKeysResponseTypedDict": ".createkeys", + "External": ".createkeys", + "ExternalTypedDict": ".createkeys", "CreateOauthTokenGlobals": ".createoauthtoken", "CreateOauthTokenGlobalsTypedDict": ".createoauthtoken", "CreateOauthTokenRequest": ".createoauthtoken", diff --git a/src/openrouter/operations/createkeys.py b/src/openrouter/operations/createkeys.py index 510645f7..2fe95efb 100644 --- a/src/openrouter/operations/createkeys.py +++ b/src/openrouter/operations/createkeys.py @@ -81,6 +81,41 @@ def serialize_model(self, handler): return m +class ExternalTypedDict(TypedDict): + r"""Optional partner-defined identity associated with the created API key.""" + + user: str + r"""Partner's end-user identifier for attribution.""" + api_key: NotRequired[str] + r"""Optional partner-supplied API key with a minimum length of 32 characters and sufficient entropy. Stored as a SHA-256 hash and never returned.""" + + +class External(BaseModel): + r"""Optional partner-defined identity associated with the created API key.""" + + user: str + r"""Partner's end-user identifier for attribution.""" + + api_key: Optional[str] = None + r"""Optional partner-supplied API key with a minimum length of 32 characters and sufficient entropy. Stored as a SHA-256 hash and never returned.""" + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set(["api_key"]) + 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 + + CreateKeysLimitReset = Union[ Literal[ "daily", @@ -99,6 +134,8 @@ class CreateKeysRequestBodyTypedDict(TypedDict): r"""Optional user ID of the key creator. Only meaningful for organization-owned keys where a specific member is creating the key.""" expires_at: NotRequired[Nullable[datetime]] r"""Optional ISO 8601 UTC expiration timestamp. Must include seconds (YYYY-MM-DDTHH:MM:SSZ; fractional seconds allowed); minute-precision timestamps are rejected.""" + external: NotRequired[ExternalTypedDict] + r"""Optional partner-defined identity associated with the created API key.""" include_byok_in_limit: NotRequired[bool] r"""Whether to include BYOK usage in the limit""" limit: NotRequired[Nullable[float]] @@ -119,6 +156,9 @@ class CreateKeysRequestBody(BaseModel): expires_at: OptionalNullable[datetime] = UNSET r"""Optional ISO 8601 UTC expiration timestamp. Must include seconds (YYYY-MM-DDTHH:MM:SSZ; fractional seconds allowed); minute-precision timestamps are rejected.""" + external: Optional[External] = None + r"""Optional partner-defined identity associated with the created API key.""" + include_byok_in_limit: Optional[bool] = None r"""Whether to include BYOK usage in the limit""" @@ -137,6 +177,7 @@ def serialize_model(self, handler): [ "creator_user_id", "expires_at", + "external", "include_byok_in_limit", "limit", "limit_reset", diff --git a/uv.lock b/uv.lock index 0466cb73..1d92efba 100644 --- a/uv.lock +++ b/uv.lock @@ -213,7 +213,7 @@ wheels = [ [[package]] name = "openrouter" -version = "1.1.119" +version = "1.1.120" source = { editable = "." } dependencies = [ { name = "httpcore" },