From f41873760de098429f1fe513ca581649ac881246 Mon Sep 17 00:00:00 2001 From: speakeasybot Date: Wed, 30 Sep 2026 18:09:35 +0000 Subject: [PATCH 1/3] ## Python SDK Changes: * `open_router.end_users.list()`: **Added** * `open_router.end_users.create()`: **Added** * `open_router.end_users.delete()`: **Added** * `open_router.end_users.get()`: **Added** * `open_router.end_users.update()`: **Added** --- .speakeasy/gen.lock | 235 ++- .speakeasy/gen.yaml | 2 +- .speakeasy/out.openapi.yaml | 517 ++++++ .speakeasy/workflow.lock | 10 +- RELEASES.md | 12 +- docs/components/createenduserrequest.mdx | 9 + docs/components/enduser.mdx | 12 + docs/components/enduserresponse.mdx | 9 + docs/components/listendusersresponse.mdx | 10 + docs/components/updateenduserrequest.mdx | 9 + docs/operations/createenduserglobals.mdx | 11 + docs/operations/createenduserrequest.mdx | 12 + docs/operations/deleteenduserglobals.mdx | 11 + docs/operations/deleteenduserrequest.mdx | 12 + docs/operations/getenduserglobals.mdx | 11 + docs/operations/getenduserrequest.mdx | 12 + docs/operations/listendusersglobals.mdx | 11 + docs/operations/listendusersrequest.mdx | 15 + docs/operations/listendusersresponse.mdx | 9 + docs/operations/updateenduserglobals.mdx | 11 + docs/operations/updateenduserrequest.mdx | 13 + docs/sdks/endusers/README.mdx | 263 +++ pyproject.toml | 2 +- src/openrouter/_version.py | 4 +- src/openrouter/components/__init__.py | 34 + .../components/createenduserrequest.py | 15 + src/openrouter/components/enduser.py | 31 + src/openrouter/components/enduserresponse.py | 14 + .../components/listendusersresponse.py | 20 + .../components/updateenduserrequest.py | 15 + src/openrouter/end_users.py | 1485 +++++++++++++++++ src/openrouter/operations/__init__.py | 76 + src/openrouter/operations/createenduser.py | 148 ++ src/openrouter/operations/deleteenduser.py | 144 ++ src/openrouter/operations/getenduser.py | 144 ++ src/openrouter/operations/listendusers.py | 202 +++ src/openrouter/operations/updateenduser.py | 160 ++ src/openrouter/sdk.py | 4 + uv.lock | 2 +- 39 files changed, 3688 insertions(+), 28 deletions(-) create mode 100644 docs/components/createenduserrequest.mdx create mode 100644 docs/components/enduser.mdx create mode 100644 docs/components/enduserresponse.mdx create mode 100644 docs/components/listendusersresponse.mdx create mode 100644 docs/components/updateenduserrequest.mdx create mode 100644 docs/operations/createenduserglobals.mdx create mode 100644 docs/operations/createenduserrequest.mdx create mode 100644 docs/operations/deleteenduserglobals.mdx create mode 100644 docs/operations/deleteenduserrequest.mdx create mode 100644 docs/operations/getenduserglobals.mdx create mode 100644 docs/operations/getenduserrequest.mdx create mode 100644 docs/operations/listendusersglobals.mdx create mode 100644 docs/operations/listendusersrequest.mdx create mode 100644 docs/operations/listendusersresponse.mdx create mode 100644 docs/operations/updateenduserglobals.mdx create mode 100644 docs/operations/updateenduserrequest.mdx create mode 100644 docs/sdks/endusers/README.mdx create mode 100644 src/openrouter/components/createenduserrequest.py create mode 100644 src/openrouter/components/enduser.py create mode 100644 src/openrouter/components/enduserresponse.py create mode 100644 src/openrouter/components/listendusersresponse.py create mode 100644 src/openrouter/components/updateenduserrequest.py create mode 100644 src/openrouter/end_users.py create mode 100644 src/openrouter/operations/createenduser.py create mode 100644 src/openrouter/operations/deleteenduser.py create mode 100644 src/openrouter/operations/getenduser.py create mode 100644 src/openrouter/operations/listendusers.py create mode 100644 src/openrouter/operations/updateenduser.py diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index 4fb05ff0..b1a01fe2 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: 306a28fc04894c25c30af5e7808a58d0 + docChecksum: 06126264462b689c48f88ac1ba852482 docVersion: 1.0.0 speakeasyVersion: 1.787.0 generationVersion: 2.914.0 - releaseVersion: 1.3.11 - configChecksum: 0f0bda5d04d5e179f70e2638860fdc17 + releaseVersion: 1.3.12 + configChecksum: 430f30d84c52858dd1d454425cf8d9bd repoURL: https://github.com/OpenRouterTeam/python-sdk.git installationURL: https://github.com/OpenRouterTeam/python-sdk.git published: true persistentEdits: - generation_id: 1fe47a9d-4490-40b4-9e39-d066c917b993 - pristine_commit_hash: 01475e09a2c374c65dca25b46efd0abbc65ed20e - pristine_tree_hash: cd9a0d53e416af933de7ada3f974c61635bbb8f9 + generation_id: f3ffde77-5c91-4a84-8f4b-dd20dfdbcf28 + pristine_commit_hash: 8a68f1738fdf2914835207adddd522d41f5d8758 + pristine_tree_hash: 430b4f53eaba7550bc82e9d1e83a38675cda5671 features: python: acceptHeaders: 3.0.0 @@ -2490,6 +2490,10 @@ trackedFiles: id: 73f247dc0e33 last_write_checksum: sha1:30861793800a2851105bfa5b9406520320129f06 pristine_git_object: 18d6a80440f1dc702eae3a3917a53a2def1fca72 + docs/components/createenduserrequest.mdx: + id: e82c759c8be2 + last_write_checksum: sha1:a91e5f439be4943f1d2012ae04c52d129fb95326 + pristine_git_object: daaedee3ad25549548155e792662282505bd099e docs/components/createguardrailrequest.mdx: id: c1a768f054c0 last_write_checksum: sha1:d32d712d132971b34f6d81d28ff45d22d919f4ac @@ -2910,6 +2914,14 @@ trackedFiles: id: 5e4fa96c840d last_write_checksum: sha1:4d2ccb7fc0d20c8a0b72db3a55a8228169891b6a pristine_git_object: 72c5b4fb8441c2a4337dc9906fa81b01bb92f126 + docs/components/enduser.mdx: + id: a690fe4da7fa + last_write_checksum: sha1:67fae70e3bac87655ed152cf389b9f21b3211e83 + pristine_git_object: 331116736dabd659c02f4aa9fa23835017b2d043 + docs/components/enduserresponse.mdx: + id: e340b96bf3b4 + last_write_checksum: sha1:83fbaf74d163f2498007397e3c37f06db8086c0a + pristine_git_object: 4b605db127b9e50464b42c8e9650b84f6b36c101 docs/components/enumcapability.mdx: id: 33c7a0f315d5 last_write_checksum: sha1:08338d742893cb3966cd12cee49a5d80748b3d63 @@ -4114,6 +4126,10 @@ trackedFiles: id: 1aeb90d09e63 last_write_checksum: sha1:b5d3535ac0e30e1ac1f4f44f3dd17fc8d07aeaff pristine_git_object: 2df1189da38f979e3ce2bc39c62eb5b79aec3060 + docs/components/listendusersresponse.mdx: + id: 83bf1b522c37 + last_write_checksum: sha1:0c009062976d9dd800d8e592b85a5796398fd456 + pristine_git_object: b95cdd819dc02959feefbabf9371ea961ef47175 docs/components/listguardrailsresponse.mdx: id: ba740952e77b last_write_checksum: sha1:5a75d264da7e1074ccb5529bf06dce343db5a8da @@ -7474,6 +7490,10 @@ trackedFiles: id: 9b4490c340b4 last_write_checksum: sha1:5ca8cef381afdb1c03ce16df023738e163dab13b pristine_git_object: cad8d3e654b3c1c1b570f80f73f1173a72e17db2 + docs/components/updateenduserrequest.mdx: + id: 42e918f01861 + last_write_checksum: sha1:cfc96316a62b5df60663ccec298ad23b33c93876 + pristine_git_object: 72a1c5ade4703a295e533f6e12733f464a21ff65 docs/components/updateguardrailrequest.mdx: id: 450912b18db6 last_write_checksum: sha1:f0e2aaf8ecb96d8b53a02768ec260472490963cd @@ -8166,6 +8186,14 @@ trackedFiles: id: 4f9205ca2bb9 last_write_checksum: sha1:8156e256387b12cc08a5a92f9e9332ec2b35a2af pristine_git_object: 1218cf960cbc2285120cb399596e0bc73b44aa9f + docs/operations/createenduserglobals.mdx: + id: edb6cb53a590 + last_write_checksum: sha1:1ab6518cccfb2d8d62fc3378bb5ccf19f07c8530 + pristine_git_object: e420bbbee81a1d9392f5249150e4d6823b7bc360 + docs/operations/createenduserrequest.mdx: + id: 36afb465cbb1 + last_write_checksum: sha1:dd01057e3c354507a3880814b7e12937ad1c143d + pristine_git_object: 9448f50842deb5c7b5dcf4c2d5f022a3d43d20d8 docs/operations/createguardrailglobals.mdx: id: ce6e792df15c last_write_checksum: sha1:6542508eed5dbd74bf6812b8cc0cc9cfd3157d06 @@ -8382,6 +8410,14 @@ trackedFiles: id: 5f6e81896314 last_write_checksum: sha1:2927f00b81e9bccb0d19ce46dfd3fdc23475eb4c pristine_git_object: 7fdac9559bfcf2860dbd533e0d3ae974ab26f193 + docs/operations/deleteenduserglobals.mdx: + id: 17d644a655d0 + last_write_checksum: sha1:7512fbfbf270ee7c9cff32787917d8a81d05c357 + pristine_git_object: 07094eff6bf7c06a69ac4181ae000c55a9482dc0 + docs/operations/deleteenduserrequest.mdx: + id: 5033dca978c6 + last_write_checksum: sha1:f3dc8c200980f206035f781db10d4be74d20f6d6 + pristine_git_object: ad4cacf77e1ba21cfd6b82ba325b2c4a4d72937c docs/operations/deletefileglobals.mdx: id: b95c49d91968 last_write_checksum: sha1:1eaa5442be2df2702baf53f5dddedd40ce930fcc @@ -8674,6 +8710,14 @@ trackedFiles: id: 8b6709d01b8b last_write_checksum: sha1:85dde6bb90c5686384d11484601d8859c0b8fa7e pristine_git_object: f8fbad096ce3725d56f12a5d6a3ea32a79891c6b + docs/operations/getenduserglobals.mdx: + id: e8c43375935a + last_write_checksum: sha1:254de886f9c34765bce15368509f1fba2b68d5ae + pristine_git_object: 9ec66ba16256d22f51356ac3ac0b2195a454f121 + docs/operations/getenduserrequest.mdx: + id: 19de93747569 + last_write_checksum: sha1:32592160c298cedac111022380ba02f466c88a3d + pristine_git_object: 501f7d298695ab0b7eb5ee0aaeffa35dadf6f67c docs/operations/getfilemetadataglobals.mdx: id: e4f16f1ce98e last_write_checksum: sha1:f736518bdebac4aa8c9caf9071e0670885bd83b3 @@ -9018,6 +9062,18 @@ trackedFiles: id: f8d0c52ac714 last_write_checksum: sha1:259ccd67ebae39f4ab027939482c3e337ba37312 pristine_git_object: 31012e2cfce20ea33c3e4781f8db798e4f33d867 + docs/operations/listendusersglobals.mdx: + id: caf708972b97 + last_write_checksum: sha1:80d09dcebee7f87784859d0462b2efc3d26fbe95 + pristine_git_object: 3b3fecc1e477bafabe93350df4bec82cad5ebfe3 + docs/operations/listendusersrequest.mdx: + id: 07d0f1292e9c + last_write_checksum: sha1:00fec8ef51775ba9dd3e6c7f8b5f2215e7fd7fd6 + pristine_git_object: 0dd8516dbc7e33fa177e38f8624978643aa7bba7 + docs/operations/listendusersresponse.mdx: + id: c939c37b2eb5 + last_write_checksum: sha1:b27d7044dd883f11fcd98d67b234120b13364c81 + pristine_git_object: d8ac526225636dfdccb8536fd7cd4e1ad4a4afde docs/operations/listfilesglobals.mdx: id: 1674db6bdeb2 last_write_checksum: sha1:e387e5f7c8e60d7b5f47d84ccdc1132cc0efc45a @@ -9554,6 +9610,14 @@ trackedFiles: id: cef280b21ee9 last_write_checksum: sha1:86da6f664f74203209024032ed6c1281cb696757 pristine_git_object: 546e001df35e2526f0e8bd92a6836be03cf7cc5d + docs/operations/updateenduserglobals.mdx: + id: 3eab3e5b90d4 + last_write_checksum: sha1:6f49a3b900d1c12830bda99251ae36da5df7db72 + pristine_git_object: de504b1ca4a7fee6076860abdc5c200708c68b0f + docs/operations/updateenduserrequest.mdx: + id: c61c7edc838b + last_write_checksum: sha1:bc25b716e93ea4ef8700cf514634924acb715d84 + pristine_git_object: 62ae0d75e3ef262ff61485f53f9e103316097953 docs/operations/updateguardrailglobals.mdx: id: e3ce035d5a7c last_write_checksum: sha1:6dc745162b36e08d38d6ea094282f5c45baf71f2 @@ -9750,6 +9814,10 @@ trackedFiles: id: 62dfac9f7b71 last_write_checksum: sha1:db7ed18401bcd4afa7382a9793c9ccafb5220497 pristine_git_object: f8cebc2061d7428904766956be45ca70e5519be4 + docs/sdks/endusers/README.mdx: + id: ba369f05185b + last_write_checksum: sha1:0eec372c7e75bea130e1cdd6405348dc49bfd938 + pristine_git_object: 8f4e8760a7ad9ced8023005e8b304f316c116273 docs/sdks/files/README.mdx: id: 1a0c257e330c last_write_checksum: sha1:f92d58e58f2ac2048faa8b4420c1663a48e20959 @@ -9844,8 +9912,8 @@ trackedFiles: pristine_git_object: 3e38f1a929f7d6b1d6de74604aa87e3d8f010544 pyproject.toml: id: 5d07e7d72637 - last_write_checksum: sha1:4c6f741c1dc0c7ee0b5c4eb7fbf2b91f2074c7e1 - pristine_git_object: 71e0d5366924fbdaa1cc1cb59ca12cdbe9954ead + last_write_checksum: sha1:77b1dff1c45babf177022bcf35a8c487b665c222 + pristine_git_object: 6372f8443a83c42b0d33f301659afd5af6dc4ade scripts/prepare_readme.py: id: e0c5957a6035 last_write_checksum: sha1:77f44b60b98bc126557ec27391f91dfba764bb54 @@ -9872,8 +9940,8 @@ trackedFiles: pristine_git_object: 86713cfea633e09d33b3d4e65281071fe20e6137 src/openrouter/_version.py: id: d8d15ad6c586 - last_write_checksum: sha1:f23a121ae5533716c91802589bb6645760fc98a0 - pristine_git_object: 03bc9a3e511f9873149518384a6c238b3c9dae87 + last_write_checksum: sha1:a5aaa3b13ea037bf135679735cea3c4b3dff7916 + pristine_git_object: b85f7b325976189a4040ff252699df8bd5c7a23b src/openrouter/alpha.py: id: 306c4d93308d last_write_checksum: sha1:30f55a360f41376ab194b9ea725fe4e001a5ae1a @@ -9920,8 +9988,8 @@ trackedFiles: pristine_git_object: ad3d247954547814054c01989a2dff3d12b3e4e1 src/openrouter/components/__init__.py: id: 81754e97b3f4 - last_write_checksum: sha1:42642b4e0e47e0822eabafb020eff7e5f2c94c38 - pristine_git_object: ada2bdeb1d49520d8348c1691535a0e14be660f6 + last_write_checksum: sha1:9a9eb742f6674e0bcc5115abb71736a81b5804b8 + pristine_git_object: 42136dee42b3b7213bbaa9868f39ee5ed4bc08c8 src/openrouter/components/aabenchmarkentry.py: id: e2e0f0b48c82 last_write_checksum: sha1:fab4d9a24d2cea937bb749d46c5f83941e99d65c @@ -10970,6 +11038,10 @@ trackedFiles: id: 2b6c5e13270a last_write_checksum: sha1:a7a2a40b9ac16a975a4c5ecc8802fc0b7785691c pristine_git_object: fcfd9d646f216fdbb715cbbaefa4382d75750b79 + src/openrouter/components/createenduserrequest.py: + id: 68e7dcf03498 + last_write_checksum: sha1:53f7c250769b1bd14e9b5e67f0270790289574e3 + pristine_git_object: 25623d5f15909380334415605a51f7f6beea9e1c src/openrouter/components/createguardrailrequest.py: id: 34d69149fb33 last_write_checksum: sha1:af6fca661fed3b42e547333b14750448c46b43cf @@ -11150,6 +11222,14 @@ trackedFiles: id: e935c578fce8 last_write_checksum: sha1:8a9c8184852faf1e3ca9a478e48df41ccac6fc33 pristine_git_object: ed5f8af0c599b1e55bb1939bc1d2aff0aeef610d + src/openrouter/components/enduser.py: + id: 1fad1ecc5e12 + last_write_checksum: sha1:8f11cd6a99d28247d4e422a7eb38bb401101852f + pristine_git_object: 1b20f1bbc5c0898cf7bb19a2bb268c65a0747a79 + src/openrouter/components/enduserresponse.py: + id: 3da82145da68 + last_write_checksum: sha1:794963d7fadbbaf7bfb91983d83bec71c9a10556 + pristine_git_object: 04707ad9a1ba9613db756ec89632d85d836c91d4 src/openrouter/components/enumcapability.py: id: 1eddd72a17a5 last_write_checksum: sha1:09e366c414f84edb166eeb8e9091e278c15136d6 @@ -11694,6 +11774,10 @@ trackedFiles: id: 7662d5774bdb last_write_checksum: sha1:8645389f8ca0cc28969d27c99c3ef6dd6a2fe3d3 pristine_git_object: f62b08917378eab6603f9b780c31a0e561329dc4 + src/openrouter/components/listendusersresponse.py: + id: f4e3d2a1226b + last_write_checksum: sha1:131ed7ad8729d2dded869a84ddf83dfd067b06f0 + pristine_git_object: b2fade2a32b04be83817295407a6b9a43473a81e src/openrouter/components/listguardrailsresponse.py: id: 78fbd2689b5d last_write_checksum: sha1:d3103f2ff7aa2be788ef4aacf6a068497779cca1 @@ -13034,6 +13118,10 @@ trackedFiles: id: 31338080f7cc last_write_checksum: sha1:794d77355ae37451076a6b5754c6c8cc77063047 pristine_git_object: a3664695c9722c531f7694851da76e51c2efe4fb + src/openrouter/components/updateenduserrequest.py: + id: 5613bf6e335a + last_write_checksum: sha1:5c92ef6ab64b445ed6c855dc7e06e8df54a1e4bf + pristine_git_object: 0a8dcb3fb8d9c0c80159a622246dff4a3110bb1b src/openrouter/components/updateguardrailrequest.py: id: 6a557cd822a0 last_write_checksum: sha1:0e5978b49b7a37f48931dd778caf1fc46657b881 @@ -13266,6 +13354,10 @@ trackedFiles: id: 0374ace39067 last_write_checksum: sha1:0b6b330486e95ed33ccb9849ff7daa11ed2804d9 pristine_git_object: 6f392ba268a36c1101c027f6a2fbf87e2cd68d10 + src/openrouter/end_users.py: + id: d6787489a521 + last_write_checksum: sha1:bb121c7899ae37fd7c8a897dd524be453816ee79 + pristine_git_object: 544e6911aca76db7531c73d52d7f0b420a1851f0 src/openrouter/endpoints.py: id: 465bbf2b7939 last_write_checksum: sha1:a04548ad80c9b1cf8ae1f5dde2e24774865c1eb8 @@ -13436,8 +13528,8 @@ trackedFiles: pristine_git_object: 8680343bbc90107ae6413bd5686012b1fd75d665 src/openrouter/operations/__init__.py: id: 9afcea1e7161 - last_write_checksum: sha1:9214c0287f7eb88eee096235ebe428439c308f51 - pristine_git_object: ee19e0cac6af2d20d360c529b6786531ab10b239 + last_write_checksum: sha1:cf7033fa5a3bc17a7ec8012f693b042afdcb6b4b + pristine_git_object: 789d0b8285902141a00adc64f2e5c56352b756cf src/openrouter/operations/activateprivateendpoint.py: id: 3b39eec5d66f last_write_checksum: sha1:9406e6b3d38c82895fd795f637702ef579cc6d36 @@ -13502,6 +13594,10 @@ trackedFiles: id: fe1160a960e9 last_write_checksum: sha1:c1e7ac31c6ed358390feeef03d91e5917e57d5de pristine_git_object: 480596964d35ec389350b19b2bf56ac1877960ce + src/openrouter/operations/createenduser.py: + id: 36f457e15ca4 + last_write_checksum: sha1:dc2efc0d9bc08d4f397412b232bd1f3f3943646a + pristine_git_object: 9a40dbfcc416018a82011457c1f795a671f6d642 src/openrouter/operations/createguardrail.py: id: 52ed4b2f5903 last_write_checksum: sha1:d4351fdd66f1fa2bedcfc9a974c7f4ff6c68a6bc @@ -13582,6 +13678,10 @@ trackedFiles: id: b1b2c6b06913 last_write_checksum: sha1:90aad5198d43e289d99c7b2eb66353de7593a68b pristine_git_object: 2148ca98c6cde1506783e9c5f2f522226a27e428 + src/openrouter/operations/deleteenduser.py: + id: f17d13ce6e08 + last_write_checksum: sha1:8bdd5d0135fd346136d447e97a96d0e58004d850 + pristine_git_object: 34d3359a609a0a2d466af2e182e2e7a67d30f5b4 src/openrouter/operations/deletefile.py: id: 7035af059141 last_write_checksum: sha1:9eef35ceee470a0dceb64d463ec499a2e8bad9b5 @@ -13678,6 +13778,10 @@ trackedFiles: id: baf3e38db22c last_write_checksum: sha1:844575d6a91ab0152ee5f64d14b24afa04a04aeb pristine_git_object: f6f9e817724dfd60e747f7c35f297c96bedad819 + src/openrouter/operations/getenduser.py: + id: d20b891f0b70 + last_write_checksum: sha1:8b5a84a6d6782b6afd98d9d195887b23939f9e6d + pristine_git_object: ec4817b78ab7619d405586bf192733c11cbb46a1 src/openrouter/operations/getfilemetadata.py: id: 408c34486769 last_write_checksum: sha1:592b6646b4ff082d8427ea08e79e6b34be490857 @@ -13802,6 +13906,10 @@ trackedFiles: id: 588bf206e92f last_write_checksum: sha1:dd1cc08d8779d71a9ad80e0ad764fea72b3fb846 pristine_git_object: f5bd1f67dc835230e6d282e0500cbf3b5781eab4 + src/openrouter/operations/listendusers.py: + id: 5a2a070b97a4 + last_write_checksum: sha1:57df0a74677bf676dbabd86e10cb653834339725 + pristine_git_object: 2997608bf4b80c6eaf5ef889f417e26a7ab187a1 src/openrouter/operations/listfiles.py: id: fd89527f4236 last_write_checksum: sha1:b4a0b5c4b4152ed8c2766afbaf9d9557ceb347f3 @@ -13958,6 +14066,10 @@ trackedFiles: id: 486f4ea60120 last_write_checksum: sha1:a170382e38c66128bddbe8ea18c034d1350910da pristine_git_object: cf8b4ee9febb198afe12c27d03c72902eaa8baf0 + src/openrouter/operations/updateenduser.py: + id: 62d2ff1bbd3e + last_write_checksum: sha1:ad15bb7939a3306707e6711b06e27bf68fb8cc33 + pristine_git_object: 2e0d7cce1294b09b88f9e40403362267479b421e src/openrouter/operations/updateguardrail.py: id: 6cfb33d7d40c last_write_checksum: sha1:bf4f6b9899c176fa012acc607556a66d6e85a51b @@ -14036,8 +14148,8 @@ trackedFiles: pristine_git_object: a28df9a26e2dd834e5bc8974c3a61d18609c79c0 src/openrouter/sdk.py: id: ee9846c4c9c5 - last_write_checksum: sha1:61f29c3c30502f852822fa16b2d16d1a778273df - pristine_git_object: 0a110f2cdff3e7c31e971721166593cc792bc424 + last_write_checksum: sha1:da0be6fb98b533d46bc081ad07a051dc0b4df355 + pristine_git_object: 8d7b90d73d3870661ef59982a25f34219d48dd2e src/openrouter/sdkconfiguration.py: id: 55773bb98d7c last_write_checksum: sha1:c01826125c31a8b8bc99d9d679782c8758fae001 @@ -17942,5 +18054,94 @@ examples: application/json: {"error": {"code": 404, "message": "Resource not found"}} "500": application/json: {"error": {"code": 500, "message": "Internal Server Error"}} + listEndUsers: + speakeasy-default-list-end-users: + parameters: + query: + offset: 0 + limit: 50 + include_inactive: false + responses: + "200": + application/json: {"data": [{"created_at": "2026-09-16T12:00:00Z", "is_active": true, "updated_at": "2026-09-16T12:00:00Z", "user": "employee_123"}], "total_count": 1} + "400": + application/json: {"error": {"code": 400, "message": "Invalid request parameters"}} + "401": + application/json: {"error": {"code": 401, "message": "Missing Authentication header"}} + "404": + application/json: {"error": {"code": 404, "message": "Resource not found"}} + "500": + application/json: {"error": {"code": 500, "message": "Internal Server Error"}} + createEndUser: + speakeasy-default-create-end-user: + requestBody: + application/json: {"user": "employee_123"} + responses: + "201": + application/json: {"data": {"created_at": "2026-09-16T12:00:00Z", "is_active": true, "updated_at": "2026-09-16T12:00:00Z", "user": "employee_123"}} + "400": + application/json: {"error": {"code": 400, "message": "Invalid request parameters"}} + "401": + application/json: {"error": {"code": 401, "message": "Missing Authentication header"}} + "404": + application/json: {"error": {"code": 404, "message": "Resource not found"}} + "409": + application/json: {"error": {"code": 409, "message": "Resource conflict. Please try again later."}} + "500": + application/json: {"error": {"code": 500, "message": "Internal Server Error"}} + deleteEndUser: + speakeasy-default-delete-end-user: + parameters: + path: + user: "employee_123" + responses: + "400": + application/json: {"error": {"code": 400, "message": "Invalid request parameters"}} + "401": + application/json: {"error": {"code": 401, "message": "Missing Authentication header"}} + "404": + application/json: {"error": {"code": 404, "message": "Resource not found"}} + "500": + application/json: {"error": {"code": 500, "message": "Internal Server Error"}} + getEndUser: + speakeasy-default-get-end-user: + parameters: + path: + user: "employee_123" + responses: + "200": + application/json: {"data": {"created_at": "2026-09-16T12:00:00Z", "is_active": true, "updated_at": "2026-09-16T12:00:00Z", "user": "employee_123"}} + "400": + application/json: {"error": {"code": 400, "message": "Invalid request parameters"}} + "401": + application/json: {"error": {"code": 401, "message": "Missing Authentication header"}} + "404": + application/json: {"error": {"code": 404, "message": "Resource not found"}} + "500": + application/json: {"error": {"code": 500, "message": "Internal Server Error"}} + updateEndUser: + speakeasy-default-update-end-user: + parameters: + path: + user: "employee_123" + requestBody: + application/json: {"is_active": true} + responses: + "200": + application/json: {"data": {"created_at": "2026-09-16T12:00:00Z", "is_active": true, "updated_at": "2026-09-16T12:00:00Z", "user": "employee_123"}} + "400": + application/json: {"error": {"code": 400, "message": "Invalid request parameters"}} + "401": + application/json: {"error": {"code": 401, "message": "Missing Authentication header"}} + "404": + application/json: {"error": {"code": 404, "message": "Resource not found"}} + "500": + application/json: {"error": {"code": 500, "message": "Internal Server Error"}} examplesVersion: 1.0.2 -releaseNotes: "## Python SDK Changes:\n* `open_router.batch.create_batches()`: `response.results[].response.body` **Changed**\n* `open_router.batch.get_batches()`: `response.results[].response.body` **Changed**\n* `open_router.chat.send()`: \n * `request.plugins[].union(alignment)` **Added**\n* `open_router.presets.create_presets_chat_completions()`: \n * `request.plugins[].union(alignment)` **Added**\n* `open_router.presets.create_presets_messages()`: \n * `request.plugins[].union(alignment)` **Added**\n* `open_router.presets.create_presets_responses()`: \n * `request.plugins[].union(alignment)` **Added**\n* `open_router.responses.send()`: \n * `request.plugins[].union(alignment)` **Added**\n * `response` **Changed**\n* `open_router.beta.responses.send()`: \n * `request.plugins[].union(alignment)` **Added**\n * `response` **Changed**\n" +releaseNotes: | + ## Python SDK Changes: + * `open_router.end_users.list()`: **Added** + * `open_router.end_users.create()`: **Added** + * `open_router.end_users.delete()`: **Added** + * `open_router.end_users.get()`: **Added** + * `open_router.end_users.update()`: **Added** diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml index 81c33a60..28e7bd1d 100644 --- a/.speakeasy/gen.yaml +++ b/.speakeasy/gen.yaml @@ -36,7 +36,7 @@ generation: documentation: mintlify preApplyUnionDiscriminators: true python: - version: 1.3.11 + version: 1.3.12 additionalDependencies: dev: {} main: {} diff --git a/.speakeasy/out.openapi.yaml b/.speakeasy/out.openapi.yaml index c347c164..69ec9b43 100644 --- a/.speakeasy/out.openapi.yaml +++ b/.speakeasy/out.openapi.yaml @@ -9340,6 +9340,21 @@ components: - 'response' - 'sequence_number' type: 'object' + CreateEndUserRequest: + additionalProperties: false + example: + user: 'employee_123' + properties: + user: + description: 'Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths.' + example: 'employee_123' + maxLength: 256 + minLength: 1 + pattern: '^[^\p{Cc}]+$' + type: 'string' + required: + - 'user' + type: 'object' CreateGuardrailRequest: example: allowed_models: null @@ -10821,6 +10836,54 @@ components: example: 0 type: 'integer' x-speakeasy-unknown-values: allow + EndUser: + additionalProperties: false + example: + created_at: '2026-09-16T12:00:00Z' + is_active: true + updated_at: '2026-09-16T12:00:00Z' + user: 'employee_123' + properties: + created_at: + description: 'Registration creation time.' + example: '2026-09-16T12:00:00Z' + format: 'date-time' + type: 'string' + is_active: + description: 'Whether this registration is active. Not an inference authorization decision.' + example: true + type: 'boolean' + updated_at: + description: 'Last registration lifecycle update time.' + example: '2026-09-16T12:00:00Z' + format: 'date-time' + type: 'string' + user: + description: 'Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths.' + example: 'employee_123' + maxLength: 256 + minLength: 1 + pattern: '^[^\p{Cc}]+$' + type: 'string' + required: + - 'user' + - 'is_active' + - 'created_at' + - 'updated_at' + type: 'object' + EndUserResponse: + example: + data: + created_at: '2026-09-16T12:00:00Z' + is_active: true + updated_at: '2026-09-16T12:00:00Z' + user: 'employee_123' + properties: + data: + $ref: '#/components/schemas/EndUser' + required: + - 'data' + type: 'object' EnumCapability: description: 'A parameter that accepts one of a discrete set of string values.' example: @@ -15595,6 +15658,27 @@ components: - 'architecture' - 'endpoints' type: 'object' + ListEndUsersResponse: + example: + data: + - created_at: '2026-09-16T12:00:00Z' + is_active: true + updated_at: '2026-09-16T12:00:00Z' + user: 'employee_123' + total_count: 1 + properties: + data: + items: + $ref: '#/components/schemas/EndUser' + type: 'array' + total_count: + description: 'Number of registrations matching the filters before pagination.' + example: 1 + type: 'integer' + required: + - 'data' + - 'total_count' + type: 'object' ListGuardrailsResponse: example: data: @@ -30996,6 +31080,18 @@ components: required: - 'data' type: 'object' + UpdateEndUserRequest: + additionalProperties: false + example: + is_active: true + properties: + is_active: + description: 'Registration state only; does not enforce inference access.' + example: true + type: 'boolean' + required: + - 'is_active' + type: 'object' UpdateGuardrailRequest: example: description: 'Updated description' @@ -37684,6 +37780,425 @@ paths: - $ref: "#/components/parameters/AppIdentifier" - $ref: "#/components/parameters/AppDisplayName" - $ref: "#/components/parameters/AppCategories" + /end-users: + get: + description: 'List registrations belonging to the authenticated organization. Inactive registrations are excluded by default. [Management key](/docs/guides/overview/auth/management-api-keys) required.' + operationId: 'listEndUsers' + parameters: + - description: 'Number of records to skip for pagination' + in: 'query' + name: 'offset' + required: false + schema: + default: 0 + description: 'Number of records to skip for pagination' + example: 0 + minimum: 0 + type: + - 'integer' + - 'null' + nullable: false + - description: 'Maximum number of records to return (max 100)' + in: 'query' + name: 'limit' + required: false + schema: + default: 50 + description: 'Maximum number of records to return (max 100)' + example: 50 + maximum: 100 + minimum: 1 + type: 'integer' + - description: 'Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths.' + in: 'query' + name: 'user' + required: false + schema: + description: 'Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths.' + example: 'employee_123' + maxLength: 256 + minLength: 1 + pattern: '^[^\p{Cc}]+$' + type: 'string' + - description: 'Include deactivated registrations.' + in: 'query' + name: 'include_inactive' + required: false + schema: + default: false + description: 'Include deactivated registrations.' + example: false + type: 'boolean' + responses: + '200': + content: + application/json: + example: + data: + - created_at: '2026-09-16T12:00:00Z' + is_active: true + updated_at: '2026-09-16T12:00:00Z' + user: 'employee_123' + total_count: 1 + schema: + $ref: '#/components/schemas/ListEndUsersResponse' + description: 'Matching registrations and their total count.' + '400': + content: + application/json: + example: + error: + code: 400 + message: 'Invalid request parameters' + schema: + $ref: '#/components/schemas/BadRequestResponse' + description: 'Bad Request - Invalid request parameters or malformed input' + '401': + content: + application/json: + example: + error: + code: 401 + message: 'Missing Authentication header' + schema: + $ref: '#/components/schemas/UnauthorizedResponse' + description: 'Unauthorized - Authentication required or invalid credentials' + '404': + content: + application/json: + example: + error: + code: 404 + message: 'Resource not found' + schema: + $ref: '#/components/schemas/NotFoundResponse' + description: 'Not Found - Resource does not exist' + '500': + content: + application/json: + example: + error: + code: 500 + message: 'Internal Server Error' + schema: + $ref: '#/components/schemas/InternalServerResponse' + description: 'Internal Server Error - Unexpected server error' + summary: 'List registered end users' + tags: + - 'End Users' + x-speakeasy-name-override: 'list' + x-speakeasy-pagination: + inputs: + - in: 'parameters' + name: 'offset' + type: 'offset' + - in: 'parameters' + name: 'limit' + type: 'limit' + outputs: + results: '$.data' + type: 'offsetLimit' + post: + description: 'Register a caller-supplied tracking ID under the authenticated organization. No login account, policy, or credentials are created. [Management key](/docs/guides/overview/auth/management-api-keys) required.' + operationId: 'createEndUser' + requestBody: + content: + application/json: + example: + user: 'employee_123' + schema: + $ref: '#/components/schemas/CreateEndUserRequest' + required: true + responses: + '201': + content: + application/json: + example: + data: + created_at: '2026-09-16T12:00:00Z' + is_active: true + updated_at: '2026-09-16T12:00:00Z' + user: 'employee_123' + schema: + $ref: '#/components/schemas/EndUserResponse' + description: 'The registered end user. No generated public identifier is returned.' + '400': + content: + application/json: + example: + error: + code: 400 + message: 'Invalid request parameters' + schema: + $ref: '#/components/schemas/BadRequestResponse' + description: 'Bad Request - Invalid request parameters or malformed input' + '401': + content: + application/json: + example: + error: + code: 401 + message: 'Missing Authentication header' + schema: + $ref: '#/components/schemas/UnauthorizedResponse' + description: 'Unauthorized - Authentication required or invalid credentials' + '404': + content: + application/json: + example: + error: + code: 404 + message: 'Resource not found' + schema: + $ref: '#/components/schemas/NotFoundResponse' + description: 'Not Found - Resource does not exist' + '409': + content: + application/json: + example: + error: + code: 409 + message: 'This tracking ID is already registered' + schema: + $ref: '#/components/schemas/ConflictResponse' + description: 'The tracking ID is already registered in this organization, active or not.' + '500': + content: + application/json: + example: + error: + code: 500 + message: 'Internal Server Error' + schema: + $ref: '#/components/schemas/InternalServerResponse' + description: 'Internal Server Error - Unexpected server error' + summary: 'Register an end user' + tags: + - 'End Users' + x-speakeasy-name-override: 'create' + parameters: + - $ref: "#/components/parameters/AppIdentifier" + - $ref: "#/components/parameters/AppDisplayName" + - $ref: "#/components/parameters/AppCategories" + /end-users/{user}: + delete: + description: 'Soft-deactivate a registration while retaining its tracking ID. Repeat deactivation succeeds. This does not block inference; reactivate through PATCH. [Management key](/docs/guides/overview/auth/management-api-keys) required.' + operationId: 'deleteEndUser' + parameters: + - description: 'Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths.' + in: 'path' + name: 'user' + required: true + schema: + description: 'Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths.' + example: 'employee_123' + maxLength: 256 + minLength: 1 + pattern: '^[^\p{Cc}]+$' + type: 'string' + responses: + '204': + description: 'Registration is inactive.' + '400': + content: + application/json: + example: + error: + code: 400 + message: 'Invalid request parameters' + schema: + $ref: '#/components/schemas/BadRequestResponse' + description: 'Bad Request - Invalid request parameters or malformed input' + '401': + content: + application/json: + example: + error: + code: 401 + message: 'Missing Authentication header' + schema: + $ref: '#/components/schemas/UnauthorizedResponse' + description: 'Unauthorized - Authentication required or invalid credentials' + '404': + content: + application/json: + example: + error: + code: 404 + message: 'Resource not found' + schema: + $ref: '#/components/schemas/NotFoundResponse' + description: 'Not Found - Resource does not exist' + '500': + content: + application/json: + example: + error: + code: 500 + message: 'Internal Server Error' + schema: + $ref: '#/components/schemas/InternalServerResponse' + description: 'Internal Server Error - Unexpected server error' + summary: 'Deactivate a registered end user' + tags: + - 'End Users' + x-speakeasy-name-override: 'delete' + get: + description: 'Retrieve an active or inactive registration by its URL-encoded, caller-supplied tracking ID. [Management key](/docs/guides/overview/auth/management-api-keys) required.' + operationId: 'getEndUser' + parameters: + - description: 'Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths.' + in: 'path' + name: 'user' + required: true + schema: + description: 'Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths.' + example: 'employee_123' + maxLength: 256 + minLength: 1 + pattern: '^[^\p{Cc}]+$' + type: 'string' + responses: + '200': + content: + application/json: + example: + data: + created_at: '2026-09-16T12:00:00Z' + is_active: true + updated_at: '2026-09-16T12:00:00Z' + user: 'employee_123' + schema: + $ref: '#/components/schemas/EndUserResponse' + description: 'The registered end user. No generated public identifier is returned.' + '400': + content: + application/json: + example: + error: + code: 400 + message: 'Invalid request parameters' + schema: + $ref: '#/components/schemas/BadRequestResponse' + description: 'Bad Request - Invalid request parameters or malformed input' + '401': + content: + application/json: + example: + error: + code: 401 + message: 'Missing Authentication header' + schema: + $ref: '#/components/schemas/UnauthorizedResponse' + description: 'Unauthorized - Authentication required or invalid credentials' + '404': + content: + application/json: + example: + error: + code: 404 + message: 'Resource not found' + schema: + $ref: '#/components/schemas/NotFoundResponse' + description: 'Not Found - Resource does not exist' + '500': + content: + application/json: + example: + error: + code: 500 + message: 'Internal Server Error' + schema: + $ref: '#/components/schemas/InternalServerResponse' + description: 'Internal Server Error - Unexpected server error' + summary: 'Get a registered end user' + tags: + - 'End Users' + x-speakeasy-name-override: 'get' + patch: + description: 'Update registration state without changing identity. State changes do not enforce inference access. [Management key](/docs/guides/overview/auth/management-api-keys) required.' + operationId: 'updateEndUser' + parameters: + - description: 'Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths.' + in: 'path' + name: 'user' + required: true + schema: + description: 'Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths.' + example: 'employee_123' + maxLength: 256 + minLength: 1 + pattern: '^[^\p{Cc}]+$' + type: 'string' + requestBody: + content: + application/json: + example: + is_active: true + schema: + $ref: '#/components/schemas/UpdateEndUserRequest' + required: true + responses: + '200': + content: + application/json: + example: + data: + created_at: '2026-09-16T12:00:00Z' + is_active: true + updated_at: '2026-09-16T12:00:00Z' + user: 'employee_123' + schema: + $ref: '#/components/schemas/EndUserResponse' + description: 'The registered end user. No generated public identifier is returned.' + '400': + content: + application/json: + example: + error: + code: 400 + message: 'Invalid request parameters' + schema: + $ref: '#/components/schemas/BadRequestResponse' + description: 'Bad Request - Invalid request parameters or malformed input' + '401': + content: + application/json: + example: + error: + code: 401 + message: 'Missing Authentication header' + schema: + $ref: '#/components/schemas/UnauthorizedResponse' + description: 'Unauthorized - Authentication required or invalid credentials' + '404': + content: + application/json: + example: + error: + code: 404 + message: 'Resource not found' + schema: + $ref: '#/components/schemas/NotFoundResponse' + description: 'Not Found - Resource does not exist' + '500': + content: + application/json: + example: + error: + code: 500 + message: 'Internal Server Error' + schema: + $ref: '#/components/schemas/InternalServerResponse' + description: 'Internal Server Error - Unexpected server error' + summary: 'Update a registered end user' + tags: + - 'End Users' + x-speakeasy-name-override: 'update' + parameters: + - $ref: "#/components/parameters/AppIdentifier" + - $ref: "#/components/parameters/AppDisplayName" + - $ref: "#/components/parameters/AppCategories" /endpoints/zdr: get: operationId: 'listEndpointsZdr' @@ -52637,6 +53152,8 @@ tags: name: 'Datasets' - description: 'Text embedding endpoints' name: 'Embeddings' + - description: 'End Users endpoints' + name: 'End Users' - description: 'Endpoint information' name: 'Endpoints' - description: 'Files endpoints' diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock index dd3db004..46ee7ada 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:834803ef63cfc97ba41255da616c1bc9711490eeba3f2ebfab565090031bdaad - sourceBlobDigest: sha256:7c20345ae48391f9c96dba9535545e59b6b2ebbb979dab7fd57912cc63ce884a + sourceRevisionDigest: sha256:7bc4aac2a9068c7b46e8cf5f90fb4994ef4fcae205748bbd34114c8f9713822c + sourceBlobDigest: sha256:d01919a75486dedd849036c7413ff8b451687727058e5bf1985d16f536ad5f86 tags: - latest - 1.0.0 @@ -11,10 +11,10 @@ targets: open-router: source: OpenRouter API sourceNamespace: open-router-chat-completions-api - sourceRevisionDigest: sha256:834803ef63cfc97ba41255da616c1bc9711490eeba3f2ebfab565090031bdaad - sourceBlobDigest: sha256:7c20345ae48391f9c96dba9535545e59b6b2ebbb979dab7fd57912cc63ce884a + sourceRevisionDigest: sha256:7bc4aac2a9068c7b46e8cf5f90fb4994ef4fcae205748bbd34114c8f9713822c + sourceBlobDigest: sha256:d01919a75486dedd849036c7413ff8b451687727058e5bf1985d16f536ad5f86 codeSamplesNamespace: open-router-python-code-samples - codeSamplesRevisionDigest: sha256:8ba988604de91796d7efb008917f27c26d144e13f6128b267066b24a2ab86ab5 + codeSamplesRevisionDigest: sha256:33b893dfc8f4b52290dfe30db1b8a87d46f0b0804dcdcc80a2dcdc61bd9450ab workflow: workflowVersion: 1.0.0 speakeasyVersion: 1.787.0 diff --git a/RELEASES.md b/RELEASES.md index 779c2a21..585ffb30 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -2879,4 +2879,14 @@ Based on: ### Generated - [python v1.3.11] . ### Releases -- [PyPI v1.3.11] https://pypi.org/project/openrouter/1.3.11 - . \ No newline at end of file +- [PyPI v1.3.11] https://pypi.org/project/openrouter/1.3.11 - . + +## 2026-09-30 18:06:50 +### Changes +Based on: +- OpenAPI Doc +- Speakeasy CLI 1.787.0 (2.914.0) https://github.com/speakeasy-api/speakeasy +### Generated +- [python v1.3.12] . +### Releases +- [PyPI v1.3.12] https://pypi.org/project/openrouter/1.3.12 - . \ No newline at end of file diff --git a/docs/components/createenduserrequest.mdx b/docs/components/createenduserrequest.mdx new file mode 100644 index 00000000..daaedee3 --- /dev/null +++ b/docs/components/createenduserrequest.mdx @@ -0,0 +1,9 @@ +--- +title: "CreateEndUserRequest" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | +| `user` | *str* | :heavy_check_mark: | Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths. | employee_123 | \ No newline at end of file diff --git a/docs/components/enduser.mdx b/docs/components/enduser.mdx new file mode 100644 index 00000000..33111673 --- /dev/null +++ b/docs/components/enduser.mdx @@ -0,0 +1,12 @@ +--- +title: "EndUser" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | +| `created_at` | [date](https://docs.python.org/3/library/datetime.html#date-objects) | :heavy_check_mark: | Registration creation time. | 2026-09-16T12:00:00Z | +| `is_active` | *bool* | :heavy_check_mark: | Whether this registration is active. Not an inference authorization decision. | true | +| `updated_at` | [date](https://docs.python.org/3/library/datetime.html#date-objects) | :heavy_check_mark: | Last registration lifecycle update time. | 2026-09-16T12:00:00Z | +| `user` | *str* | :heavy_check_mark: | Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths. | employee_123 | \ No newline at end of file diff --git a/docs/components/enduserresponse.mdx b/docs/components/enduserresponse.mdx new file mode 100644 index 00000000..4b605db1 --- /dev/null +++ b/docs/components/enduserresponse.mdx @@ -0,0 +1,9 @@ +--- +title: "EndUserResponse" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | +| `data` | [components.EndUser](../components/enduser.mdx) | :heavy_check_mark: | N/A | \{
"created_at": "2026-09-16T12:00:00Z",
"is_active": true,
"updated_at": "2026-09-16T12:00:00Z",
"user": "employee_123"
} | \ No newline at end of file diff --git a/docs/components/listendusersresponse.mdx b/docs/components/listendusersresponse.mdx new file mode 100644 index 00000000..b95cdd81 --- /dev/null +++ b/docs/components/listendusersresponse.mdx @@ -0,0 +1,10 @@ +--- +title: "ListEndUsersResponse" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------------------------------------------- | --------------------------------------------------------------- | --------------------------------------------------------------- | --------------------------------------------------------------- | --------------------------------------------------------------- | +| `data` | List[[components.EndUser](../components/enduser.mdx)] | :heavy_check_mark: | N/A | | +| `total_count` | *int* | :heavy_check_mark: | Number of registrations matching the filters before pagination. | 1 | \ No newline at end of file diff --git a/docs/components/updateenduserrequest.mdx b/docs/components/updateenduserrequest.mdx new file mode 100644 index 00000000..72a1c5ad --- /dev/null +++ b/docs/components/updateenduserrequest.mdx @@ -0,0 +1,9 @@ +--- +title: "UpdateEndUserRequest" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------- | ----------------------------------------------------------- | ----------------------------------------------------------- | ----------------------------------------------------------- | ----------------------------------------------------------- | +| `is_active` | *bool* | :heavy_check_mark: | Registration state only; does not enforce inference access. | true | \ No newline at end of file diff --git a/docs/operations/createenduserglobals.mdx b/docs/operations/createenduserglobals.mdx new file mode 100644 index 00000000..e420bbbe --- /dev/null +++ b/docs/operations/createenduserglobals.mdx @@ -0,0 +1,11 @@ +--- +title: "CreateEndUserGlobals" +--- + +## Fields + +| Field | Type | Required | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| +| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| +| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| \ No newline at end of file diff --git a/docs/operations/createenduserrequest.mdx b/docs/operations/createenduserrequest.mdx new file mode 100644 index 00000000..9448f508 --- /dev/null +++ b/docs/operations/createenduserrequest.mdx @@ -0,0 +1,12 @@ +--- +title: "CreateEndUserRequest" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| | +| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| | +| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| | +| `create_end_user_request` | [components.CreateEndUserRequest](../components/createenduserrequest.mdx) | :heavy_check_mark: | N/A | \{
"user": "employee_123"
} | \ No newline at end of file diff --git a/docs/operations/deleteenduserglobals.mdx b/docs/operations/deleteenduserglobals.mdx new file mode 100644 index 00000000..07094eff --- /dev/null +++ b/docs/operations/deleteenduserglobals.mdx @@ -0,0 +1,11 @@ +--- +title: "DeleteEndUserGlobals" +--- + +## Fields + +| Field | Type | Required | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| +| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| +| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| \ No newline at end of file diff --git a/docs/operations/deleteenduserrequest.mdx b/docs/operations/deleteenduserrequest.mdx new file mode 100644 index 00000000..ad4cacf7 --- /dev/null +++ b/docs/operations/deleteenduserrequest.mdx @@ -0,0 +1,12 @@ +--- +title: "DeleteEndUserRequest" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| | +| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| | +| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| | +| `user` | *str* | :heavy_check_mark: | Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths. | employee_123 | \ No newline at end of file diff --git a/docs/operations/getenduserglobals.mdx b/docs/operations/getenduserglobals.mdx new file mode 100644 index 00000000..9ec66ba1 --- /dev/null +++ b/docs/operations/getenduserglobals.mdx @@ -0,0 +1,11 @@ +--- +title: "GetEndUserGlobals" +--- + +## Fields + +| Field | Type | Required | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| +| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| +| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| \ No newline at end of file diff --git a/docs/operations/getenduserrequest.mdx b/docs/operations/getenduserrequest.mdx new file mode 100644 index 00000000..501f7d29 --- /dev/null +++ b/docs/operations/getenduserrequest.mdx @@ -0,0 +1,12 @@ +--- +title: "GetEndUserRequest" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| | +| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| | +| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| | +| `user` | *str* | :heavy_check_mark: | Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths. | employee_123 | \ No newline at end of file diff --git a/docs/operations/listendusersglobals.mdx b/docs/operations/listendusersglobals.mdx new file mode 100644 index 00000000..3b3fecc1 --- /dev/null +++ b/docs/operations/listendusersglobals.mdx @@ -0,0 +1,11 @@ +--- +title: "ListEndUsersGlobals" +--- + +## Fields + +| Field | Type | Required | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| +| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| +| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| \ No newline at end of file diff --git a/docs/operations/listendusersrequest.mdx b/docs/operations/listendusersrequest.mdx new file mode 100644 index 00000000..0dd8516d --- /dev/null +++ b/docs/operations/listendusersrequest.mdx @@ -0,0 +1,15 @@ +--- +title: "ListEndUsersRequest" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| | +| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| | +| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| | +| `offset` | *OptionalNullable[int]* | :heavy_minus_sign: | Number of records to skip for pagination | 0 | +| `limit` | *Optional[int]* | :heavy_minus_sign: | Maximum number of records to return (max 100) | 50 | +| `user` | *Optional[str]* | :heavy_minus_sign: | Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths. | employee_123 | +| `include_inactive` | *Optional[bool]* | :heavy_minus_sign: | Include deactivated registrations. | false | \ No newline at end of file diff --git a/docs/operations/listendusersresponse.mdx b/docs/operations/listendusersresponse.mdx new file mode 100644 index 00000000..d8ac5262 --- /dev/null +++ b/docs/operations/listendusersresponse.mdx @@ -0,0 +1,9 @@ +--- +title: "ListEndUsersResponse" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `result` | [components.ListEndUsersResponse](../components/listendusersresponse.mdx) | :heavy_check_mark: | N/A | \{
"data": [
\{
"created_at": "2026-09-16T12:00:00Z",
"is_active": true,
"updated_at": "2026-09-16T12:00:00Z",
"user": "employee_123"
}
],
"total_count": 1
} | \ No newline at end of file diff --git a/docs/operations/updateenduserglobals.mdx b/docs/operations/updateenduserglobals.mdx new file mode 100644 index 00000000..de504b1c --- /dev/null +++ b/docs/operations/updateenduserglobals.mdx @@ -0,0 +1,11 @@ +--- +title: "UpdateEndUserGlobals" +--- + +## Fields + +| Field | Type | Required | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| +| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| +| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| \ No newline at end of file diff --git a/docs/operations/updateenduserrequest.mdx b/docs/operations/updateenduserrequest.mdx new file mode 100644 index 00000000..62ae0d75 --- /dev/null +++ b/docs/operations/updateenduserrequest.mdx @@ -0,0 +1,13 @@ +--- +title: "UpdateEndUserRequest" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| | +| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| | +| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| | +| `user` | *str* | :heavy_check_mark: | Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths. | employee_123 | +| `update_end_user_request` | [components.UpdateEndUserRequest](../components/updateenduserrequest.mdx) | :heavy_check_mark: | N/A | \{
"is_active": true
} | \ No newline at end of file diff --git a/docs/sdks/endusers/README.mdx b/docs/sdks/endusers/README.mdx new file mode 100644 index 00000000..8f4e8760 --- /dev/null +++ b/docs/sdks/endusers/README.mdx @@ -0,0 +1,263 @@ +--- +title: "EndUsers" +description: "End Users endpoints" +--- + +## Overview + +End Users endpoints + +### Available Operations + +* [list](#list) - List registered end users +* [create](#create) - Register an end user +* [delete](#delete) - Deactivate a registered end user +* [get](#get) - Get a registered end user +* [update](#update) - Update a registered end user + +## list + +List registrations belonging to the authenticated organization. Inactive registrations are excluded by default. [Management key](/docs/guides/overview/auth/management-api-keys) required. + +### Example Usage + +```python +from openrouter import OpenRouter +import os + + +with OpenRouter( + http_referer="", + x_open_router_title="", + x_open_router_categories="", + api_key=os.getenv("OPENROUTER_API_KEY", ""), +) as open_router: + + res = open_router.end_users.list(offset=0, limit=50, include_inactive=False) + + while res is not None: + # Handle items + + res = res.next() + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| | +| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| | +| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| | +| `offset` | *OptionalNullable[int]* | :heavy_minus_sign: | Number of records to skip for pagination | 0 | +| `limit` | *Optional[int]* | :heavy_minus_sign: | Maximum number of records to return (max 100) | 50 | +| `user` | *Optional[str]* | :heavy_minus_sign: | Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths. | employee_123 | +| `include_inactive` | *Optional[bool]* | :heavy_minus_sign: | Include deactivated registrations. | false | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.mdx) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + +### Response + +**[operations.ListEndUsersResponse](../../operations/listendusersresponse.mdx)** + +### Errors + +| Error Type | Status Code | Content Type | +| ---------------------------------- | ---------------------------------- | ---------------------------------- | +| errors.BadRequestResponseError | 400 | application/json | +| errors.UnauthorizedResponseError | 401 | application/json | +| errors.NotFoundResponseError | 404 | application/json | +| errors.InternalServerResponseError | 500 | application/json | +| errors.OpenRouterDefaultError | 4XX, 5XX | \*/\* | + +## create + +Register a caller-supplied tracking ID under the authenticated organization. No login account, policy, or credentials are created. [Management key](/docs/guides/overview/auth/management-api-keys) required. + +### Example Usage + +```python +from openrouter import OpenRouter +import os + + +with OpenRouter( + http_referer="", + x_open_router_title="", + x_open_router_categories="", + api_key=os.getenv("OPENROUTER_API_KEY", ""), +) as open_router: + + res = open_router.end_users.create(user="employee_123") + + # Handle response + print(res) + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `user` | *str* | :heavy_check_mark: | Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths. | employee_123 | +| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| | +| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| | +| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.mdx) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + +### Response + +**[components.EndUserResponse](../../components/enduserresponse.mdx)** + +### Errors + +| Error Type | Status Code | Content Type | +| ---------------------------------- | ---------------------------------- | ---------------------------------- | +| errors.BadRequestResponseError | 400 | application/json | +| errors.UnauthorizedResponseError | 401 | application/json | +| errors.NotFoundResponseError | 404 | application/json | +| errors.ConflictResponseError | 409 | application/json | +| errors.InternalServerResponseError | 500 | application/json | +| errors.OpenRouterDefaultError | 4XX, 5XX | \*/\* | + +## delete + +Soft-deactivate a registration while retaining its tracking ID. Repeat deactivation succeeds. This does not block inference; reactivate through PATCH. [Management key](/docs/guides/overview/auth/management-api-keys) required. + +### Example Usage + +```python +from openrouter import OpenRouter +import os + + +with OpenRouter( + http_referer="", + x_open_router_title="", + x_open_router_categories="", + api_key=os.getenv("OPENROUTER_API_KEY", ""), +) as open_router: + + open_router.end_users.delete(user="employee_123") + + # Use the SDK ... + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `user` | *str* | :heavy_check_mark: | Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths. | employee_123 | +| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| | +| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| | +| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.mdx) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + +### Errors + +| Error Type | Status Code | Content Type | +| ---------------------------------- | ---------------------------------- | ---------------------------------- | +| errors.BadRequestResponseError | 400 | application/json | +| errors.UnauthorizedResponseError | 401 | application/json | +| errors.NotFoundResponseError | 404 | application/json | +| errors.InternalServerResponseError | 500 | application/json | +| errors.OpenRouterDefaultError | 4XX, 5XX | \*/\* | + +## get + +Retrieve an active or inactive registration by its URL-encoded, caller-supplied tracking ID. [Management key](/docs/guides/overview/auth/management-api-keys) required. + +### Example Usage + +```python +from openrouter import OpenRouter +import os + + +with OpenRouter( + http_referer="", + x_open_router_title="", + x_open_router_categories="", + api_key=os.getenv("OPENROUTER_API_KEY", ""), +) as open_router: + + res = open_router.end_users.get(user="employee_123") + + # Handle response + print(res) + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `user` | *str* | :heavy_check_mark: | Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths. | employee_123 | +| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| | +| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| | +| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.mdx) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + +### Response + +**[components.EndUserResponse](../../components/enduserresponse.mdx)** + +### Errors + +| Error Type | Status Code | Content Type | +| ---------------------------------- | ---------------------------------- | ---------------------------------- | +| errors.BadRequestResponseError | 400 | application/json | +| errors.UnauthorizedResponseError | 401 | application/json | +| errors.NotFoundResponseError | 404 | application/json | +| errors.InternalServerResponseError | 500 | application/json | +| errors.OpenRouterDefaultError | 4XX, 5XX | \*/\* | + +## update + +Update registration state without changing identity. State changes do not enforce inference access. [Management key](/docs/guides/overview/auth/management-api-keys) required. + +### Example Usage + +```python +from openrouter import OpenRouter +import os + + +with OpenRouter( + http_referer="", + x_open_router_title="", + x_open_router_categories="", + api_key=os.getenv("OPENROUTER_API_KEY", ""), +) as open_router: + + res = open_router.end_users.update(user="employee_123", is_active=True) + + # Handle response + print(res) + +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `user` | *str* | :heavy_check_mark: | Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths. | employee_123 | +| `is_active` | *bool* | :heavy_check_mark: | Registration state only; does not enforce inference access. | true | +| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| | +| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| | +| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.mdx) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | + +### Response + +**[components.EndUserResponse](../../components/enduserresponse.mdx)** + +### Errors + +| Error Type | Status Code | Content Type | +| ---------------------------------- | ---------------------------------- | ---------------------------------- | +| errors.BadRequestResponseError | 400 | application/json | +| errors.UnauthorizedResponseError | 401 | application/json | +| errors.NotFoundResponseError | 404 | application/json | +| errors.InternalServerResponseError | 500 | application/json | +| errors.OpenRouterDefaultError | 4XX, 5XX | \*/\* | \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 71e0d536..6372f844 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "openrouter" -version = "1.3.11" +version = "1.3.12" 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 03bc9a3e..b85f7b32 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.11" +__version__: str = "1.3.12" __openapi_doc_version__: str = "1.0.0" __gen_version__: str = "2.914.0" -__user_agent__: str = "speakeasy-sdk/python 1.3.11 2.914.0 1.0.0 openrouter" +__user_agent__: str = "speakeasy-sdk/python 1.3.12 2.914.0 1.0.0 openrouter" try: if __package__ is not None: diff --git a/src/openrouter/components/__init__.py b/src/openrouter/components/__init__.py index ada2bdeb..42136dee 100644 --- a/src/openrouter/components/__init__.py +++ b/src/openrouter/components/__init__.py @@ -1402,6 +1402,10 @@ CreateBYOKKeyResponse, CreateBYOKKeyResponseTypedDict, ) + from .createenduserrequest import ( + CreateEndUserRequest, + CreateEndUserRequestTypedDict, + ) from .createguardrailrequest import ( CreateGuardrailRequest, CreateGuardrailRequestTypedDict, @@ -1651,6 +1655,8 @@ from .endpointinfo import EndpointInfo, EndpointInfoTypedDict from .endpointsmetadata import EndpointsMetadata, EndpointsMetadataTypedDict from .endpointstatus import EndpointStatus + from .enduser import EndUser, EndUserTypedDict + from .enduserresponse import EndUserResponse, EndUserResponseTypedDict from .enumcapability import ( EnumCapability, EnumCapabilityType, @@ -2301,6 +2307,10 @@ ListEndpointsResponse, ListEndpointsResponseTypedDict, ) + from .listendusersresponse import ( + ListEndUsersResponse, + ListEndUsersResponseTypedDict, + ) from .listguardrailsresponse import ( ListGuardrailsResponse, ListGuardrailsResponseTypedDict, @@ -4092,6 +4102,10 @@ UpdateBYOKKeyResponse, UpdateBYOKKeyResponseTypedDict, ) + from .updateenduserrequest import ( + UpdateEndUserRequest, + UpdateEndUserRequestTypedDict, + ) from .updateguardrailrequest import ( UpdateGuardrailRequest, UpdateGuardrailRequestTypedDict, @@ -5264,6 +5278,8 @@ "CreateBYOKKeyRequestTypedDict", "CreateBYOKKeyResponse", "CreateBYOKKeyResponseTypedDict", + "CreateEndUserRequest", + "CreateEndUserRequestTypedDict", "CreateGuardrailRequest", "CreateGuardrailRequestTypedDict", "CreateGuardrailResponse", @@ -5433,6 +5449,10 @@ "EmbeddingTypedDict", "Embeddings", "EmbeddingsTypedDict", + "EndUser", + "EndUserResponse", + "EndUserResponseTypedDict", + "EndUserTypedDict", "Endpoint", "EndpointInfo", "EndpointInfoTypedDict", @@ -5918,6 +5938,8 @@ "LegendTypedDict", "ListBYOKKeysResponse", "ListBYOKKeysResponseTypedDict", + "ListEndUsersResponse", + "ListEndUsersResponseTypedDict", "ListEndpointsResponse", "ListEndpointsResponseTypedDict", "ListGuardrailsResponse", @@ -7284,6 +7306,8 @@ "UpdateBYOKKeyRequestTypedDict", "UpdateBYOKKeyResponse", "UpdateBYOKKeyResponseTypedDict", + "UpdateEndUserRequest", + "UpdateEndUserRequestTypedDict", "UpdateGuardrailRequest", "UpdateGuardrailRequestTypedDict", "UpdateGuardrailResponse", @@ -8420,6 +8444,8 @@ "CreateBYOKKeyRequestTypedDict": ".createbyokkeyrequest", "CreateBYOKKeyResponse": ".createbyokkeyresponse", "CreateBYOKKeyResponseTypedDict": ".createbyokkeyresponse", + "CreateEndUserRequest": ".createenduserrequest", + "CreateEndUserRequestTypedDict": ".createenduserrequest", "CreateGuardrailRequest": ".createguardrailrequest", "CreateGuardrailRequestTypedDict": ".createguardrailrequest", "CreateGuardrailResponse": ".createguardrailresponse", @@ -8599,6 +8625,10 @@ "EndpointsMetadata": ".endpointsmetadata", "EndpointsMetadataTypedDict": ".endpointsmetadata", "EndpointStatus": ".endpointstatus", + "EndUser": ".enduser", + "EndUserTypedDict": ".enduser", + "EndUserResponse": ".enduserresponse", + "EndUserResponseTypedDict": ".enduserresponse", "EnumCapability": ".enumcapability", "EnumCapabilityType": ".enumcapability", "EnumCapabilityTypedDict": ".enumcapability", @@ -9075,6 +9105,8 @@ "ArchitectureTypedDict": ".listendpointsresponse", "ListEndpointsResponse": ".listendpointsresponse", "ListEndpointsResponseTypedDict": ".listendpointsresponse", + "ListEndUsersResponse": ".listendusersresponse", + "ListEndUsersResponseTypedDict": ".listendusersresponse", "ListGuardrailsResponse": ".listguardrailsresponse", "ListGuardrailsResponseTypedDict": ".listguardrailsresponse", "ListKeyAssignmentsResponse": ".listkeyassignmentsresponse", @@ -10423,6 +10455,8 @@ "UpdateBYOKKeyRequestTypedDict": ".updatebyokkeyrequest", "UpdateBYOKKeyResponse": ".updatebyokkeyresponse", "UpdateBYOKKeyResponseTypedDict": ".updatebyokkeyresponse", + "UpdateEndUserRequest": ".updateenduserrequest", + "UpdateEndUserRequestTypedDict": ".updateenduserrequest", "UpdateGuardrailRequest": ".updateguardrailrequest", "UpdateGuardrailRequestTypedDict": ".updateguardrailrequest", "UpdateGuardrailResponse": ".updateguardrailresponse", diff --git a/src/openrouter/components/createenduserrequest.py b/src/openrouter/components/createenduserrequest.py new file mode 100644 index 00000000..25623d5f --- /dev/null +++ b/src/openrouter/components/createenduserrequest.py @@ -0,0 +1,15 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from openrouter.types import BaseModel +from typing_extensions import TypedDict + + +class CreateEndUserRequestTypedDict(TypedDict): + user: str + r"""Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths.""" + + +class CreateEndUserRequest(BaseModel): + user: str + r"""Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths.""" diff --git a/src/openrouter/components/enduser.py b/src/openrouter/components/enduser.py new file mode 100644 index 00000000..1b20f1bb --- /dev/null +++ b/src/openrouter/components/enduser.py @@ -0,0 +1,31 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from datetime import datetime +from openrouter.types import BaseModel +from typing_extensions import TypedDict + + +class EndUserTypedDict(TypedDict): + created_at: datetime + r"""Registration creation time.""" + is_active: bool + r"""Whether this registration is active. Not an inference authorization decision.""" + updated_at: datetime + r"""Last registration lifecycle update time.""" + user: str + r"""Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths.""" + + +class EndUser(BaseModel): + created_at: datetime + r"""Registration creation time.""" + + is_active: bool + r"""Whether this registration is active. Not an inference authorization decision.""" + + updated_at: datetime + r"""Last registration lifecycle update time.""" + + user: str + r"""Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths.""" diff --git a/src/openrouter/components/enduserresponse.py b/src/openrouter/components/enduserresponse.py new file mode 100644 index 00000000..04707ad9 --- /dev/null +++ b/src/openrouter/components/enduserresponse.py @@ -0,0 +1,14 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from .enduser import EndUser, EndUserTypedDict +from openrouter.types import BaseModel +from typing_extensions import TypedDict + + +class EndUserResponseTypedDict(TypedDict): + data: EndUserTypedDict + + +class EndUserResponse(BaseModel): + data: EndUser diff --git a/src/openrouter/components/listendusersresponse.py b/src/openrouter/components/listendusersresponse.py new file mode 100644 index 00000000..b2fade2a --- /dev/null +++ b/src/openrouter/components/listendusersresponse.py @@ -0,0 +1,20 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from .enduser import EndUser, EndUserTypedDict +from openrouter.types import BaseModel +from typing import List +from typing_extensions import TypedDict + + +class ListEndUsersResponseTypedDict(TypedDict): + data: List[EndUserTypedDict] + total_count: int + r"""Number of registrations matching the filters before pagination.""" + + +class ListEndUsersResponse(BaseModel): + data: List[EndUser] + + total_count: int + r"""Number of registrations matching the filters before pagination.""" diff --git a/src/openrouter/components/updateenduserrequest.py b/src/openrouter/components/updateenduserrequest.py new file mode 100644 index 00000000..0a8dcb3f --- /dev/null +++ b/src/openrouter/components/updateenduserrequest.py @@ -0,0 +1,15 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from openrouter.types import BaseModel +from typing_extensions import TypedDict + + +class UpdateEndUserRequestTypedDict(TypedDict): + is_active: bool + r"""Registration state only; does not enforce inference access.""" + + +class UpdateEndUserRequest(BaseModel): + is_active: bool + r"""Registration state only; does not enforce inference access.""" diff --git a/src/openrouter/end_users.py b/src/openrouter/end_users.py new file mode 100644 index 00000000..544e6911 --- /dev/null +++ b/src/openrouter/end_users.py @@ -0,0 +1,1485 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from .basesdk import BaseSDK +from jsonpath import JSONPath +from openrouter import components, errors, operations, utils +from openrouter._hooks import HookContext +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, Awaitable, Dict, List, Mapping, Optional, Union + + +class EndUsers(BaseSDK): + r"""End Users endpoints""" + + def list( + self, + *, + http_referer: Optional[str] = None, + x_open_router_title: Optional[str] = None, + x_open_router_categories: Optional[str] = None, + offset: OptionalNullable[int] = 0, + limit: Optional[int] = 50, + user: Optional[str] = None, + include_inactive: Optional[bool] = False, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ) -> Optional[operations.ListEndUsersResponse]: + r"""List registered end users + + List registrations belonging to the authenticated organization. Inactive registrations are excluded by default. [Management key](/docs/guides/overview/auth/management-api-keys) required. + + :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + :param offset: Number of records to skip for pagination + :param limit: Maximum number of records to return (max 100) + :param user: Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths. + :param include_inactive: Include deactivated registrations. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_ms: Override the default request timeout configuration for this method in milliseconds + :param http_headers: Additional headers to set or replace on requests. + """ + base_url = None + url_variables = None + if timeout_ms is None: + timeout_ms = self.sdk_configuration.timeout_ms + + if server_url is not None: + base_url = server_url + else: + base_url = self._get_url(base_url, url_variables) + + request = operations.ListEndUsersRequest( + http_referer=http_referer, + x_open_router_title=x_open_router_title, + x_open_router_categories=x_open_router_categories, + offset=offset, + limit=limit, + user=user, + include_inactive=include_inactive, + ) + + req = self._build_request( + method="GET", + path="/end-users", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + http_headers=http_headers, + _globals=operations.ListEndUsersGlobals( + http_referer=self.sdk_configuration.globals.http_referer, + x_open_router_title=self.sdk_configuration.globals.x_open_router_title, + x_open_router_categories=self.sdk_configuration.globals.x_open_router_categories, + ), + security=self.sdk_configuration.security, + allow_empty_value=None, + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + else: + retries = utils.RetryConfig( + "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True + ) + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["5XX"]) + + http_res = self.do_request( + hook_ctx=HookContext( + config=self.sdk_configuration, + base_url=base_url or "", + operation_id="listEndUsers", + oauth2_scopes=None, + security_source=get_security_from_env( + self.sdk_configuration.security, components.Security + ), + tags=["End Users"], + extensions=None, + ), + request=req, + is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c), + retry_config=retry_config, + ) + + def next_func() -> Optional[operations.ListEndUsersResponse]: + body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]]) + + offset = request.offset if isinstance(request.offset, int) else 0 + + if not http_res.text: + return None + results = JSONPath("$.data").parse(body) + if len(results) == 0 or len(results[0]) == 0: + return None + limit_ = request.limit if isinstance(request.limit, int) else 50 + if len(results[0]) < limit_: + return None + next_offset = offset + len(results[0]) + + return self.list( + http_referer=http_referer, + x_open_router_title=x_open_router_title, + x_open_router_categories=x_open_router_categories, + offset=next_offset, + limit=limit, + user=user, + include_inactive=include_inactive, + retries=retries, + server_url=server_url, + timeout_ms=timeout_ms, + http_headers=http_headers, + ) + + response_data: Any = None + if utils.match_response(http_res, "200", "application/json"): + return operations.ListEndUsersResponse( + result=unmarshal_json_response( + components.ListEndUsersResponse, http_res + ), + next=next_func, + ) + if utils.match_response(http_res, "400", "application/json"): + response_data = unmarshal_json_response( + errors.BadRequestResponseErrorData, http_res + ) + raise errors.BadRequestResponseError(response_data, http_res) + if utils.match_response(http_res, "401", "application/json"): + response_data = unmarshal_json_response( + errors.UnauthorizedResponseErrorData, http_res + ) + raise errors.UnauthorizedResponseError(response_data, http_res) + if utils.match_response(http_res, "404", "application/json"): + response_data = unmarshal_json_response( + errors.NotFoundResponseErrorData, http_res + ) + raise errors.NotFoundResponseError(response_data, http_res) + if utils.match_response(http_res, "500", "application/json"): + response_data = unmarshal_json_response( + errors.InternalServerResponseErrorData, http_res + ) + raise errors.InternalServerResponseError(response_data, http_res) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + if utils.match_response(http_res, "5XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + + raise errors.OpenRouterDefaultError("Unexpected response received", http_res) + + async def list_async( + self, + *, + http_referer: Optional[str] = None, + x_open_router_title: Optional[str] = None, + x_open_router_categories: Optional[str] = None, + offset: OptionalNullable[int] = 0, + limit: Optional[int] = 50, + user: Optional[str] = None, + include_inactive: Optional[bool] = False, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ) -> Optional[operations.ListEndUsersResponse]: + r"""List registered end users + + List registrations belonging to the authenticated organization. Inactive registrations are excluded by default. [Management key](/docs/guides/overview/auth/management-api-keys) required. + + :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + :param offset: Number of records to skip for pagination + :param limit: Maximum number of records to return (max 100) + :param user: Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths. + :param include_inactive: Include deactivated registrations. + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_ms: Override the default request timeout configuration for this method in milliseconds + :param http_headers: Additional headers to set or replace on requests. + """ + base_url = None + url_variables = None + if timeout_ms is None: + timeout_ms = self.sdk_configuration.timeout_ms + + if server_url is not None: + base_url = server_url + else: + base_url = self._get_url(base_url, url_variables) + + request = operations.ListEndUsersRequest( + http_referer=http_referer, + x_open_router_title=x_open_router_title, + x_open_router_categories=x_open_router_categories, + offset=offset, + limit=limit, + user=user, + include_inactive=include_inactive, + ) + + req = self._build_request_async( + method="GET", + path="/end-users", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + http_headers=http_headers, + _globals=operations.ListEndUsersGlobals( + http_referer=self.sdk_configuration.globals.http_referer, + x_open_router_title=self.sdk_configuration.globals.x_open_router_title, + x_open_router_categories=self.sdk_configuration.globals.x_open_router_categories, + ), + security=self.sdk_configuration.security, + allow_empty_value=None, + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + else: + retries = utils.RetryConfig( + "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True + ) + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["5XX"]) + + http_res = await self.do_request_async( + hook_ctx=HookContext( + config=self.sdk_configuration, + base_url=base_url or "", + operation_id="listEndUsers", + oauth2_scopes=None, + security_source=get_security_from_env( + self.sdk_configuration.security, components.Security + ), + tags=["End Users"], + extensions=None, + ), + request=req, + is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c), + retry_config=retry_config, + ) + + def next_func() -> Awaitable[Optional[operations.ListEndUsersResponse]]: + body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]]) + + async def empty_result(): + return None + + offset = request.offset if isinstance(request.offset, int) else 0 + + if not http_res.text: + return empty_result() + results = JSONPath("$.data").parse(body) + if len(results) == 0 or len(results[0]) == 0: + return empty_result() + limit_ = request.limit if isinstance(request.limit, int) else 50 + if len(results[0]) < limit_: + return empty_result() + next_offset = offset + len(results[0]) + + return self.list_async( + http_referer=http_referer, + x_open_router_title=x_open_router_title, + x_open_router_categories=x_open_router_categories, + offset=next_offset, + limit=limit, + user=user, + include_inactive=include_inactive, + retries=retries, + server_url=server_url, + timeout_ms=timeout_ms, + http_headers=http_headers, + ) + + response_data: Any = None + if utils.match_response(http_res, "200", "application/json"): + return operations.ListEndUsersResponse( + result=unmarshal_json_response( + components.ListEndUsersResponse, http_res + ), + next=next_func, + ) + if utils.match_response(http_res, "400", "application/json"): + response_data = unmarshal_json_response( + errors.BadRequestResponseErrorData, http_res + ) + raise errors.BadRequestResponseError(response_data, http_res) + if utils.match_response(http_res, "401", "application/json"): + response_data = unmarshal_json_response( + errors.UnauthorizedResponseErrorData, http_res + ) + raise errors.UnauthorizedResponseError(response_data, http_res) + if utils.match_response(http_res, "404", "application/json"): + response_data = unmarshal_json_response( + errors.NotFoundResponseErrorData, http_res + ) + raise errors.NotFoundResponseError(response_data, http_res) + if utils.match_response(http_res, "500", "application/json"): + response_data = unmarshal_json_response( + errors.InternalServerResponseErrorData, http_res + ) + raise errors.InternalServerResponseError(response_data, http_res) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + if utils.match_response(http_res, "5XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + + raise errors.OpenRouterDefaultError("Unexpected response received", http_res) + + def create( + self, + *, + user: str, + http_referer: Optional[str] = None, + x_open_router_title: Optional[str] = None, + x_open_router_categories: Optional[str] = None, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ) -> components.EndUserResponse: + r"""Register an end user + + Register a caller-supplied tracking ID under the authenticated organization. No login account, policy, or credentials are created. [Management key](/docs/guides/overview/auth/management-api-keys) required. + + :param user: Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths. + :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_ms: Override the default request timeout configuration for this method in milliseconds + :param http_headers: Additional headers to set or replace on requests. + """ + base_url = None + url_variables = None + if timeout_ms is None: + timeout_ms = self.sdk_configuration.timeout_ms + + if server_url is not None: + base_url = server_url + else: + base_url = self._get_url(base_url, url_variables) + + request = operations.CreateEndUserRequest( + http_referer=http_referer, + x_open_router_title=x_open_router_title, + x_open_router_categories=x_open_router_categories, + create_end_user_request=components.CreateEndUserRequest( + user=user, + ), + ) + + req = self._build_request( + method="POST", + path="/end-users", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + http_headers=http_headers, + _globals=operations.CreateEndUserGlobals( + http_referer=self.sdk_configuration.globals.http_referer, + x_open_router_title=self.sdk_configuration.globals.x_open_router_title, + x_open_router_categories=self.sdk_configuration.globals.x_open_router_categories, + ), + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body( + request.create_end_user_request, + False, + False, + "json", + components.CreateEndUserRequest, + ), + allow_empty_value=None, + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + else: + retries = utils.RetryConfig( + "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True + ) + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["5XX"]) + + http_res = self.do_request( + hook_ctx=HookContext( + config=self.sdk_configuration, + base_url=base_url or "", + operation_id="createEndUser", + oauth2_scopes=None, + security_source=get_security_from_env( + self.sdk_configuration.security, components.Security + ), + tags=["End Users"], + extensions=None, + ), + request=req, + is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c), + retry_config=retry_config, + ) + + response_data: Any = None + if utils.match_response(http_res, "201", "application/json"): + return unmarshal_json_response(components.EndUserResponse, http_res) + if utils.match_response(http_res, "400", "application/json"): + response_data = unmarshal_json_response( + errors.BadRequestResponseErrorData, http_res + ) + raise errors.BadRequestResponseError(response_data, http_res) + if utils.match_response(http_res, "401", "application/json"): + response_data = unmarshal_json_response( + errors.UnauthorizedResponseErrorData, http_res + ) + raise errors.UnauthorizedResponseError(response_data, http_res) + if utils.match_response(http_res, "404", "application/json"): + response_data = unmarshal_json_response( + errors.NotFoundResponseErrorData, http_res + ) + raise errors.NotFoundResponseError(response_data, http_res) + if utils.match_response(http_res, "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, "500", "application/json"): + response_data = unmarshal_json_response( + errors.InternalServerResponseErrorData, http_res + ) + raise errors.InternalServerResponseError(response_data, http_res) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + if utils.match_response(http_res, "5XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + + raise errors.OpenRouterDefaultError("Unexpected response received", http_res) + + async def create_async( + self, + *, + user: str, + http_referer: Optional[str] = None, + x_open_router_title: Optional[str] = None, + x_open_router_categories: Optional[str] = None, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ) -> components.EndUserResponse: + r"""Register an end user + + Register a caller-supplied tracking ID under the authenticated organization. No login account, policy, or credentials are created. [Management key](/docs/guides/overview/auth/management-api-keys) required. + + :param user: Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths. + :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_ms: Override the default request timeout configuration for this method in milliseconds + :param http_headers: Additional headers to set or replace on requests. + """ + base_url = None + url_variables = None + if timeout_ms is None: + timeout_ms = self.sdk_configuration.timeout_ms + + if server_url is not None: + base_url = server_url + else: + base_url = self._get_url(base_url, url_variables) + + request = operations.CreateEndUserRequest( + http_referer=http_referer, + x_open_router_title=x_open_router_title, + x_open_router_categories=x_open_router_categories, + create_end_user_request=components.CreateEndUserRequest( + user=user, + ), + ) + + req = self._build_request_async( + method="POST", + path="/end-users", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=False, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + http_headers=http_headers, + _globals=operations.CreateEndUserGlobals( + http_referer=self.sdk_configuration.globals.http_referer, + x_open_router_title=self.sdk_configuration.globals.x_open_router_title, + x_open_router_categories=self.sdk_configuration.globals.x_open_router_categories, + ), + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body( + request.create_end_user_request, + False, + False, + "json", + components.CreateEndUserRequest, + ), + allow_empty_value=None, + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + else: + retries = utils.RetryConfig( + "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True + ) + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["5XX"]) + + http_res = await self.do_request_async( + hook_ctx=HookContext( + config=self.sdk_configuration, + base_url=base_url or "", + operation_id="createEndUser", + oauth2_scopes=None, + security_source=get_security_from_env( + self.sdk_configuration.security, components.Security + ), + tags=["End Users"], + extensions=None, + ), + request=req, + is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c), + retry_config=retry_config, + ) + + response_data: Any = None + if utils.match_response(http_res, "201", "application/json"): + return unmarshal_json_response(components.EndUserResponse, http_res) + if utils.match_response(http_res, "400", "application/json"): + response_data = unmarshal_json_response( + errors.BadRequestResponseErrorData, http_res + ) + raise errors.BadRequestResponseError(response_data, http_res) + if utils.match_response(http_res, "401", "application/json"): + response_data = unmarshal_json_response( + errors.UnauthorizedResponseErrorData, http_res + ) + raise errors.UnauthorizedResponseError(response_data, http_res) + if utils.match_response(http_res, "404", "application/json"): + response_data = unmarshal_json_response( + errors.NotFoundResponseErrorData, http_res + ) + raise errors.NotFoundResponseError(response_data, http_res) + if utils.match_response(http_res, "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, "500", "application/json"): + response_data = unmarshal_json_response( + errors.InternalServerResponseErrorData, http_res + ) + raise errors.InternalServerResponseError(response_data, http_res) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + if utils.match_response(http_res, "5XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + + raise errors.OpenRouterDefaultError("Unexpected response received", http_res) + + def delete( + self, + *, + user: str, + http_referer: Optional[str] = None, + x_open_router_title: Optional[str] = None, + x_open_router_categories: Optional[str] = None, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ): + r"""Deactivate a registered end user + + Soft-deactivate a registration while retaining its tracking ID. Repeat deactivation succeeds. This does not block inference; reactivate through PATCH. [Management key](/docs/guides/overview/auth/management-api-keys) required. + + :param user: Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths. + :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_ms: Override the default request timeout configuration for this method in milliseconds + :param http_headers: Additional headers to set or replace on requests. + """ + base_url = None + url_variables = None + if timeout_ms is None: + timeout_ms = self.sdk_configuration.timeout_ms + + if server_url is not None: + base_url = server_url + else: + base_url = self._get_url(base_url, url_variables) + + request = operations.DeleteEndUserRequest( + http_referer=http_referer, + x_open_router_title=x_open_router_title, + x_open_router_categories=x_open_router_categories, + user=user, + ) + + req = self._build_request( + method="DELETE", + path="/end-users/{user}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + http_headers=http_headers, + _globals=operations.DeleteEndUserGlobals( + http_referer=self.sdk_configuration.globals.http_referer, + x_open_router_title=self.sdk_configuration.globals.x_open_router_title, + x_open_router_categories=self.sdk_configuration.globals.x_open_router_categories, + ), + security=self.sdk_configuration.security, + allow_empty_value=None, + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + else: + retries = utils.RetryConfig( + "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True + ) + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["5XX"]) + + http_res = self.do_request( + hook_ctx=HookContext( + config=self.sdk_configuration, + base_url=base_url or "", + operation_id="deleteEndUser", + oauth2_scopes=None, + security_source=get_security_from_env( + self.sdk_configuration.security, components.Security + ), + tags=["End Users"], + extensions=None, + ), + request=req, + is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c), + retry_config=retry_config, + ) + + response_data: Any = None + if utils.match_response(http_res, "204", "*"): + return + if utils.match_response(http_res, "400", "application/json"): + response_data = unmarshal_json_response( + errors.BadRequestResponseErrorData, http_res + ) + raise errors.BadRequestResponseError(response_data, http_res) + if utils.match_response(http_res, "401", "application/json"): + response_data = unmarshal_json_response( + errors.UnauthorizedResponseErrorData, http_res + ) + raise errors.UnauthorizedResponseError(response_data, http_res) + if utils.match_response(http_res, "404", "application/json"): + response_data = unmarshal_json_response( + errors.NotFoundResponseErrorData, http_res + ) + raise errors.NotFoundResponseError(response_data, http_res) + if utils.match_response(http_res, "500", "application/json"): + response_data = unmarshal_json_response( + errors.InternalServerResponseErrorData, http_res + ) + raise errors.InternalServerResponseError(response_data, http_res) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + if utils.match_response(http_res, "5XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + + raise errors.OpenRouterDefaultError("Unexpected response received", http_res) + + async def delete_async( + self, + *, + user: str, + http_referer: Optional[str] = None, + x_open_router_title: Optional[str] = None, + x_open_router_categories: Optional[str] = None, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ): + r"""Deactivate a registered end user + + Soft-deactivate a registration while retaining its tracking ID. Repeat deactivation succeeds. This does not block inference; reactivate through PATCH. [Management key](/docs/guides/overview/auth/management-api-keys) required. + + :param user: Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths. + :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_ms: Override the default request timeout configuration for this method in milliseconds + :param http_headers: Additional headers to set or replace on requests. + """ + base_url = None + url_variables = None + if timeout_ms is None: + timeout_ms = self.sdk_configuration.timeout_ms + + if server_url is not None: + base_url = server_url + else: + base_url = self._get_url(base_url, url_variables) + + request = operations.DeleteEndUserRequest( + http_referer=http_referer, + x_open_router_title=x_open_router_title, + x_open_router_categories=x_open_router_categories, + user=user, + ) + + req = self._build_request_async( + method="DELETE", + path="/end-users/{user}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + http_headers=http_headers, + _globals=operations.DeleteEndUserGlobals( + http_referer=self.sdk_configuration.globals.http_referer, + x_open_router_title=self.sdk_configuration.globals.x_open_router_title, + x_open_router_categories=self.sdk_configuration.globals.x_open_router_categories, + ), + security=self.sdk_configuration.security, + allow_empty_value=None, + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + else: + retries = utils.RetryConfig( + "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True + ) + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["5XX"]) + + http_res = await self.do_request_async( + hook_ctx=HookContext( + config=self.sdk_configuration, + base_url=base_url or "", + operation_id="deleteEndUser", + oauth2_scopes=None, + security_source=get_security_from_env( + self.sdk_configuration.security, components.Security + ), + tags=["End Users"], + extensions=None, + ), + request=req, + is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c), + retry_config=retry_config, + ) + + response_data: Any = None + if utils.match_response(http_res, "204", "*"): + return + if utils.match_response(http_res, "400", "application/json"): + response_data = unmarshal_json_response( + errors.BadRequestResponseErrorData, http_res + ) + raise errors.BadRequestResponseError(response_data, http_res) + if utils.match_response(http_res, "401", "application/json"): + response_data = unmarshal_json_response( + errors.UnauthorizedResponseErrorData, http_res + ) + raise errors.UnauthorizedResponseError(response_data, http_res) + if utils.match_response(http_res, "404", "application/json"): + response_data = unmarshal_json_response( + errors.NotFoundResponseErrorData, http_res + ) + raise errors.NotFoundResponseError(response_data, http_res) + if utils.match_response(http_res, "500", "application/json"): + response_data = unmarshal_json_response( + errors.InternalServerResponseErrorData, http_res + ) + raise errors.InternalServerResponseError(response_data, http_res) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + if utils.match_response(http_res, "5XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + + raise errors.OpenRouterDefaultError("Unexpected response received", http_res) + + def get( + self, + *, + user: str, + http_referer: Optional[str] = None, + x_open_router_title: Optional[str] = None, + x_open_router_categories: Optional[str] = None, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ) -> components.EndUserResponse: + r"""Get a registered end user + + Retrieve an active or inactive registration by its URL-encoded, caller-supplied tracking ID. [Management key](/docs/guides/overview/auth/management-api-keys) required. + + :param user: Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths. + :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_ms: Override the default request timeout configuration for this method in milliseconds + :param http_headers: Additional headers to set or replace on requests. + """ + base_url = None + url_variables = None + if timeout_ms is None: + timeout_ms = self.sdk_configuration.timeout_ms + + if server_url is not None: + base_url = server_url + else: + base_url = self._get_url(base_url, url_variables) + + request = operations.GetEndUserRequest( + http_referer=http_referer, + x_open_router_title=x_open_router_title, + x_open_router_categories=x_open_router_categories, + user=user, + ) + + req = self._build_request( + method="GET", + path="/end-users/{user}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + http_headers=http_headers, + _globals=operations.GetEndUserGlobals( + http_referer=self.sdk_configuration.globals.http_referer, + x_open_router_title=self.sdk_configuration.globals.x_open_router_title, + x_open_router_categories=self.sdk_configuration.globals.x_open_router_categories, + ), + security=self.sdk_configuration.security, + allow_empty_value=None, + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + else: + retries = utils.RetryConfig( + "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True + ) + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["5XX"]) + + http_res = self.do_request( + hook_ctx=HookContext( + config=self.sdk_configuration, + base_url=base_url or "", + operation_id="getEndUser", + oauth2_scopes=None, + security_source=get_security_from_env( + self.sdk_configuration.security, components.Security + ), + tags=["End Users"], + extensions=None, + ), + request=req, + is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c), + retry_config=retry_config, + ) + + response_data: Any = None + if utils.match_response(http_res, "200", "application/json"): + return unmarshal_json_response(components.EndUserResponse, http_res) + if utils.match_response(http_res, "400", "application/json"): + response_data = unmarshal_json_response( + errors.BadRequestResponseErrorData, http_res + ) + raise errors.BadRequestResponseError(response_data, http_res) + if utils.match_response(http_res, "401", "application/json"): + response_data = unmarshal_json_response( + errors.UnauthorizedResponseErrorData, http_res + ) + raise errors.UnauthorizedResponseError(response_data, http_res) + if utils.match_response(http_res, "404", "application/json"): + response_data = unmarshal_json_response( + errors.NotFoundResponseErrorData, http_res + ) + raise errors.NotFoundResponseError(response_data, http_res) + if utils.match_response(http_res, "500", "application/json"): + response_data = unmarshal_json_response( + errors.InternalServerResponseErrorData, http_res + ) + raise errors.InternalServerResponseError(response_data, http_res) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + if utils.match_response(http_res, "5XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + + raise errors.OpenRouterDefaultError("Unexpected response received", http_res) + + async def get_async( + self, + *, + user: str, + http_referer: Optional[str] = None, + x_open_router_title: Optional[str] = None, + x_open_router_categories: Optional[str] = None, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ) -> components.EndUserResponse: + r"""Get a registered end user + + Retrieve an active or inactive registration by its URL-encoded, caller-supplied tracking ID. [Management key](/docs/guides/overview/auth/management-api-keys) required. + + :param user: Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths. + :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_ms: Override the default request timeout configuration for this method in milliseconds + :param http_headers: Additional headers to set or replace on requests. + """ + base_url = None + url_variables = None + if timeout_ms is None: + timeout_ms = self.sdk_configuration.timeout_ms + + if server_url is not None: + base_url = server_url + else: + base_url = self._get_url(base_url, url_variables) + + request = operations.GetEndUserRequest( + http_referer=http_referer, + x_open_router_title=x_open_router_title, + x_open_router_categories=x_open_router_categories, + user=user, + ) + + req = self._build_request_async( + method="GET", + path="/end-users/{user}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + http_headers=http_headers, + _globals=operations.GetEndUserGlobals( + http_referer=self.sdk_configuration.globals.http_referer, + x_open_router_title=self.sdk_configuration.globals.x_open_router_title, + x_open_router_categories=self.sdk_configuration.globals.x_open_router_categories, + ), + security=self.sdk_configuration.security, + allow_empty_value=None, + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + else: + retries = utils.RetryConfig( + "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True + ) + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["5XX"]) + + http_res = await self.do_request_async( + hook_ctx=HookContext( + config=self.sdk_configuration, + base_url=base_url or "", + operation_id="getEndUser", + oauth2_scopes=None, + security_source=get_security_from_env( + self.sdk_configuration.security, components.Security + ), + tags=["End Users"], + extensions=None, + ), + request=req, + is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c), + retry_config=retry_config, + ) + + response_data: Any = None + if utils.match_response(http_res, "200", "application/json"): + return unmarshal_json_response(components.EndUserResponse, http_res) + if utils.match_response(http_res, "400", "application/json"): + response_data = unmarshal_json_response( + errors.BadRequestResponseErrorData, http_res + ) + raise errors.BadRequestResponseError(response_data, http_res) + if utils.match_response(http_res, "401", "application/json"): + response_data = unmarshal_json_response( + errors.UnauthorizedResponseErrorData, http_res + ) + raise errors.UnauthorizedResponseError(response_data, http_res) + if utils.match_response(http_res, "404", "application/json"): + response_data = unmarshal_json_response( + errors.NotFoundResponseErrorData, http_res + ) + raise errors.NotFoundResponseError(response_data, http_res) + if utils.match_response(http_res, "500", "application/json"): + response_data = unmarshal_json_response( + errors.InternalServerResponseErrorData, http_res + ) + raise errors.InternalServerResponseError(response_data, http_res) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + if utils.match_response(http_res, "5XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + + raise errors.OpenRouterDefaultError("Unexpected response received", http_res) + + def update( + self, + *, + user: str, + is_active: bool, + http_referer: Optional[str] = None, + x_open_router_title: Optional[str] = None, + x_open_router_categories: Optional[str] = None, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ) -> components.EndUserResponse: + r"""Update a registered end user + + Update registration state without changing identity. State changes do not enforce inference access. [Management key](/docs/guides/overview/auth/management-api-keys) required. + + :param user: Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths. + :param is_active: Registration state only; does not enforce inference access. + :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_ms: Override the default request timeout configuration for this method in milliseconds + :param http_headers: Additional headers to set or replace on requests. + """ + base_url = None + url_variables = None + if timeout_ms is None: + timeout_ms = self.sdk_configuration.timeout_ms + + if server_url is not None: + base_url = server_url + else: + base_url = self._get_url(base_url, url_variables) + + request = operations.UpdateEndUserRequest( + http_referer=http_referer, + x_open_router_title=x_open_router_title, + x_open_router_categories=x_open_router_categories, + user=user, + update_end_user_request=components.UpdateEndUserRequest( + is_active=is_active, + ), + ) + + req = self._build_request( + method="PATCH", + path="/end-users/{user}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + http_headers=http_headers, + _globals=operations.UpdateEndUserGlobals( + http_referer=self.sdk_configuration.globals.http_referer, + x_open_router_title=self.sdk_configuration.globals.x_open_router_title, + x_open_router_categories=self.sdk_configuration.globals.x_open_router_categories, + ), + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body( + request.update_end_user_request, + False, + False, + "json", + components.UpdateEndUserRequest, + ), + allow_empty_value=None, + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + else: + retries = utils.RetryConfig( + "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True + ) + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["5XX"]) + + http_res = self.do_request( + hook_ctx=HookContext( + config=self.sdk_configuration, + base_url=base_url or "", + operation_id="updateEndUser", + oauth2_scopes=None, + security_source=get_security_from_env( + self.sdk_configuration.security, components.Security + ), + tags=["End Users"], + extensions=None, + ), + request=req, + is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c), + retry_config=retry_config, + ) + + response_data: Any = None + if utils.match_response(http_res, "200", "application/json"): + return unmarshal_json_response(components.EndUserResponse, http_res) + if utils.match_response(http_res, "400", "application/json"): + response_data = unmarshal_json_response( + errors.BadRequestResponseErrorData, http_res + ) + raise errors.BadRequestResponseError(response_data, http_res) + if utils.match_response(http_res, "401", "application/json"): + response_data = unmarshal_json_response( + errors.UnauthorizedResponseErrorData, http_res + ) + raise errors.UnauthorizedResponseError(response_data, http_res) + if utils.match_response(http_res, "404", "application/json"): + response_data = unmarshal_json_response( + errors.NotFoundResponseErrorData, http_res + ) + raise errors.NotFoundResponseError(response_data, http_res) + if utils.match_response(http_res, "500", "application/json"): + response_data = unmarshal_json_response( + errors.InternalServerResponseErrorData, http_res + ) + raise errors.InternalServerResponseError(response_data, http_res) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + if utils.match_response(http_res, "5XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + + raise errors.OpenRouterDefaultError("Unexpected response received", http_res) + + async def update_async( + self, + *, + user: str, + is_active: bool, + http_referer: Optional[str] = None, + x_open_router_title: Optional[str] = None, + x_open_router_categories: Optional[str] = None, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + http_headers: Optional[Mapping[str, str]] = None, + ) -> components.EndUserResponse: + r"""Update a registered end user + + Update registration state without changing identity. State changes do not enforce inference access. [Management key](/docs/guides/overview/auth/management-api-keys) required. + + :param user: Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths. + :param is_active: Registration state only; does not enforce inference access. + :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_ms: Override the default request timeout configuration for this method in milliseconds + :param http_headers: Additional headers to set or replace on requests. + """ + base_url = None + url_variables = None + if timeout_ms is None: + timeout_ms = self.sdk_configuration.timeout_ms + + if server_url is not None: + base_url = server_url + else: + base_url = self._get_url(base_url, url_variables) + + request = operations.UpdateEndUserRequest( + http_referer=http_referer, + x_open_router_title=x_open_router_title, + x_open_router_categories=x_open_router_categories, + user=user, + update_end_user_request=components.UpdateEndUserRequest( + is_active=is_active, + ), + ) + + req = self._build_request_async( + method="PATCH", + path="/end-users/{user}", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=True, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + http_headers=http_headers, + _globals=operations.UpdateEndUserGlobals( + http_referer=self.sdk_configuration.globals.http_referer, + x_open_router_title=self.sdk_configuration.globals.x_open_router_title, + x_open_router_categories=self.sdk_configuration.globals.x_open_router_categories, + ), + security=self.sdk_configuration.security, + get_serialized_body=lambda: utils.serialize_request_body( + request.update_end_user_request, + False, + False, + "json", + components.UpdateEndUserRequest, + ), + allow_empty_value=None, + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + else: + retries = utils.RetryConfig( + "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True + ) + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["5XX"]) + + http_res = await self.do_request_async( + hook_ctx=HookContext( + config=self.sdk_configuration, + base_url=base_url or "", + operation_id="updateEndUser", + oauth2_scopes=None, + security_source=get_security_from_env( + self.sdk_configuration.security, components.Security + ), + tags=["End Users"], + extensions=None, + ), + request=req, + is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c), + retry_config=retry_config, + ) + + response_data: Any = None + if utils.match_response(http_res, "200", "application/json"): + return unmarshal_json_response(components.EndUserResponse, http_res) + if utils.match_response(http_res, "400", "application/json"): + response_data = unmarshal_json_response( + errors.BadRequestResponseErrorData, http_res + ) + raise errors.BadRequestResponseError(response_data, http_res) + if utils.match_response(http_res, "401", "application/json"): + response_data = unmarshal_json_response( + errors.UnauthorizedResponseErrorData, http_res + ) + raise errors.UnauthorizedResponseError(response_data, http_res) + if utils.match_response(http_res, "404", "application/json"): + response_data = unmarshal_json_response( + errors.NotFoundResponseErrorData, http_res + ) + raise errors.NotFoundResponseError(response_data, http_res) + if utils.match_response(http_res, "500", "application/json"): + response_data = unmarshal_json_response( + errors.InternalServerResponseErrorData, http_res + ) + raise errors.InternalServerResponseError(response_data, http_res) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + if utils.match_response(http_res, "5XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.OpenRouterDefaultError( + "API error occurred", http_res, http_res_text + ) + + raise errors.OpenRouterDefaultError("Unexpected response received", http_res) diff --git a/src/openrouter/operations/__init__.py b/src/openrouter/operations/__init__.py index ee19e0ca..789d0b82 100644 --- a/src/openrouter/operations/__init__.py +++ b/src/openrouter/operations/__init__.py @@ -147,6 +147,12 @@ TypeImageURL, TypeText, ) + from .createenduser import ( + CreateEndUserGlobals, + CreateEndUserGlobalsTypedDict, + CreateEndUserRequest, + CreateEndUserRequestTypedDict, + ) from .createguardrail import ( CreateGuardrailGlobals, CreateGuardrailGlobalsTypedDict, @@ -302,6 +308,12 @@ DeleteBYOKKeyRequest, DeleteBYOKKeyRequestTypedDict, ) + from .deleteenduser import ( + DeleteEndUserGlobals, + DeleteEndUserGlobalsTypedDict, + DeleteEndUserRequest, + DeleteEndUserRequestTypedDict, + ) from .deletefile import ( DeleteFileGlobals, DeleteFileGlobalsTypedDict, @@ -494,6 +506,12 @@ RateLimit, RateLimitTypedDict, ) + from .getenduser import ( + GetEndUserGlobals, + GetEndUserGlobalsTypedDict, + GetEndUserRequest, + GetEndUserRequestTypedDict, + ) from .getfilemetadata import ( GetFileMetadataGlobals, GetFileMetadataGlobalsTypedDict, @@ -722,6 +740,14 @@ ListEndpointsZdrResponse, ListEndpointsZdrResponseTypedDict, ) + from .listendusers import ( + ListEndUsersGlobals, + ListEndUsersGlobalsTypedDict, + ListEndUsersRequest, + ListEndUsersRequestTypedDict, + ListEndUsersResponse, + ListEndUsersResponseTypedDict, + ) from .listfiles import ( ListFilesGlobals, ListFilesGlobalsTypedDict, @@ -1037,6 +1063,12 @@ UpdateBYOKKeyRequest, UpdateBYOKKeyRequestTypedDict, ) + from .updateenduser import ( + UpdateEndUserGlobals, + UpdateEndUserGlobalsTypedDict, + UpdateEndUserRequest, + UpdateEndUserRequestTypedDict, + ) from .updateguardrail import ( UpdateGuardrailGlobals, UpdateGuardrailGlobalsTypedDict, @@ -1221,6 +1253,10 @@ "CreateEmbeddingsResponseTypedDict", "CreateEmbeddingsUsage", "CreateEmbeddingsUsageTypedDict", + "CreateEndUserGlobals", + "CreateEndUserGlobalsTypedDict", + "CreateEndUserRequest", + "CreateEndUserRequestTypedDict", "CreateGuardrailGlobals", "CreateGuardrailGlobalsTypedDict", "CreateGuardrailRequest", @@ -1327,6 +1363,10 @@ "DeleteBatchGlobalsTypedDict", "DeleteBatchRequest", "DeleteBatchRequestTypedDict", + "DeleteEndUserGlobals", + "DeleteEndUserGlobalsTypedDict", + "DeleteEndUserRequest", + "DeleteEndUserRequestTypedDict", "DeleteFileGlobals", "DeleteFileGlobalsTypedDict", "DeleteFileRequest", @@ -1465,6 +1505,10 @@ "GetCurrentKeyRequestTypedDict", "GetCurrentKeyResponse", "GetCurrentKeyResponseTypedDict", + "GetEndUserGlobals", + "GetEndUserGlobalsTypedDict", + "GetEndUserRequest", + "GetEndUserRequestTypedDict", "GetFileMetadataGlobals", "GetFileMetadataGlobalsTypedDict", "GetFileMetadataRequest", @@ -1617,6 +1661,12 @@ "ListEmbeddingsModelsRequestTypedDict", "ListEmbeddingsModelsResponse", "ListEmbeddingsModelsResponseTypedDict", + "ListEndUsersGlobals", + "ListEndUsersGlobalsTypedDict", + "ListEndUsersRequest", + "ListEndUsersRequestTypedDict", + "ListEndUsersResponse", + "ListEndUsersResponseTypedDict", "ListEndpointsGlobals", "ListEndpointsGlobalsTypedDict", "ListEndpointsRequest", @@ -1878,6 +1928,10 @@ "UpdateBYOKKeyGlobalsTypedDict", "UpdateBYOKKeyRequest", "UpdateBYOKKeyRequestTypedDict", + "UpdateEndUserGlobals", + "UpdateEndUserGlobalsTypedDict", + "UpdateEndUserRequest", + "UpdateEndUserRequestTypedDict", "UpdateGuardrailGlobals", "UpdateGuardrailGlobalsTypedDict", "UpdateGuardrailRequest", @@ -2056,6 +2110,10 @@ "PromptTokensDetailsTypedDict": ".createembeddings", "TypeImageURL": ".createembeddings", "TypeText": ".createembeddings", + "CreateEndUserGlobals": ".createenduser", + "CreateEndUserGlobalsTypedDict": ".createenduser", + "CreateEndUserRequest": ".createenduser", + "CreateEndUserRequestTypedDict": ".createenduser", "CreateGuardrailGlobals": ".createguardrail", "CreateGuardrailGlobalsTypedDict": ".createguardrail", "CreateGuardrailRequest": ".createguardrail", @@ -2171,6 +2229,10 @@ "DeleteBYOKKeyGlobalsTypedDict": ".deletebyokkey", "DeleteBYOKKeyRequest": ".deletebyokkey", "DeleteBYOKKeyRequestTypedDict": ".deletebyokkey", + "DeleteEndUserGlobals": ".deleteenduser", + "DeleteEndUserGlobalsTypedDict": ".deleteenduser", + "DeleteEndUserRequest": ".deleteenduser", + "DeleteEndUserRequestTypedDict": ".deleteenduser", "DeleteFileGlobals": ".deletefile", "DeleteFileGlobalsTypedDict": ".deletefile", "DeleteFileRequest": ".deletefile", @@ -2315,6 +2377,10 @@ "GetCurrentKeyResponseTypedDict": ".getcurrentkey", "RateLimit": ".getcurrentkey", "RateLimitTypedDict": ".getcurrentkey", + "GetEndUserGlobals": ".getenduser", + "GetEndUserGlobalsTypedDict": ".getenduser", + "GetEndUserRequest": ".getenduser", + "GetEndUserRequestTypedDict": ".getenduser", "GetFileMetadataGlobals": ".getfilemetadata", "GetFileMetadataGlobalsTypedDict": ".getfilemetadata", "GetFileMetadataRequest": ".getfilemetadata", @@ -2481,6 +2547,12 @@ "ListEndpointsZdrRequestTypedDict": ".listendpointszdr", "ListEndpointsZdrResponse": ".listendpointszdr", "ListEndpointsZdrResponseTypedDict": ".listendpointszdr", + "ListEndUsersGlobals": ".listendusers", + "ListEndUsersGlobalsTypedDict": ".listendusers", + "ListEndUsersRequest": ".listendusers", + "ListEndUsersRequestTypedDict": ".listendusers", + "ListEndUsersResponse": ".listendusers", + "ListEndUsersResponseTypedDict": ".listendusers", "ListFilesGlobals": ".listfiles", "ListFilesGlobalsTypedDict": ".listfiles", "ListFilesRequest": ".listfiles", @@ -2718,6 +2790,10 @@ "UpdateBYOKKeyGlobalsTypedDict": ".updatebyokkey", "UpdateBYOKKeyRequest": ".updatebyokkey", "UpdateBYOKKeyRequestTypedDict": ".updatebyokkey", + "UpdateEndUserGlobals": ".updateenduser", + "UpdateEndUserGlobalsTypedDict": ".updateenduser", + "UpdateEndUserRequest": ".updateenduser", + "UpdateEndUserRequestTypedDict": ".updateenduser", "UpdateGuardrailGlobals": ".updateguardrail", "UpdateGuardrailGlobalsTypedDict": ".updateguardrail", "UpdateGuardrailRequest": ".updateguardrail", diff --git a/src/openrouter/operations/createenduser.py b/src/openrouter/operations/createenduser.py new file mode 100644 index 00000000..9a40dbfc --- /dev/null +++ b/src/openrouter/operations/createenduser.py @@ -0,0 +1,148 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from openrouter.components import ( + createenduserrequest as components_createenduserrequest, +) +from openrouter.types import BaseModel, UNSET_SENTINEL +from openrouter.utils import FieldMetadata, HeaderMetadata, RequestMetadata +import pydantic +from pydantic import model_serializer +from typing import Optional +from typing_extensions import Annotated, NotRequired, TypedDict + + +class CreateEndUserGlobalsTypedDict(TypedDict): + http_referer: NotRequired[str] + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + x_open_router_title: NotRequired[str] + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + x_open_router_categories: NotRequired[str] + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + +class CreateEndUserGlobals(BaseModel): + http_referer: Annotated[ + Optional[str], + pydantic.Field(alias="HTTP-Referer"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + + x_open_router_title: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Title"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + + x_open_router_categories: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Categories"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set( + ["HTTP-Referer", "X-OpenRouter-Title", "X-OpenRouter-Categories"] + ) + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + if val is not None or k not in optional_fields: + m[k] = val + + return m + + +class CreateEndUserRequestTypedDict(TypedDict): + create_end_user_request: ( + components_createenduserrequest.CreateEndUserRequestTypedDict + ) + http_referer: NotRequired[str] + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + x_open_router_title: NotRequired[str] + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + x_open_router_categories: NotRequired[str] + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + +class CreateEndUserRequest(BaseModel): + create_end_user_request: Annotated[ + components_createenduserrequest.CreateEndUserRequest, + FieldMetadata(request=RequestMetadata(media_type="application/json")), + ] + + http_referer: Annotated[ + Optional[str], + pydantic.Field(alias="HTTP-Referer"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + + x_open_router_title: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Title"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + + x_open_router_categories: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Categories"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set( + ["HTTP-Referer", "X-OpenRouter-Title", "X-OpenRouter-Categories"] + ) + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + if val is not None or k not in optional_fields: + m[k] = val + + return m diff --git a/src/openrouter/operations/deleteenduser.py b/src/openrouter/operations/deleteenduser.py new file mode 100644 index 00000000..34d3359a --- /dev/null +++ b/src/openrouter/operations/deleteenduser.py @@ -0,0 +1,144 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from openrouter.types import BaseModel, UNSET_SENTINEL +from openrouter.utils import FieldMetadata, HeaderMetadata, PathParamMetadata +import pydantic +from pydantic import model_serializer +from typing import Optional +from typing_extensions import Annotated, NotRequired, TypedDict + + +class DeleteEndUserGlobalsTypedDict(TypedDict): + http_referer: NotRequired[str] + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + x_open_router_title: NotRequired[str] + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + x_open_router_categories: NotRequired[str] + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + +class DeleteEndUserGlobals(BaseModel): + http_referer: Annotated[ + Optional[str], + pydantic.Field(alias="HTTP-Referer"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + + x_open_router_title: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Title"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + + x_open_router_categories: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Categories"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set( + ["HTTP-Referer", "X-OpenRouter-Title", "X-OpenRouter-Categories"] + ) + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + if val is not None or k not in optional_fields: + m[k] = val + + return m + + +class DeleteEndUserRequestTypedDict(TypedDict): + user: str + r"""Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths.""" + http_referer: NotRequired[str] + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + x_open_router_title: NotRequired[str] + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + x_open_router_categories: NotRequired[str] + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + +class DeleteEndUserRequest(BaseModel): + user: Annotated[ + str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False)) + ] + r"""Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths.""" + + http_referer: Annotated[ + Optional[str], + pydantic.Field(alias="HTTP-Referer"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + + x_open_router_title: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Title"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + + x_open_router_categories: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Categories"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set( + ["HTTP-Referer", "X-OpenRouter-Title", "X-OpenRouter-Categories"] + ) + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + if val is not None or k not in optional_fields: + m[k] = val + + return m diff --git a/src/openrouter/operations/getenduser.py b/src/openrouter/operations/getenduser.py new file mode 100644 index 00000000..ec4817b7 --- /dev/null +++ b/src/openrouter/operations/getenduser.py @@ -0,0 +1,144 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from openrouter.types import BaseModel, UNSET_SENTINEL +from openrouter.utils import FieldMetadata, HeaderMetadata, PathParamMetadata +import pydantic +from pydantic import model_serializer +from typing import Optional +from typing_extensions import Annotated, NotRequired, TypedDict + + +class GetEndUserGlobalsTypedDict(TypedDict): + http_referer: NotRequired[str] + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + x_open_router_title: NotRequired[str] + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + x_open_router_categories: NotRequired[str] + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + +class GetEndUserGlobals(BaseModel): + http_referer: Annotated[ + Optional[str], + pydantic.Field(alias="HTTP-Referer"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + + x_open_router_title: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Title"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + + x_open_router_categories: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Categories"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set( + ["HTTP-Referer", "X-OpenRouter-Title", "X-OpenRouter-Categories"] + ) + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + if val is not None or k not in optional_fields: + m[k] = val + + return m + + +class GetEndUserRequestTypedDict(TypedDict): + user: str + r"""Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths.""" + http_referer: NotRequired[str] + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + x_open_router_title: NotRequired[str] + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + x_open_router_categories: NotRequired[str] + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + +class GetEndUserRequest(BaseModel): + user: Annotated[ + str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False)) + ] + r"""Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths.""" + + http_referer: Annotated[ + Optional[str], + pydantic.Field(alias="HTTP-Referer"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + + x_open_router_title: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Title"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + + x_open_router_categories: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Categories"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set( + ["HTTP-Referer", "X-OpenRouter-Title", "X-OpenRouter-Categories"] + ) + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + if val is not None or k not in optional_fields: + m[k] = val + + return m diff --git a/src/openrouter/operations/listendusers.py b/src/openrouter/operations/listendusers.py new file mode 100644 index 00000000..2997608b --- /dev/null +++ b/src/openrouter/operations/listendusers.py @@ -0,0 +1,202 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from openrouter.components import ( + listendusersresponse as components_listendusersresponse, +) +from openrouter.types import BaseModel, Nullable, OptionalNullable, UNSET_SENTINEL +from openrouter.utils import FieldMetadata, HeaderMetadata, QueryParamMetadata +import pydantic +from pydantic import model_serializer +from typing import Awaitable, Callable, Optional, Union +from typing_extensions import Annotated, NotRequired, TypedDict + + +class ListEndUsersGlobalsTypedDict(TypedDict): + http_referer: NotRequired[str] + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + x_open_router_title: NotRequired[str] + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + x_open_router_categories: NotRequired[str] + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + +class ListEndUsersGlobals(BaseModel): + http_referer: Annotated[ + Optional[str], + pydantic.Field(alias="HTTP-Referer"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + + x_open_router_title: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Title"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + + x_open_router_categories: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Categories"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set( + ["HTTP-Referer", "X-OpenRouter-Title", "X-OpenRouter-Categories"] + ) + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + if val is not None or k not in optional_fields: + m[k] = val + + return m + + +class ListEndUsersRequestTypedDict(TypedDict): + http_referer: NotRequired[str] + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + x_open_router_title: NotRequired[str] + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + x_open_router_categories: NotRequired[str] + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + offset: NotRequired[Nullable[int]] + r"""Number of records to skip for pagination""" + limit: NotRequired[int] + r"""Maximum number of records to return (max 100)""" + user: NotRequired[str] + r"""Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths.""" + include_inactive: NotRequired[bool] + r"""Include deactivated registrations.""" + + +class ListEndUsersRequest(BaseModel): + http_referer: Annotated[ + Optional[str], + pydantic.Field(alias="HTTP-Referer"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + + x_open_router_title: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Title"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + + x_open_router_categories: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Categories"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + offset: Annotated[ + OptionalNullable[int], + FieldMetadata(query=QueryParamMetadata(style="form", explode=True)), + ] = 0 + r"""Number of records to skip for pagination""" + + limit: Annotated[ + Optional[int], + FieldMetadata(query=QueryParamMetadata(style="form", explode=True)), + ] = 50 + r"""Maximum number of records to return (max 100)""" + + user: Annotated[ + Optional[str], + FieldMetadata(query=QueryParamMetadata(style="form", explode=True)), + ] = None + r"""Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths.""" + + include_inactive: Annotated[ + Optional[bool], + FieldMetadata(query=QueryParamMetadata(style="form", explode=True)), + ] = False + r"""Include deactivated registrations.""" + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set( + [ + "HTTP-Referer", + "X-OpenRouter-Title", + "X-OpenRouter-Categories", + "offset", + "limit", + "user", + "include_inactive", + ] + ) + nullable_fields = set(["offset"]) + 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)) + is_nullable_and_explicitly_set = ( + k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member + ) + + if val != UNSET_SENTINEL: + if ( + val is not None + or k not in optional_fields + or is_nullable_and_explicitly_set + ): + m[k] = val + + return m + + +class ListEndUsersResponseTypedDict(TypedDict): + result: components_listendusersresponse.ListEndUsersResponseTypedDict + + +class ListEndUsersResponse(BaseModel): + next: Union[ + Callable[[], Optional[ListEndUsersResponse]], + Callable[[], Awaitable[Optional[ListEndUsersResponse]]], + ] + + result: components_listendusersresponse.ListEndUsersResponse diff --git a/src/openrouter/operations/updateenduser.py b/src/openrouter/operations/updateenduser.py new file mode 100644 index 00000000..2e0d7cce --- /dev/null +++ b/src/openrouter/operations/updateenduser.py @@ -0,0 +1,160 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from openrouter.components import ( + updateenduserrequest as components_updateenduserrequest, +) +from openrouter.types import BaseModel, UNSET_SENTINEL +from openrouter.utils import ( + FieldMetadata, + HeaderMetadata, + PathParamMetadata, + RequestMetadata, +) +import pydantic +from pydantic import model_serializer +from typing import Optional +from typing_extensions import Annotated, NotRequired, TypedDict + + +class UpdateEndUserGlobalsTypedDict(TypedDict): + http_referer: NotRequired[str] + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + x_open_router_title: NotRequired[str] + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + x_open_router_categories: NotRequired[str] + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + +class UpdateEndUserGlobals(BaseModel): + http_referer: Annotated[ + Optional[str], + pydantic.Field(alias="HTTP-Referer"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + + x_open_router_title: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Title"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + + x_open_router_categories: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Categories"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set( + ["HTTP-Referer", "X-OpenRouter-Title", "X-OpenRouter-Categories"] + ) + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + if val is not None or k not in optional_fields: + m[k] = val + + return m + + +class UpdateEndUserRequestTypedDict(TypedDict): + user: str + r"""Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths.""" + update_end_user_request: ( + components_updateenduserrequest.UpdateEndUserRequestTypedDict + ) + http_referer: NotRequired[str] + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + x_open_router_title: NotRequired[str] + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + x_open_router_categories: NotRequired[str] + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + +class UpdateEndUserRequest(BaseModel): + user: Annotated[ + str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False)) + ] + r"""Immutable case-sensitive tracking string supplied as user on inference requests. URL-encode it in resource paths.""" + + update_end_user_request: Annotated[ + components_updateenduserrequest.UpdateEndUserRequest, + FieldMetadata(request=RequestMetadata(media_type="application/json")), + ] + + http_referer: Annotated[ + Optional[str], + pydantic.Field(alias="HTTP-Referer"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app identifier should be your app's URL and is used as the primary identifier for rankings. + This is used to track API usage per application. + + """ + + x_open_router_title: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Title"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard. + + """ + + x_open_router_categories: Annotated[ + Optional[str], + pydantic.Field(alias="X-OpenRouter-Categories"), + FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), + ] = None + r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings. + + """ + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set( + ["HTTP-Referer", "X-OpenRouter-Title", "X-OpenRouter-Categories"] + ) + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + if val is not None or k not in optional_fields: + m[k] = val + + return m diff --git a/src/openrouter/sdk.py b/src/openrouter/sdk.py index 0a110f2c..8d7b90d7 100644 --- a/src/openrouter/sdk.py +++ b/src/openrouter/sdk.py @@ -29,6 +29,7 @@ from openrouter.credits import Credits from openrouter.datasets import Datasets from openrouter.embeddings import Embeddings + from openrouter.end_users import EndUsers from openrouter.endpoints import Endpoints from openrouter.files import Files from openrouter.generations import Generations @@ -85,6 +86,8 @@ class OpenRouter(BaseSDK): r"""Public OpenRouter usage datasets. Data returned by these endpoints is licensed under CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/): reuse and republish it, including commercially, with attribution to OpenRouter.""" embeddings: "Embeddings" r"""Text embedding endpoints""" + end_users: "EndUsers" + r"""End Users endpoints""" endpoints: "Endpoints" r"""Endpoint information""" files: "Files" @@ -143,6 +146,7 @@ class OpenRouter(BaseSDK): "credits": ("openrouter.credits", "Credits"), "datasets": ("openrouter.datasets", "Datasets"), "embeddings": ("openrouter.embeddings", "Embeddings"), + "end_users": ("openrouter.end_users", "EndUsers"), "endpoints": ("openrouter.endpoints", "Endpoints"), "files": ("openrouter.files", "Files"), "generations": ("openrouter.generations", "Generations"), diff --git a/uv.lock b/uv.lock index 519369b6..49ff3b94 100644 --- a/uv.lock +++ b/uv.lock @@ -213,7 +213,7 @@ wheels = [ [[package]] name = "openrouter" -version = "1.3.11" +version = "1.3.12" source = { editable = "." } dependencies = [ { name = "httpcore" }, From c950268c1d6da038e8019d965d1ee0dd3c30f3f4 Mon Sep 17 00:00:00 2001 From: "speakeasy-github[bot]" <128539517+speakeasy-github[bot]@users.noreply.github.com> Date: Wed, 30 Sep 2026 18:09:44 +0000 Subject: [PATCH 2/3] empty commit to trigger [run-tests] workflow From 348378ef74127a3fcd49a98d0093481f252ccfea Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 30 Sep 2026 18:10:00 +0000 Subject: [PATCH 3/3] Chore: regenerate docs navigation Auto-generated-by: update-generated-files-action; https://github.com/OpenRouterTeam/python-sdk/actions/runs/36756596341 --- docs/docs.json | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/docs.json b/docs/docs.json index b16f280d..184dd7de 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -24,6 +24,7 @@ "sdks/decisions/README", "sdks/embeddings/README", "sdks/endpoints/README", + "sdks/endusers/README", "sdks/files/README", "sdks/generations/README", "sdks/guardrails/README",