From c137f68c5dd1105f5fb8f34e741b8d911cb22c32 Mon Sep 17 00:00:00 2001 From: nezhyborets Date: Fri, 19 Jun 2026 01:06:13 +0300 Subject: [PATCH 1/9] Update openapi spec --- openapi.with-code-samples.yml => openapi.yaml | 8795 +++++++++++++++-- 1 file changed, 8120 insertions(+), 675 deletions(-) rename openapi.with-code-samples.yml => openapi.yaml (89%) diff --git a/openapi.with-code-samples.yml b/openapi.yaml similarity index 89% rename from openapi.with-code-samples.yml rename to openapi.yaml index 8ec4305b..ccc56933 100644 --- a/openapi.with-code-samples.yml +++ b/openapi.yaml @@ -9467,7 +9467,11 @@ paths: can be up to 512 MB, and each project can store up to 2.5 TB of files in - total. There is no organization-wide storage limit. + total. There is no organization-wide storage limit. Uploads to this + + endpoint are rate-limited to 1,000 requests per minute per authenticated + + user. - The Assistants API supports files up to 2 million tokens and of @@ -9482,6 +9486,12 @@ paths: input also has a specific required [format](/docs/api-reference/batch/request-input). + - For Retrieval or `file_search` ingestion, upload files here first. If + you need to attach multiple uploaded files to the same vector store, use + [`/vector_stores/{vector_store_id}/file_batches`](/docs/api-reference/vector-stores-file-batches/createBatch) + instead of attaching them one by one. Vector store attachment has separate + limits from file upload, including 2,000 attached files per minute per + organization. Please [contact us](https://help.openai.com/) if you need to increase these @@ -9503,6 +9513,13 @@ paths: x-oaiMeta: name: Upload file group: files + description: > + Uploads a file for later use across OpenAI APIs. Uploads to this + endpoint are rate-limited to 1,000 requests per minute per + authenticated user. For Retrieval or `file_search` ingestion, upload + files here first. If you need to attach multiple uploaded files to the + same vector store, use vector store file batches instead of attaching + them one by one. examples: request: curl: | @@ -11418,7 +11435,7 @@ paths: "usage_metrics": null, "shared_with_openai": false } - + - title: Validation file request: curl: | @@ -13481,7 +13498,7 @@ paths: async function main() { const model = await openai.models.delete("ft:gpt-4o-mini:acemeco:suffix:abc123"); - + console.log(model); } main(); @@ -13895,6 +13912,8 @@ paths: } /organization/admin_api_keys: get: + security: + - AdminApiKeyAuth: [] summary: List organization API keys operationId: admin-api-keys-list description: Retrieve a paginated list of organization admin API keys. @@ -13943,6 +13962,64 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + // Automatically fetches more pages as needed. + + for await (const adminAPIKey of + client.admin.organization.adminAPIKeys.list()) { + console.log(adminAPIKey.id); + } + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + page = client.admin.organization.admin_api_keys.list() + page = page.data[0] + print(page.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tpage, err := client.Admin.Organization.AdminAPIKeys.List(context.TODO(), openai.AdminOrganizationAdminAPIKeyListParams{})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", page)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.adminapikeys.AdminApiKeyListPage; + + import + com.openai.models.admin.organization.adminapikeys.AdminApiKeyListParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + AdminApiKeyListPage page = client.admin().organization().adminApiKeys().list(); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + page = openai.admin.organization.admin_api_keys.list + + puts(page) response: | { "object": "list", @@ -13969,6 +14046,8 @@ paths: "has_more": false } post: + security: + - AdminApiKeyAuth: [] summary: Create an organization admin API key operationId: admin-api-keys-create description: Create a new admin-level API key for the organization. @@ -13990,7 +14069,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/AdminApiKey' + $ref: '#/components/schemas/AdminApiKeyCreateResponse' x-oaiMeta: name: Create admin API key group: administration @@ -14004,6 +14083,73 @@ paths: -d '{ "name": "New Admin Key" }' + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const adminAPIKey = await + client.admin.organization.adminAPIKeys.create({ name: 'New Admin + Key' }); + + + console.log(adminAPIKey); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + admin_api_key = client.admin.organization.admin_api_keys.create( + name="New Admin Key", + ) + print(admin_api_key) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tadminAPIKey, err := client.Admin.Organization.AdminAPIKeys.New(context.TODO(), openai.AdminOrganizationAdminAPIKeyNewParams{\n\t\tName: \"New Admin Key\",\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", adminAPIKey)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.adminapikeys.AdminApiKeyCreateParams; + + import + com.openai.models.admin.organization.adminapikeys.AdminApiKeyCreateResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + AdminApiKeyCreateParams params = AdminApiKeyCreateParams.builder() + .name("New Admin Key") + .build(); + AdminApiKeyCreateResponse adminApiKey = client.admin().organization().adminApiKeys().create(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + admin_api_key = + openai.admin.organization.admin_api_keys.create(name: "New Admin + Key") + + + puts(admin_api_key) response: | { "object": "organization.admin_api_key", @@ -14024,6 +14170,8 @@ paths: } /organization/admin_api_keys/{key_id}: get: + security: + - AdminApiKeyAuth: [] summary: Retrieve a single organization API key operationId: admin-api-keys-get description: Get details for a specific organization API key by its ID. @@ -14051,6 +14199,68 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const adminAPIKey = await + client.admin.organization.adminAPIKeys.retrieve('key_id'); + + + console.log(adminAPIKey.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + admin_api_key = client.admin.organization.admin_api_keys.retrieve( + "key_id", + ) + print(admin_api_key.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tadminAPIKey, err := client.Admin.Organization.AdminAPIKeys.Get(context.TODO(), \"key_id\")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", adminAPIKey.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.adminapikeys.AdminApiKey; + + import + com.openai.models.admin.organization.adminapikeys.AdminApiKeyRetrieveParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + AdminApiKey adminApiKey = client.admin().organization().adminApiKeys().retrieve("key_id"); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + admin_api_key = + openai.admin.organization.admin_api_keys.retrieve("key_id") + + + puts(admin_api_key) response: | { "object": "organization.admin_api_key", @@ -14069,6 +14279,8 @@ paths: } } delete: + security: + - AdminApiKeyAuth: [] summary: Delete an organization admin API key operationId: admin-api-keys-delete description: Delete the specified admin API key. @@ -14092,10 +14304,17 @@ paths: example: key_abc object: type: string + enum: + - organization.admin_api_key.deleted example: organization.admin_api_key.deleted + x-stainless-const: true deleted: type: boolean example: true + required: + - id + - object + - deleted x-oaiMeta: name: Delete admin API key group: administration @@ -14106,6 +14325,68 @@ paths: https://api.openai.com/v1/organization/admin_api_keys/key_abc \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const adminAPIKey = await + client.admin.organization.adminAPIKeys.delete('key_id'); + + + console.log(adminAPIKey.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + admin_api_key = client.admin.organization.admin_api_keys.delete( + "key_id", + ) + print(admin_api_key.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tadminAPIKey, err := client.Admin.Organization.AdminAPIKeys.Delete(context.TODO(), \"key_id\")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", adminAPIKey.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.adminapikeys.AdminApiKeyDeleteParams; + + import + com.openai.models.admin.organization.adminapikeys.AdminApiKeyDeleteResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + AdminApiKeyDeleteResponse adminApiKey = client.admin().organization().adminApiKeys().delete("key_id"); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + admin_api_key = + openai.admin.organization.admin_api_keys.delete("key_id") + + + puts(admin_api_key) response: | { "id": "key_abc", @@ -14114,6 +14395,8 @@ paths: } /organization/audit_logs: get: + security: + - AdminApiKeyAuth: [] summary: List user actions and configuration changes within this organization. operationId: list-audit-logs tags: @@ -14239,6 +14522,64 @@ paths: curl https://api.openai.com/v1/organization/audit_logs \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + // Automatically fetches more pages as needed. + + for await (const auditLogListResponse of + client.admin.organization.auditLogs.list()) { + console.log(auditLogListResponse.id); + } + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + page = client.admin.organization.audit_logs.list() + page = page.data[0] + print(page.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tpage, err := client.Admin.Organization.AuditLogs.List(context.TODO(), openai.AdminOrganizationAuditLogListParams{})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", page)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.auditlogs.AuditLogListPage; + + import + com.openai.models.admin.organization.auditlogs.AuditLogListParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + AuditLogListPage page = client.admin().organization().auditLogs().list(); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + page = openai.admin.organization.audit_logs.list + + puts(page) response: | { "object": "list", @@ -14301,6 +14642,8 @@ paths: } /organization/certificates: get: + security: + - AdminApiKeyAuth: [] summary: List uploaded certificates for this organization. operationId: listOrganizationCertificates tags: @@ -14351,6 +14694,64 @@ paths: curl: | curl https://api.openai.com/v1/organization/certificates \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + // Automatically fetches more pages as needed. + + for await (const certificateListResponse of + client.admin.organization.certificates.list()) { + console.log(certificateListResponse.id); + } + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + page = client.admin.organization.certificates.list() + page = page.data[0] + print(page.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tpage, err := client.Admin.Organization.Certificates.List(context.TODO(), openai.AdminOrganizationCertificateListParams{})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", page)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.certificates.CertificateListPage; + + import + com.openai.models.admin.organization.certificates.CertificateListParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + CertificateListPage page = client.admin().organization().certificates().list(); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + page = openai.admin.organization.certificates.list + + puts(page) response: | { "object": "list", @@ -14372,6 +14773,8 @@ paths: "has_more": false } post: + security: + - AdminApiKeyAuth: [] summary: > Upload a certificate to the organization. This does **not** automatically activate the certificate. @@ -14408,6 +14811,74 @@ paths: "name": "My Example Certificate", "certificate": "-----BEGIN CERTIFICATE-----\\nMIIDeT...\\n-----END CERTIFICATE-----" }' + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const certificate = await + client.admin.organization.certificates.create({ + certificate: 'certificate', + }); + + + console.log(certificate.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + certificate = client.admin.organization.certificates.create( + certificate="certificate", + ) + print(certificate.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tcertificate, err := client.Admin.Organization.Certificates.New(context.TODO(), openai.AdminOrganizationCertificateNewParams{\n\t\tCertificate: \"certificate\",\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", certificate.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.certificates.Certificate; + + import + com.openai.models.admin.organization.certificates.CertificateCreateParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + CertificateCreateParams params = CertificateCreateParams.builder() + .certificate("certificate") + .build(); + Certificate certificate = client.admin().organization().certificates().create(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + certificate = + openai.admin.organization.certificates.create(certificate: + "certificate") + + + puts(certificate) response: | { "object": "certificate", @@ -14421,6 +14892,8 @@ paths: } /organization/certificates/activate: post: + security: + - AdminApiKeyAuth: [] summary: > Activate certificates at the organization level. @@ -14443,7 +14916,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/ListCertificatesResponse' + $ref: '#/components/schemas/OrganizationCertificateActivationResponse' x-oaiMeta: name: Activate certificates for organization group: administration @@ -14458,8 +14931,78 @@ paths: -H "Content-Type: application/json" \ -d '{ - "data": ["cert_abc", "cert_def"] + "certificate_ids": ["cert_abc", "cert_def"] }' + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + // Automatically fetches more pages as needed. + + for await (const certificateActivateResponse of + client.admin.organization.certificates.activate({ + certificate_ids: ['cert_abc'], + })) { + console.log(certificateActivateResponse.id); + } + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + page = client.admin.organization.certificates.activate( + certificate_ids=["cert_abc"], + ) + page = page.data[0] + print(page.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tpage, err := client.Admin.Organization.Certificates.Activate(context.TODO(), openai.AdminOrganizationCertificateActivateParams{\n\t\tCertificateIDs: []string{\"cert_abc\"},\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", page)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.certificates.CertificateActivatePage; + + import + com.openai.models.admin.organization.certificates.CertificateActivateParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + CertificateActivateParams params = CertificateActivateParams.builder() + .addCertificateId("cert_abc") + .build(); + CertificateActivatePage page = client.admin().organization().certificates().activate(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + page = + openai.admin.organization.certificates.activate(certificate_ids: + ["cert_abc"]) + + + puts(page) response: | { "object": "organization.certificate.activation", @@ -14490,6 +15033,8 @@ paths: } /organization/certificates/deactivate: post: + security: + - AdminApiKeyAuth: [] summary: > Deactivate certificates at the organization level. @@ -14512,7 +15057,8 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/ListCertificatesResponse' + $ref: >- + #/components/schemas/OrganizationCertificateDeactivationResponse x-oaiMeta: name: Deactivate certificates for organization group: administration @@ -14527,8 +15073,78 @@ paths: -H "Content-Type: application/json" \ -d '{ - "data": ["cert_abc", "cert_def"] + "certificate_ids": ["cert_abc", "cert_def"] }' + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + // Automatically fetches more pages as needed. + + for await (const certificateDeactivateResponse of + client.admin.organization.certificates.deactivate( + { certificate_ids: ['cert_abc'] }, + )) { + console.log(certificateDeactivateResponse.id); + } + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + page = client.admin.organization.certificates.deactivate( + certificate_ids=["cert_abc"], + ) + page = page.data[0] + print(page.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tpage, err := client.Admin.Organization.Certificates.Deactivate(context.TODO(), openai.AdminOrganizationCertificateDeactivateParams{\n\t\tCertificateIDs: []string{\"cert_abc\"},\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", page)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.certificates.CertificateDeactivatePage; + + import + com.openai.models.admin.organization.certificates.CertificateDeactivateParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + CertificateDeactivateParams params = CertificateDeactivateParams.builder() + .addCertificateId("cert_abc") + .build(); + CertificateDeactivatePage page = client.admin().organization().certificates().deactivate(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + page = + openai.admin.organization.certificates.deactivate(certificate_ids: + ["cert_abc"]) + + + puts(page) response: | { "object": "organization.certificate.deactivation", @@ -14559,6 +15175,8 @@ paths: } /organization/certificates/{certificate_id}: get: + security: + - AdminApiKeyAuth: [] summary: | Get a certificate that has been uploaded to the organization. @@ -14604,6 +15222,68 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const certificate = await + client.admin.organization.certificates.retrieve('certificate_id'); + + + console.log(certificate.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + certificate = client.admin.organization.certificates.retrieve( + certificate_id="certificate_id", + ) + print(certificate.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tcertificate, err := client.Admin.Organization.Certificates.Get(\n\t\tcontext.TODO(),\n\t\t\"certificate_id\",\n\t\topenai.AdminOrganizationCertificateGetParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", certificate.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.certificates.Certificate; + + import + com.openai.models.admin.organization.certificates.CertificateRetrieveParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + Certificate certificate = client.admin().organization().certificates().retrieve("certificate_id"); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + certificate = + openai.admin.organization.certificates.retrieve("certificate_id") + + + puts(certificate) response: | { "object": "certificate", @@ -14617,6 +15297,8 @@ paths: } } post: + security: + - AdminApiKeyAuth: [] summary: | Modify a certificate. Note that only the name can be modified. operationId: modifyCertificate @@ -14659,6 +15341,68 @@ paths: -d '{ "name": "Renamed Certificate" }' + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const certificate = await + client.admin.organization.certificates.update('certificate_id'); + + + console.log(certificate.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + certificate = client.admin.organization.certificates.update( + certificate_id="certificate_id", + ) + print(certificate.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tcertificate, err := client.Admin.Organization.Certificates.Update(\n\t\tcontext.TODO(),\n\t\t\"certificate_id\",\n\t\topenai.AdminOrganizationCertificateUpdateParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", certificate.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.certificates.Certificate; + + import + com.openai.models.admin.organization.certificates.CertificateUpdateParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + Certificate certificate = client.admin().organization().certificates().update("certificate_id"); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + certificate = + openai.admin.organization.certificates.update("certificate_id") + + + puts(certificate) response: | { "object": "certificate", @@ -14671,6 +15415,8 @@ paths: } } delete: + security: + - AdminApiKeyAuth: [] summary: | Delete a certificate from the organization. @@ -14702,6 +15448,68 @@ paths: https://api.openai.com/v1/organization/certificates/cert_abc \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const certificate = await + client.admin.organization.certificates.delete('certificate_id'); + + + console.log(certificate.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + certificate = client.admin.organization.certificates.delete( + "certificate_id", + ) + print(certificate.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tcertificate, err := client.Admin.Organization.Certificates.Delete(context.TODO(), \"certificate_id\")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", certificate.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.certificates.CertificateDeleteParams; + + import + com.openai.models.admin.organization.certificates.CertificateDeleteResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + CertificateDeleteResponse certificate = client.admin().organization().certificates().delete("certificate_id"); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + certificate = + openai.admin.organization.certificates.delete("certificate_id") + + + puts(certificate) response: | { "object": "certificate.deleted", @@ -14709,6 +15517,8 @@ paths: } /organization/costs: get: + security: + - AdminApiKeyAuth: [] summary: Get costs details for the organization. operationId: usage-costs tags: @@ -14745,11 +15555,19 @@ paths: type: array items: type: string + - name: api_key_ids + in: query + description: Return only costs for these API keys. + required: false + schema: + type: array + items: + type: string - name: group_by in: query description: >- Group the costs by the specified fields. Support fields include - `project_id`, `line_item` and any combination of them. + `project_id`, `line_item`, `api_key_id` and any combination of them. required: false schema: type: array @@ -14758,6 +15576,7 @@ paths: enum: - project_id - line_item + - api_key_id - name: limit in: query description: > @@ -14794,6 +15613,67 @@ paths: -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const response = await client.admin.organization.usage.costs({ + start_time: 0 }); + + + console.log(response.data); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + response = client.admin.organization.usage.costs( + start_time=0, + ) + print(response.data) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tresponse, err := client.Admin.Organization.Usage.Costs(context.TODO(), openai.AdminOrganizationUsageCostsParams{\n\t\tStartTime: 0,\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", response.Data)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.usage.UsageCostsParams; + + import + com.openai.models.admin.organization.usage.UsageCostsResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + UsageCostsParams params = UsageCostsParams.builder() + .startTime(0L) + .build(); + UsageCostsResponse response = client.admin().organization().usage().costs(params); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + response = openai.admin.organization.usage.costs(start_time: 0) + + puts(response) response: | { "object": "page", @@ -14810,7 +15690,9 @@ paths: "currency": "usd" }, "line_item": null, - "project_id": null + "project_id": null, + "api_key_id": null, + "quantity": null } ] } @@ -14820,6 +15702,8 @@ paths: } /organization/groups: get: + security: + - AdminApiKeyAuth: [] summary: Lists all groups in the organization. operationId: list-groups tags: @@ -14874,6 +15758,63 @@ paths: https://api.openai.com/v1/organization/groups?limit=20&order=asc \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + // Automatically fetches more pages as needed. + + for await (const group of client.admin.organization.groups.list()) + { + console.log(group.id); + } + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + page = client.admin.organization.groups.list() + page = page.data[0] + print(page.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tpage, err := client.Admin.Organization.Groups.List(context.TODO(), openai.AdminOrganizationGroupListParams{})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", page)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import com.openai.models.admin.organization.groups.GroupListPage; + + import + com.openai.models.admin.organization.groups.GroupListParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + GroupListPage page = client.admin().organization().groups().list(); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + page = openai.admin.organization.groups.list + + puts(page) response: | { "object": "list", @@ -14890,6 +15831,8 @@ paths: "next": null } post: + security: + - AdminApiKeyAuth: [] summary: Creates a new group in the organization. operationId: create-group tags: @@ -14920,6 +15863,66 @@ paths: -d '{ "name": "Support Team" }' + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const group = await client.admin.organization.groups.create({ + name: 'x' }); + + + console.log(group.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + group = client.admin.organization.groups.create( + name="x", + ) + print(group.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tgroup, err := client.Admin.Organization.Groups.New(context.TODO(), openai.AdminOrganizationGroupNewParams{\n\t\tName: \"x\",\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", group.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import com.openai.models.admin.organization.groups.Group; + + import + com.openai.models.admin.organization.groups.GroupCreateParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + GroupCreateParams params = GroupCreateParams.builder() + .name("x") + .build(); + Group group = client.admin().organization().groups().create(params); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + group = openai.admin.organization.groups.create(name: "x") + + puts(group) response: | { "object": "group", @@ -14930,6 +15933,8 @@ paths: } /organization/groups/{group_id}: post: + security: + - AdminApiKeyAuth: [] summary: Updates a group's information. operationId: update-group tags: @@ -14969,6 +15974,74 @@ paths: -d '{ "name": "Escalations" }' + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const group = await + client.admin.organization.groups.update('group_id', { name: 'x' + }); + + + console.log(group.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + group = client.admin.organization.groups.update( + group_id="group_id", + name="x", + ) + print(group.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tgroup, err := client.Admin.Organization.Groups.Update(\n\t\tcontext.TODO(),\n\t\t\"group_id\",\n\t\topenai.AdminOrganizationGroupUpdateParams{\n\t\t\tName: \"x\",\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", group.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.groups.GroupUpdateParams; + + import + com.openai.models.admin.organization.groups.GroupUpdateResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + GroupUpdateParams params = GroupUpdateParams.builder() + .groupId("group_id") + .name("x") + .build(); + GroupUpdateResponse group = client.admin().organization().groups().update(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + group = openai.admin.organization.groups.update("group_id", name: + "x") + + + puts(group) response: | { "id": "group_01J1F8ABCDXYZ", @@ -14977,6 +16050,8 @@ paths: "is_scim_managed": false } delete: + security: + - AdminApiKeyAuth: [] summary: Deletes a group from the organization. operationId: delete-group tags: @@ -15006,25 +16081,85 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" - response: | - { - "object": "group.deleted", - "id": "group_01J1F8ABCDXYZ", - "deleted": true - } - /organization/groups/{group_id}/roles: - get: - summary: >- - Lists the organization roles assigned to a group within the - organization. - operationId: list-group-role-assignments - tags: - - Group organization role assignments - parameters: - - name: group_id - in: path - description: >- - The ID of the group whose organization role assignments you want to + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const group = await + client.admin.organization.groups.delete('group_id'); + + + console.log(group.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + group = client.admin.organization.groups.delete( + "group_id", + ) + print(group.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tgroup, err := client.Admin.Organization.Groups.Delete(context.TODO(), \"group_id\")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", group.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.groups.GroupDeleteParams; + + import + com.openai.models.admin.organization.groups.GroupDeleteResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + GroupDeleteResponse group = client.admin().organization().groups().delete("group_id"); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + group = openai.admin.organization.groups.delete("group_id") + + puts(group) + response: | + { + "object": "group.deleted", + "id": "group_01J1F8ABCDXYZ", + "deleted": true + } + /organization/groups/{group_id}/roles: + get: + security: + - AdminApiKeyAuth: [] + summary: >- + Lists the organization roles assigned to a group within the + organization. + operationId: list-group-role-assignments + tags: + - Group organization role assignments + parameters: + - name: group_id + in: path + description: >- + The ID of the group whose organization role assignments you want to list. required: true schema: @@ -15072,6 +16207,66 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + // Automatically fetches more pages as needed. + + for await (const roleListResponse of + client.admin.organization.groups.roles.list('group_id')) { + console.log(roleListResponse.id); + } + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + page = client.admin.organization.groups.roles.list( + group_id="group_id", + ) + page = page.data[0] + print(page.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tpage, err := client.Admin.Organization.Groups.Roles.List(\n\t\tcontext.TODO(),\n\t\t\"group_id\",\n\t\topenai.AdminOrganizationGroupRoleListParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", page)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.groups.roles.RoleListPage; + + import + com.openai.models.admin.organization.groups.roles.RoleListParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + RoleListPage page = client.admin().organization().groups().roles().list("group_id"); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + page = openai.admin.organization.groups.roles.list("group_id") + + puts(page) response: | { "object": "list", @@ -15101,6 +16296,8 @@ paths: "next": null } post: + security: + - AdminApiKeyAuth: [] summary: Assigns an organization role to a group within the organization. operationId: assign-group-role tags: @@ -15140,6 +16337,75 @@ paths: -d '{ "role_id": "role_01J1F8ROLE01" }' + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const role = await + client.admin.organization.groups.roles.create('group_id', { + role_id: 'role_id', + }); + + + console.log(role.group); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + role = client.admin.organization.groups.roles.create( + group_id="group_id", + role_id="role_id", + ) + print(role.group) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\trole, err := client.Admin.Organization.Groups.Roles.New(\n\t\tcontext.TODO(),\n\t\t\"group_id\",\n\t\topenai.AdminOrganizationGroupRoleNewParams{\n\t\t\tRoleID: \"role_id\",\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", role.Group)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.groups.roles.RoleCreateParams; + + import + com.openai.models.admin.organization.groups.roles.RoleCreateResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + RoleCreateParams params = RoleCreateParams.builder() + .groupId("group_id") + .roleId("role_id") + .build(); + RoleCreateResponse role = client.admin().organization().groups().roles().create(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + role = openai.admin.organization.groups.roles.create("group_id", + role_id: "role_id") + + + puts(role) response: | { "object": "group.role", @@ -15165,6 +16431,8 @@ paths: } /organization/groups/{group_id}/roles/{role_id}: delete: + security: + - AdminApiKeyAuth: [] summary: Unassigns an organization role from a group within the organization. operationId: unassign-group-role tags: @@ -15200,6 +16468,75 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const role = await + client.admin.organization.groups.roles.delete('role_id', { + group_id: 'group_id', + }); + + + console.log(role.deleted); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + role = client.admin.organization.groups.roles.delete( + role_id="role_id", + group_id="group_id", + ) + print(role.deleted) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\trole, err := client.Admin.Organization.Groups.Roles.Delete(\n\t\tcontext.TODO(),\n\t\t\"group_id\",\n\t\t\"role_id\",\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", role.Deleted)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.groups.roles.RoleDeleteParams; + + import + com.openai.models.admin.organization.groups.roles.RoleDeleteResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + RoleDeleteParams params = RoleDeleteParams.builder() + .groupId("group_id") + .roleId("role_id") + .build(); + RoleDeleteResponse role = client.admin().organization().groups().roles().delete(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + role = openai.admin.organization.groups.roles.delete("role_id", + group_id: "group_id") + + + puts(role) response: | { "object": "group.role.deleted", @@ -15207,6 +16544,8 @@ paths: } /organization/groups/{group_id}/users: get: + security: + - AdminApiKeyAuth: [] summary: Lists the users assigned to a group. operationId: list-group-users tags: @@ -15265,23 +16604,82 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + // Automatically fetches more pages as needed. + + for await (const organizationGroupUser of + client.admin.organization.groups.users.list('group_id')) { + console.log(organizationGroupUser.id); + } + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + page = client.admin.organization.groups.users.list( + group_id="group_id", + ) + page = page.data[0] + print(page.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tpage, err := client.Admin.Organization.Groups.Users.List(\n\t\tcontext.TODO(),\n\t\t\"group_id\",\n\t\topenai.AdminOrganizationGroupUserListParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", page)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.groups.users.UserListPage; + + import + com.openai.models.admin.organization.groups.users.UserListParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + UserListPage page = client.admin().organization().groups().users().list("group_id"); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + page = openai.admin.organization.groups.users.list("group_id") + + puts(page) response: | { "object": "list", "data": [ { - "object": "organization.user", "id": "user_abc123", "name": "Ada Lovelace", - "email": "ada@example.com", - "role": "owner", - "added_at": 1711471533 + "email": "ada@example.com" } ], "has_more": false, "next": null } post: + security: + - AdminApiKeyAuth: [] summary: Adds a user to a group. operationId: add-group-user tags: @@ -15321,6 +16719,75 @@ paths: -d '{ "user_id": "user_abc123" }' + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const user = await + client.admin.organization.groups.users.create('group_id', { + user_id: 'user_id', + }); + + + console.log(user.group_id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + user = client.admin.organization.groups.users.create( + group_id="group_id", + user_id="user_id", + ) + print(user.group_id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tuser, err := client.Admin.Organization.Groups.Users.New(\n\t\tcontext.TODO(),\n\t\t\"group_id\",\n\t\topenai.AdminOrganizationGroupUserNewParams{\n\t\t\tUserID: \"user_id\",\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", user.GroupID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.groups.users.UserCreateParams; + + import + com.openai.models.admin.organization.groups.users.UserCreateResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + UserCreateParams params = UserCreateParams.builder() + .groupId("group_id") + .userId("user_id") + .build(); + UserCreateResponse user = client.admin().organization().groups().users().create(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + user = openai.admin.organization.groups.users.create("group_id", + user_id: "user_id") + + + puts(user) response: | { "object": "group.user", @@ -15329,6 +16796,8 @@ paths: } /organization/groups/{group_id}/users/{user_id}: delete: + security: + - AdminApiKeyAuth: [] summary: Removes a user from a group. operationId: remove-group-user tags: @@ -15364,6 +16833,75 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const user = await + client.admin.organization.groups.users.delete('user_id', { + group_id: 'group_id', + }); + + + console.log(user.deleted); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + user = client.admin.organization.groups.users.delete( + user_id="user_id", + group_id="group_id", + ) + print(user.deleted) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tuser, err := client.Admin.Organization.Groups.Users.Delete(\n\t\tcontext.TODO(),\n\t\t\"group_id\",\n\t\t\"user_id\",\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", user.Deleted)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.groups.users.UserDeleteParams; + + import + com.openai.models.admin.organization.groups.users.UserDeleteResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + UserDeleteParams params = UserDeleteParams.builder() + .groupId("group_id") + .userId("user_id") + .build(); + UserDeleteResponse user = client.admin().organization().groups().users().delete(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + user = openai.admin.organization.groups.users.delete("user_id", + group_id: "group_id") + + + puts(user) response: | { "object": "group.user.deleted", @@ -15371,6 +16909,8 @@ paths: } /organization/invites: get: + security: + - AdminApiKeyAuth: [] summary: Returns a list of invites in the organization. operationId: list-invites tags: @@ -15413,6 +16953,64 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + // Automatically fetches more pages as needed. + + for await (const invite of + client.admin.organization.invites.list()) { + console.log(invite.id); + } + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + page = client.admin.organization.invites.list() + page = page.data[0] + print(page.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tpage, err := client.Admin.Organization.Invites.List(context.TODO(), openai.AdminOrganizationInviteListParams{})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", page)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.invites.InviteListPage; + + import + com.openai.models.admin.organization.invites.InviteListParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + InviteListPage page = client.admin().organization().invites().list(); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + page = openai.admin.organization.invites.list + + puts(page) response: | { "object": "list", @@ -15423,7 +17021,7 @@ paths: "email": "user@example.com", "role": "owner", "status": "accepted", - "invited_at": 1711471533, + "created_at": 1711471533, "expires_at": 1711471533, "accepted_at": 1711471533 } @@ -15433,6 +17031,8 @@ paths: "has_more": false } post: + security: + - AdminApiKeyAuth: [] summary: >- Create an invite for a user to the organization. The invite must be accepted by the user before they have access to the organization. @@ -15476,6 +17076,72 @@ paths: } ] }' + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const invite = await client.admin.organization.invites.create({ + email: 'email', role: 'reader' }); + + + console.log(invite.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + invite = client.admin.organization.invites.create( + email="email", + role="reader", + ) + print(invite.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tinvite, err := client.Admin.Organization.Invites.New(context.TODO(), openai.AdminOrganizationInviteNewParams{\n\t\tEmail: \"email\",\n\t\tRole: openai.AdminOrganizationInviteNewParamsRoleReader,\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", invite.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import com.openai.models.admin.organization.invites.Invite; + + import + com.openai.models.admin.organization.invites.InviteCreateParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + InviteCreateParams params = InviteCreateParams.builder() + .email("email") + .role(InviteCreateParams.Role.READER) + .build(); + Invite invite = client.admin().organization().invites().create(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + invite = openai.admin.organization.invites.create(email: "email", + role: :reader) + + + puts(invite) response: | { "object": "organization.invite", @@ -15483,7 +17149,7 @@ paths: "email": "anotheruser@example.com", "role": "reader", "status": "pending", - "invited_at": 1711471533, + "created_at": 1711471533, "expires_at": 1711471533, "accepted_at": null, "projects": [ @@ -15499,6 +17165,8 @@ paths: } /organization/invites/{invite_id}: get: + security: + - AdminApiKeyAuth: [] summary: Retrieves an invite. operationId: retrieve-invite tags: @@ -15526,6 +17194,63 @@ paths: curl https://api.openai.com/v1/organization/invites/invite-abc \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const invite = await + client.admin.organization.invites.retrieve('invite_id'); + + + console.log(invite.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + invite = client.admin.organization.invites.retrieve( + "invite_id", + ) + print(invite.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tinvite, err := client.Admin.Organization.Invites.Get(context.TODO(), \"invite_id\")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", invite.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import com.openai.models.admin.organization.invites.Invite; + + import + com.openai.models.admin.organization.invites.InviteRetrieveParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + Invite invite = client.admin().organization().invites().retrieve("invite_id"); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + invite = openai.admin.organization.invites.retrieve("invite_id") + + puts(invite) response: | { "object": "organization.invite", @@ -15533,11 +17258,13 @@ paths: "email": "user@example.com", "role": "owner", "status": "accepted", - "invited_at": 1711471533, + "created_at": 1711471533, "expires_at": 1711471533, "accepted_at": 1711471533 } delete: + security: + - AdminApiKeyAuth: [] summary: >- Delete an invite. If the invite has already been accepted, it cannot be deleted. @@ -15568,6 +17295,64 @@ paths: https://api.openai.com/v1/organization/invites/invite-abc \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const invite = await + client.admin.organization.invites.delete('invite_id'); + + + console.log(invite.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + invite = client.admin.organization.invites.delete( + "invite_id", + ) + print(invite.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tinvite, err := client.Admin.Organization.Invites.Delete(context.TODO(), \"invite_id\")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", invite.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.invites.InviteDeleteParams; + + import + com.openai.models.admin.organization.invites.InviteDeleteResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + InviteDeleteResponse invite = client.admin().organization().invites().delete("invite_id"); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + invite = openai.admin.organization.invites.delete("invite_id") + + puts(invite) response: | { "object": "organization.invite.deleted", @@ -15578,6 +17363,8 @@ paths: get: summary: Returns a list of projects. operationId: list-projects + security: + - AdminApiKeyAuth: [] tags: - Projects parameters: @@ -15626,6 +17413,64 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + // Automatically fetches more pages as needed. + + for await (const project of + client.admin.organization.projects.list()) { + console.log(project.id); + } + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + page = client.admin.organization.projects.list() + page = page.data[0] + print(page.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tpage, err := client.Admin.Organization.Projects.List(context.TODO(), openai.AdminOrganizationProjectListParams{})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", page)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.ProjectListPage; + + import + com.openai.models.admin.organization.projects.ProjectListParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + ProjectListPage page = client.admin().organization().projects().list(); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + page = openai.admin.organization.projects.list + + puts(page) response: | { "object": "list", @@ -15648,6 +17493,8 @@ paths: Create a new project in the organization. Projects can be created and archived, but cannot be deleted. operationId: create-project + security: + - AdminApiKeyAuth: [] tags: - Projects requestBody: @@ -15676,6 +17523,66 @@ paths: -d '{ "name": "Project ABC" }' + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const project = await client.admin.organization.projects.create({ + name: 'name' }); + + + console.log(project.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + project = client.admin.organization.projects.create( + name="name", + ) + print(project.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tproject, err := client.Admin.Organization.Projects.New(context.TODO(), openai.AdminOrganizationProjectNewParams{\n\t\tName: \"name\",\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", project.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import com.openai.models.admin.organization.projects.Project; + + import + com.openai.models.admin.organization.projects.ProjectCreateParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + ProjectCreateParams params = ProjectCreateParams.builder() + .name("name") + .build(); + Project project = client.admin().organization().projects().create(params); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + project = openai.admin.organization.projects.create(name: "name") + + puts(project) response: | { "id": "proj_abc", @@ -15689,6 +17596,8 @@ paths: get: summary: Retrieves a project. operationId: retrieve-project + security: + - AdminApiKeyAuth: [] tags: - Projects parameters: @@ -15715,6 +17624,67 @@ paths: curl https://api.openai.com/v1/organization/projects/proj_abc \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const project = await + client.admin.organization.projects.retrieve('project_id'); + + + console.log(project.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + project = client.admin.organization.projects.retrieve( + "project_id", + ) + print(project.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tproject, err := client.Admin.Organization.Projects.Get(context.TODO(), \"project_id\")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", project.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import com.openai.models.admin.organization.projects.Project; + + import + com.openai.models.admin.organization.projects.ProjectRetrieveParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + Project project = client.admin().organization().projects().retrieve("project_id"); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + project = + openai.admin.organization.projects.retrieve("project_id") + + + puts(project) response: | { "id": "proj_abc", @@ -15727,6 +17697,8 @@ paths: post: summary: Modifies a project in the organization. operationId: modify-project + security: + - AdminApiKeyAuth: [] tags: - Projects parameters: @@ -15769,9 +17741,68 @@ paths: -d '{ "name": "Project DEF" }' + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const project = await + client.admin.organization.projects.update('project_id'); + + + console.log(project.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + project = client.admin.organization.projects.update( + project_id="project_id", + ) + print(project.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tproject, err := client.Admin.Organization.Projects.Update(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\topenai.AdminOrganizationProjectUpdateParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", project.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import com.openai.models.admin.organization.projects.Project; + + import + com.openai.models.admin.organization.projects.ProjectUpdateParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + Project project = client.admin().organization().projects().update("project_id"); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + project = openai.admin.organization.projects.update("project_id") + + puts(project) response: '' /organization/projects/{project_id}/api_keys: get: + security: + - AdminApiKeyAuth: [] summary: Returns a list of API keys in the project. operationId: list-project-api-keys tags: @@ -15820,6 +17851,70 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + // Automatically fetches more pages as needed. + + for await (const projectAPIKey of + client.admin.organization.projects.apiKeys.list('project_id')) { + console.log(projectAPIKey.id); + } + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + page = client.admin.organization.projects.api_keys.list( + project_id="project_id", + ) + page = page.data[0] + print(page.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tpage, err := client.Admin.Organization.Projects.APIKeys.List(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\topenai.AdminOrganizationProjectAPIKeyListParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", page)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.apikeys.ApiKeyListPage; + + import + com.openai.models.admin.organization.projects.apikeys.ApiKeyListParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + ApiKeyListPage page = client.admin().organization().projects().apiKeys().list("project_id"); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + page = + openai.admin.organization.projects.api_keys.list("project_id") + + + puts(page) response: | { "object": "list", @@ -15834,12 +17929,11 @@ paths: "owner": { "type": "user", "user": { - "object": "organization.project.user", "id": "user_abc", "name": "First Last", "email": "user@example.com", "role": "owner", - "added_at": 1711471533 + "created_at": 1711471533 } } } @@ -15848,8 +17942,10 @@ paths: "last_id": "key_xyz", "has_more": false } - /organization/projects/{project_id}/api_keys/{key_id}: + /organization/projects/{project_id}/api_keys/{api_key_id}: get: + security: + - AdminApiKeyAuth: [] summary: Retrieves an API key in the project. operationId: retrieve-project-api-key tags: @@ -15861,7 +17957,7 @@ paths: required: true schema: type: string - - name: key_id + - name: api_key_id in: path description: The ID of the API key. required: true @@ -15885,6 +17981,82 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const projectAPIKey = await + client.admin.organization.projects.apiKeys.retrieve('api_key_id', + { + project_id: 'project_id', + }); + + + console.log(projectAPIKey.id); + python: >- + import os + + from openai import OpenAI + + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + + project_api_key = + client.admin.organization.projects.api_keys.retrieve( + api_key_id="api_key_id", + project_id="project_id", + ) + + print(project_api_key.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tprojectAPIKey, err := client.Admin.Organization.Projects.APIKeys.Get(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\t\"api_key_id\",\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", projectAPIKey.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.apikeys.ApiKeyRetrieveParams; + + import + com.openai.models.admin.organization.projects.apikeys.ProjectApiKey; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + ApiKeyRetrieveParams params = ApiKeyRetrieveParams.builder() + .projectId("project_id") + .apiKeyId("api_key_id") + .build(); + ProjectApiKey projectApiKey = client.admin().organization().projects().apiKeys().retrieve(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + project_api_key = + openai.admin.organization.projects.api_keys.retrieve("api_key_id", + project_id: "project_id") + + + puts(project_api_key) response: | { "object": "organization.project.api_key", @@ -15896,16 +18068,17 @@ paths: "owner": { "type": "user", "user": { - "object": "organization.project.user", "id": "user_abc", "name": "First Last", "email": "user@example.com", "role": "owner", - "added_at": 1711471533 + "created_at": 1711471533 } } } delete: + security: + - AdminApiKeyAuth: [] summary: > Deletes an API key from the project. @@ -15924,7 +18097,7 @@ paths: required: true schema: type: string - - name: key_id + - name: api_key_id in: path description: The ID of the API key. required: true @@ -15954,6 +18127,76 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const apiKey = await + client.admin.organization.projects.apiKeys.delete('api_key_id', { + project_id: 'project_id', + }); + + + console.log(apiKey.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + api_key = client.admin.organization.projects.api_keys.delete( + api_key_id="api_key_id", + project_id="project_id", + ) + print(api_key.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tapiKey, err := client.Admin.Organization.Projects.APIKeys.Delete(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\t\"api_key_id\",\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", apiKey.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.apikeys.ApiKeyDeleteParams; + + import + com.openai.models.admin.organization.projects.apikeys.ApiKeyDeleteResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + ApiKeyDeleteParams params = ApiKeyDeleteParams.builder() + .projectId("project_id") + .apiKeyId("api_key_id") + .build(); + ApiKeyDeleteResponse apiKey = client.admin().organization().projects().apiKeys().delete(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + api_key = + openai.admin.organization.projects.api_keys.delete("api_key_id", + project_id: "project_id") + + + puts(api_key) response: | { "object": "organization.project.api_key.deleted", @@ -15966,6 +18209,8 @@ paths: Archives a project in the organization. Archived projects cannot be used or updated. operationId: archive-project + security: + - AdminApiKeyAuth: [] tags: - Projects parameters: @@ -15992,6 +18237,63 @@ paths: https://api.openai.com/v1/organization/projects/proj_abc/archive \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const project = await + client.admin.organization.projects.archive('project_id'); + + + console.log(project.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + project = client.admin.organization.projects.archive( + "project_id", + ) + print(project.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tproject, err := client.Admin.Organization.Projects.Archive(context.TODO(), \"project_id\")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", project.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import com.openai.models.admin.organization.projects.Project; + + import + com.openai.models.admin.organization.projects.ProjectArchiveParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + Project project = client.admin().organization().projects().archive("project_id"); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + project = openai.admin.organization.projects.archive("project_id") + + puts(project) response: | { "id": "proj_abc", @@ -16003,6 +18305,8 @@ paths: } /organization/projects/{project_id}/certificates: get: + security: + - AdminApiKeyAuth: [] summary: List certificates for this project. operationId: listProjectCertificates tags: @@ -16050,7 +18354,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/ListCertificatesResponse' + $ref: '#/components/schemas/ListProjectCertificatesResponse' x-oaiMeta: name: List project certificates group: administration @@ -16062,6 +18366,72 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + // Automatically fetches more pages as needed. + + for await (const certificateListResponse of + client.admin.organization.projects.certificates.list( + 'project_id', + )) { + console.log(certificateListResponse.id); + } + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + page = client.admin.organization.projects.certificates.list( + project_id="project_id", + ) + page = page.data[0] + print(page.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tpage, err := client.Admin.Organization.Projects.Certificates.List(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\topenai.AdminOrganizationProjectCertificateListParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", page)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.certificates.CertificateListPage; + + import + com.openai.models.admin.organization.projects.certificates.CertificateListParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + CertificateListPage page = client.admin().organization().projects().certificates().list("project_id"); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + page = + openai.admin.organization.projects.certificates.list("project_id") + + + puts(page) response: | { "object": "list", @@ -16084,6 +18454,8 @@ paths: } /organization/projects/{project_id}/certificates/activate: post: + security: + - AdminApiKeyAuth: [] summary: > Activate certificates at the project level. @@ -16113,7 +18485,8 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/ListCertificatesResponse' + $ref: >- + #/components/schemas/OrganizationProjectCertificateActivationResponse x-oaiMeta: name: Activate certificates for project group: administration @@ -16129,8 +18502,81 @@ paths: -H "Content-Type: application/json" \ -d '{ - "data": ["cert_abc", "cert_def"] + "certificate_ids": ["cert_abc", "cert_def"] }' + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + // Automatically fetches more pages as needed. + + for await (const certificateActivateResponse of + client.admin.organization.projects.certificates.activate( + 'project_id', + { certificate_ids: ['cert_abc'] }, + )) { + console.log(certificateActivateResponse.id); + } + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + page = client.admin.organization.projects.certificates.activate( + project_id="project_id", + certificate_ids=["cert_abc"], + ) + page = page.data[0] + print(page.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tpage, err := client.Admin.Organization.Projects.Certificates.Activate(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\topenai.AdminOrganizationProjectCertificateActivateParams{\n\t\t\tCertificateIDs: []string{\"cert_abc\"},\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", page)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.certificates.CertificateActivatePage; + + import + com.openai.models.admin.organization.projects.certificates.CertificateActivateParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + CertificateActivateParams params = CertificateActivateParams.builder() + .projectId("project_id") + .addCertificateId("cert_abc") + .build(); + CertificateActivatePage page = client.admin().organization().projects().certificates().activate(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + page = + openai.admin.organization.projects.certificates.activate("project_id", + certificate_ids: ["cert_abc"]) + + + puts(page) response: | { "object": "organization.project.certificate.activation", @@ -16161,8 +18607,10 @@ paths: } /organization/projects/{project_id}/certificates/deactivate: post: + security: + - AdminApiKeyAuth: [] summary: | - Deactivate certificates at the project level. You can atomically and + Deactivate certificates at the project level. You can atomically and idempotently deactivate up to 10 certificates at a time. operationId: deactivateProjectCertificates tags: @@ -16187,7 +18635,8 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/ListCertificatesResponse' + $ref: >- + #/components/schemas/OrganizationProjectCertificateDeactivationResponse x-oaiMeta: name: Deactivate certificates for project group: administration @@ -16203,8 +18652,81 @@ paths: -H "Content-Type: application/json" \ -d '{ - "data": ["cert_abc", "cert_def"] + "certificate_ids": ["cert_abc", "cert_def"] }' + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + // Automatically fetches more pages as needed. + + for await (const certificateDeactivateResponse of + client.admin.organization.projects.certificates.deactivate( + 'project_id', + { certificate_ids: ['cert_abc'] }, + )) { + console.log(certificateDeactivateResponse.id); + } + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + page = client.admin.organization.projects.certificates.deactivate( + project_id="project_id", + certificate_ids=["cert_abc"], + ) + page = page.data[0] + print(page.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tpage, err := client.Admin.Organization.Projects.Certificates.Deactivate(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\topenai.AdminOrganizationProjectCertificateDeactivateParams{\n\t\t\tCertificateIDs: []string{\"cert_abc\"},\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", page)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.certificates.CertificateDeactivatePage; + + import + com.openai.models.admin.organization.projects.certificates.CertificateDeactivateParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + CertificateDeactivateParams params = CertificateDeactivateParams.builder() + .projectId("project_id") + .addCertificateId("cert_abc") + .build(); + CertificateDeactivatePage page = client.admin().organization().projects().certificates().deactivate(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + page = + openai.admin.organization.projects.certificates.deactivate("project_id", + certificate_ids: ["cert_abc"]) + + + puts(page) response: | { "object": "organization.project.certificate.deactivation", @@ -16235,6 +18757,8 @@ paths: } /organization/projects/{project_id}/groups: get: + security: + - AdminApiKeyAuth: [] summary: Lists the groups that have access to a project. operationId: list-project-groups tags: @@ -16291,6 +18815,70 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + // Automatically fetches more pages as needed. + + for await (const projectGroup of + client.admin.organization.projects.groups.list('project_id')) { + console.log(projectGroup.group_id); + } + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + page = client.admin.organization.projects.groups.list( + project_id="project_id", + ) + page = page.data[0] + print(page.group_id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tpage, err := client.Admin.Organization.Projects.Groups.List(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\topenai.AdminOrganizationProjectGroupListParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", page)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.groups.GroupListPage; + + import + com.openai.models.admin.organization.projects.groups.GroupListParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + GroupListPage page = client.admin().organization().projects().groups().list("project_id"); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + page = + openai.admin.organization.projects.groups.list("project_id") + + + puts(page) response: | { "object": "list", @@ -16307,6 +18895,8 @@ paths: "next": null } post: + security: + - AdminApiKeyAuth: [] summary: Grants a group access to a project. operationId: add-project-group tags: @@ -16347,6 +18937,79 @@ paths: "group_id": "group_01J1F8ABCDXYZ", "role": "role_01J1F8PROJ" }' + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const projectGroup = await + client.admin.organization.projects.groups.create('project_id', { + group_id: 'group_id', + role: 'role', + }); + + + console.log(projectGroup.group_id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + project_group = client.admin.organization.projects.groups.create( + project_id="project_id", + group_id="group_id", + role="role", + ) + print(project_group.group_id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tprojectGroup, err := client.Admin.Organization.Projects.Groups.New(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\topenai.AdminOrganizationProjectGroupNewParams{\n\t\t\tGroupID: \"group_id\",\n\t\t\tRole: \"role\",\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", projectGroup.GroupID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.groups.GroupCreateParams; + + import + com.openai.models.admin.organization.projects.groups.ProjectGroup; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + GroupCreateParams params = GroupCreateParams.builder() + .projectId("project_id") + .groupId("group_id") + .role("role") + .build(); + ProjectGroup projectGroup = client.admin().organization().projects().groups().create(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + project_group = + openai.admin.organization.projects.groups.create("project_id", + group_id: "group_id", role: "role") + + + puts(project_group) response: | { "object": "project.group", @@ -16357,6 +19020,8 @@ paths: } /organization/projects/{project_id}/groups/{group_id}: delete: + security: + - AdminApiKeyAuth: [] summary: Revokes a group's access to a project. operationId: remove-project-group tags: @@ -16392,6 +19057,76 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const group = await + client.admin.organization.projects.groups.delete('group_id', { + project_id: 'project_id', + }); + + + console.log(group.deleted); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + group = client.admin.organization.projects.groups.delete( + group_id="group_id", + project_id="project_id", + ) + print(group.deleted) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tgroup, err := client.Admin.Organization.Projects.Groups.Delete(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\t\"group_id\",\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", group.Deleted)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.groups.GroupDeleteParams; + + import + com.openai.models.admin.organization.projects.groups.GroupDeleteResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + GroupDeleteParams params = GroupDeleteParams.builder() + .projectId("project_id") + .groupId("group_id") + .build(); + GroupDeleteResponse group = client.admin().organization().projects().groups().delete(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + group = + openai.admin.organization.projects.groups.delete("group_id", + project_id: "project_id") + + + puts(group) response: | { "object": "project.group.deleted", @@ -16399,6 +19134,8 @@ paths: } /organization/projects/{project_id}/rate_limits: get: + security: + - AdminApiKeyAuth: [] summary: Returns the rate limits per model for a project. operationId: list-project-rate-limits tags: @@ -16457,6 +19194,78 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + // Automatically fetches more pages as needed. + + for await (const projectRateLimit of + client.admin.organization.projects.rateLimits.listRateLimits( + 'project_id', + )) { + console.log(projectRateLimit.id); + } + python: >- + import os + + from openai import OpenAI + + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + + page = + client.admin.organization.projects.rate_limits.list_rate_limits( + project_id="project_id", + ) + + page = page.data[0] + + print(page.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tpage, err := client.Admin.Organization.Projects.RateLimits.ListRateLimits(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\topenai.AdminOrganizationProjectRateLimitListRateLimitsParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", page)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.ratelimits.RateLimitListRateLimitsPage; + + import + com.openai.models.admin.organization.projects.ratelimits.RateLimitListRateLimitsParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + RateLimitListRateLimitsPage page = client.admin().organization().projects().rateLimits().listRateLimits("project_id"); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + page = + openai.admin.organization.projects.rate_limits.list_rate_limits("project_id") + + + puts(page) response: | { "object": "list", @@ -16481,6 +19290,8 @@ paths: } /organization/projects/{project_id}/rate_limits/{rate_limit_id}: post: + security: + - AdminApiKeyAuth: [] summary: Updates a project rate limit. operationId: update-project-rate-limits tags: @@ -16532,6 +19343,84 @@ paths: -d '{ "max_requests_per_1_minute": 500 }' + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const projectRateLimit = await + client.admin.organization.projects.rateLimits.updateRateLimit( + 'rate_limit_id', + { project_id: 'project_id' }, + ); + + + console.log(projectRateLimit.id); + python: >- + import os + + from openai import OpenAI + + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + + project_rate_limit = + client.admin.organization.projects.rate_limits.update_rate_limit( + rate_limit_id="rate_limit_id", + project_id="project_id", + ) + + print(project_rate_limit.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tprojectRateLimit, err := client.Admin.Organization.Projects.RateLimits.UpdateRateLimit(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\t\"rate_limit_id\",\n\t\topenai.AdminOrganizationProjectRateLimitUpdateRateLimitParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", projectRateLimit.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.ratelimits.ProjectRateLimit; + + import + com.openai.models.admin.organization.projects.ratelimits.RateLimitUpdateRateLimitParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + RateLimitUpdateRateLimitParams params = RateLimitUpdateRateLimitParams.builder() + .projectId("project_id") + .rateLimitId("rate_limit_id") + .build(); + ProjectRateLimit projectRateLimit = client.admin().organization().projects().rateLimits().updateRateLimit(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + project_rate_limit = + openai.admin.organization.projects.rate_limits.update_rate_limit( + "rate_limit_id", + project_id: "project_id" + ) + + + puts(project_rate_limit) response: | { "object": "project.rate_limit", @@ -16548,6 +19437,8 @@ paths: } /organization/projects/{project_id}/service_accounts: get: + security: + - AdminApiKeyAuth: [] summary: Returns a list of service accounts in the project. operationId: list-project-service-accounts tags: @@ -16602,6 +19493,72 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + // Automatically fetches more pages as needed. + + for await (const projectServiceAccount of + client.admin.organization.projects.serviceAccounts.list( + 'project_id', + )) { + console.log(projectServiceAccount.id); + } + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + page = client.admin.organization.projects.service_accounts.list( + project_id="project_id", + ) + page = page.data[0] + print(page.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tpage, err := client.Admin.Organization.Projects.ServiceAccounts.List(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\topenai.AdminOrganizationProjectServiceAccountListParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", page)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.serviceaccounts.ServiceAccountListPage; + + import + com.openai.models.admin.organization.projects.serviceaccounts.ServiceAccountListParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + ServiceAccountListPage page = client.admin().organization().projects().serviceAccounts().list("project_id"); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + page = + openai.admin.organization.projects.service_accounts.list("project_id") + + + puts(page) response: | { "object": "list", @@ -16619,6 +19576,8 @@ paths: "has_more": false } post: + security: + - AdminApiKeyAuth: [] summary: >- Creates a new service account in the project. This also returns an unredacted API key for the service account. @@ -16666,6 +19625,82 @@ paths: -d '{ "name": "Production App" }' + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const serviceAccount = await + client.admin.organization.projects.serviceAccounts.create( + 'project_id', + { name: 'name' }, + ); + + + console.log(serviceAccount.id); + python: >- + import os + + from openai import OpenAI + + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + + service_account = + client.admin.organization.projects.service_accounts.create( + project_id="project_id", + name="name", + ) + + print(service_account.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tserviceAccount, err := client.Admin.Organization.Projects.ServiceAccounts.New(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\topenai.AdminOrganizationProjectServiceAccountNewParams{\n\t\t\tName: \"name\",\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", serviceAccount.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.serviceaccounts.ServiceAccountCreateParams; + + import + com.openai.models.admin.organization.projects.serviceaccounts.ServiceAccountCreateResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + ServiceAccountCreateParams params = ServiceAccountCreateParams.builder() + .projectId("project_id") + .name("name") + .build(); + ServiceAccountCreateResponse serviceAccount = client.admin().organization().projects().serviceAccounts().create(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + service_account = + openai.admin.organization.projects.service_accounts.create("project_id", + name: "name") + + + puts(service_account) response: | { "object": "organization.project.service_account", @@ -16683,6 +19718,8 @@ paths: } /organization/projects/{project_id}/service_accounts/{service_account_id}: get: + security: + - AdminApiKeyAuth: [] summary: Retrieves a service account in the project. operationId: retrieve-project-service-account tags: @@ -16718,6 +19755,84 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const projectServiceAccount = await + client.admin.organization.projects.serviceAccounts.retrieve( + 'service_account_id', + { project_id: 'project_id' }, + ); + + + console.log(projectServiceAccount.id); + python: >- + import os + + from openai import OpenAI + + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + + project_service_account = + client.admin.organization.projects.service_accounts.retrieve( + service_account_id="service_account_id", + project_id="project_id", + ) + + print(project_service_account.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tprojectServiceAccount, err := client.Admin.Organization.Projects.ServiceAccounts.Get(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\t\"service_account_id\",\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", projectServiceAccount.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.serviceaccounts.ProjectServiceAccount; + + import + com.openai.models.admin.organization.projects.serviceaccounts.ServiceAccountRetrieveParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + ServiceAccountRetrieveParams params = ServiceAccountRetrieveParams.builder() + .projectId("project_id") + .serviceAccountId("service_account_id") + .build(); + ProjectServiceAccount projectServiceAccount = client.admin().organization().projects().serviceAccounts().retrieve(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + project_service_account = + openai.admin.organization.projects.service_accounts.retrieve( + "service_account_id", + project_id: "project_id" + ) + + + puts(project_service_account) response: | { "object": "organization.project.service_account", @@ -16727,6 +19842,8 @@ paths: "created_at": 1711471533 } delete: + security: + - AdminApiKeyAuth: [] summary: > Deletes a service account from the project. @@ -16769,6 +19886,82 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const serviceAccount = await + client.admin.organization.projects.serviceAccounts.delete( + 'service_account_id', + { project_id: 'project_id' }, + ); + + + console.log(serviceAccount.id); + python: >- + import os + + from openai import OpenAI + + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + + service_account = + client.admin.organization.projects.service_accounts.delete( + service_account_id="service_account_id", + project_id="project_id", + ) + + print(service_account.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tserviceAccount, err := client.Admin.Organization.Projects.ServiceAccounts.Delete(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\t\"service_account_id\",\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", serviceAccount.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.serviceaccounts.ServiceAccountDeleteParams; + + import + com.openai.models.admin.organization.projects.serviceaccounts.ServiceAccountDeleteResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + ServiceAccountDeleteParams params = ServiceAccountDeleteParams.builder() + .projectId("project_id") + .serviceAccountId("service_account_id") + .build(); + ServiceAccountDeleteResponse serviceAccount = client.admin().organization().projects().serviceAccounts().delete(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + service_account = + openai.admin.organization.projects.service_accounts.delete("service_account_id", + project_id: "project_id") + + + puts(service_account) response: | { "object": "organization.project.service_account.deleted", @@ -16777,6 +19970,8 @@ paths: } /organization/projects/{project_id}/users: get: + security: + - AdminApiKeyAuth: [] summary: Returns a list of users in the project. operationId: list-project-users tags: @@ -16831,6 +20026,66 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + // Automatically fetches more pages as needed. + + for await (const projectUser of + client.admin.organization.projects.users.list('project_id')) { + console.log(projectUser.id); + } + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + page = client.admin.organization.projects.users.list( + project_id="project_id", + ) + page = page.data[0] + print(page.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tpage, err := client.Admin.Organization.Projects.Users.List(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\topenai.AdminOrganizationProjectUserListParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", page)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.users.UserListPage; + + import + com.openai.models.admin.organization.projects.users.UserListParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + UserListPage page = client.admin().organization().projects().users().list("project_id"); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + page = openai.admin.organization.projects.users.list("project_id") + + puts(page) response: | { "object": "list", @@ -16849,6 +20104,8 @@ paths: "has_more": false } post: + security: + - AdminApiKeyAuth: [] summary: >- Adds a user to the project. Users must already be members of the organization to be added to a project. @@ -16896,6 +20153,76 @@ paths: "user_id": "user_abc", "role": "member" }' + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const projectUser = await + client.admin.organization.projects.users.create('project_id', { + role: 'role', + }); + + + console.log(projectUser.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + project_user = client.admin.organization.projects.users.create( + project_id="project_id", + role="role", + ) + print(project_user.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tprojectUser, err := client.Admin.Organization.Projects.Users.New(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\topenai.AdminOrganizationProjectUserNewParams{\n\t\t\tRole: \"role\",\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", projectUser.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.users.ProjectUser; + + import + com.openai.models.admin.organization.projects.users.UserCreateParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + UserCreateParams params = UserCreateParams.builder() + .projectId("project_id") + .role("role") + .build(); + ProjectUser projectUser = client.admin().organization().projects().users().create(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + project_user = + openai.admin.organization.projects.users.create("project_id", + role: "role") + + + puts(project_user) response: | { "object": "organization.project.user", @@ -16906,6 +20233,8 @@ paths: } /organization/projects/{project_id}/users/{user_id}: get: + security: + - AdminApiKeyAuth: [] summary: Retrieves a user in the project. operationId: retrieve-project-user tags: @@ -16941,6 +20270,76 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const projectUser = await + client.admin.organization.projects.users.retrieve('user_id', { + project_id: 'project_id', + }); + + + console.log(projectUser.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + project_user = client.admin.organization.projects.users.retrieve( + user_id="user_id", + project_id="project_id", + ) + print(project_user.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tprojectUser, err := client.Admin.Organization.Projects.Users.Get(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\t\"user_id\",\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", projectUser.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.users.ProjectUser; + + import + com.openai.models.admin.organization.projects.users.UserRetrieveParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + UserRetrieveParams params = UserRetrieveParams.builder() + .projectId("project_id") + .userId("user_id") + .build(); + ProjectUser projectUser = client.admin().organization().projects().users().retrieve(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + project_user = + openai.admin.organization.projects.users.retrieve("user_id", + project_id: "project_id") + + + puts(project_user) response: | { "object": "organization.project.user", @@ -16951,6 +20350,8 @@ paths: "added_at": 1711471533 } post: + security: + - AdminApiKeyAuth: [] summary: Modifies a user's role in the project. operationId: modify-project-user tags: @@ -17002,6 +20403,76 @@ paths: -d '{ "role": "owner" }' + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const projectUser = await + client.admin.organization.projects.users.update('user_id', { + project_id: 'project_id', + }); + + + console.log(projectUser.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + project_user = client.admin.organization.projects.users.update( + user_id="user_id", + project_id="project_id", + ) + print(project_user.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tprojectUser, err := client.Admin.Organization.Projects.Users.Update(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\t\"user_id\",\n\t\topenai.AdminOrganizationProjectUserUpdateParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", projectUser.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.users.ProjectUser; + + import + com.openai.models.admin.organization.projects.users.UserUpdateParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + UserUpdateParams params = UserUpdateParams.builder() + .projectId("project_id") + .userId("user_id") + .build(); + ProjectUser projectUser = client.admin().organization().projects().users().update(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + project_user = + openai.admin.organization.projects.users.update("user_id", + project_id: "project_id") + + + puts(project_user) response: | { "object": "organization.project.user", @@ -17012,6 +20483,8 @@ paths: "added_at": 1711471533 } delete: + security: + - AdminApiKeyAuth: [] summary: > Deletes a user from the project. @@ -17060,6 +20533,75 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const user = await + client.admin.organization.projects.users.delete('user_id', { + project_id: 'project_id', + }); + + + console.log(user.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + user = client.admin.organization.projects.users.delete( + user_id="user_id", + project_id="project_id", + ) + print(user.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tuser, err := client.Admin.Organization.Projects.Users.Delete(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\t\"user_id\",\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", user.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.users.UserDeleteParams; + + import + com.openai.models.admin.organization.projects.users.UserDeleteResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + UserDeleteParams params = UserDeleteParams.builder() + .projectId("project_id") + .userId("user_id") + .build(); + UserDeleteResponse user = client.admin().organization().projects().users().delete(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + user = openai.admin.organization.projects.users.delete("user_id", + project_id: "project_id") + + + puts(user) response: | { "object": "organization.project.user.deleted", @@ -17068,6 +20610,8 @@ paths: } /organization/roles: get: + security: + - AdminApiKeyAuth: [] summary: Lists the roles configured for the organization. operationId: list-roles tags: @@ -17116,6 +20660,53 @@ paths: curl https://api.openai.com/v1/organization/roles?limit=20 \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: |- + import OpenAI from 'openai'; + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + // Automatically fetches more pages as needed. + for await (const role of client.admin.organization.roles.list()) { + console.log(role.id); + } + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + page = client.admin.organization.roles.list() + page = page.data[0] + print(page.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tpage, err := client.Admin.Organization.Roles.List(context.TODO(), openai.AdminOrganizationRoleListParams{})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", page)\n}\n" + java: |- + package com.openai.example; + + import com.openai.client.OpenAIClient; + import com.openai.client.okhttp.OpenAIOkHttpClient; + import com.openai.models.admin.organization.roles.RoleListPage; + import com.openai.models.admin.organization.roles.RoleListParams; + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + RoleListPage page = client.admin().organization().roles().list(); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + page = openai.admin.organization.roles.list + + puts(page) response: | { "object": "list", @@ -17137,6 +20728,8 @@ paths: "next": null } post: + security: + - AdminApiKeyAuth: [] summary: Creates a custom role for the organization. operationId: create-role tags: @@ -17172,6 +20765,71 @@ paths: ], "description": "Allows managing organization groups" }' + node.js: |- + import OpenAI from 'openai'; + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + const role = await client.admin.organization.roles.create({ + permissions: ['string'], + role_name: 'role_name', + }); + + console.log(role.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + role = client.admin.organization.roles.create( + permissions=["string"], + role_name="role_name", + ) + print(role.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\trole, err := client.Admin.Organization.Roles.New(context.TODO(), openai.AdminOrganizationRoleNewParams{\n\t\tPermissions: []string{\"string\"},\n\t\tRoleName: \"role_name\",\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", role.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import com.openai.models.admin.organization.roles.Role; + + import + com.openai.models.admin.organization.roles.RoleCreateParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + RoleCreateParams params = RoleCreateParams.builder() + .addPermission("string") + .roleName("role_name") + .build(); + Role role = client.admin().organization().roles().create(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + role = openai.admin.organization.roles.create(permissions: + ["string"], role_name: "role_name") + + + puts(role) response: | { "object": "role", @@ -17187,6 +20845,8 @@ paths: } /organization/roles/{role_id}: post: + security: + - AdminApiKeyAuth: [] summary: Updates an existing organization role. operationId: update-role tags: @@ -17230,6 +20890,63 @@ paths: ], "description": "Allows managing organization groups" }' + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const role = await + client.admin.organization.roles.update('role_id'); + + + console.log(role.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + role = client.admin.organization.roles.update( + role_id="role_id", + ) + print(role.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\trole, err := client.Admin.Organization.Roles.Update(\n\t\tcontext.TODO(),\n\t\t\"role_id\",\n\t\topenai.AdminOrganizationRoleUpdateParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", role.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import com.openai.models.admin.organization.roles.Role; + + import + com.openai.models.admin.organization.roles.RoleUpdateParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + Role role = client.admin().organization().roles().update("role_id"); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + role = openai.admin.organization.roles.update("role_id") + + puts(role) response: | { "object": "role", @@ -17244,6 +20961,8 @@ paths: "predefined_role": false } delete: + security: + - AdminApiKeyAuth: [] summary: Deletes a custom role from the organization. operationId: delete-role tags: @@ -17272,6 +20991,64 @@ paths: https://api.openai.com/v1/organization/roles/role_01J1F8ROLE01 \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const role = await + client.admin.organization.roles.delete('role_id'); + + + console.log(role.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + role = client.admin.organization.roles.delete( + "role_id", + ) + print(role.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\trole, err := client.Admin.Organization.Roles.Delete(context.TODO(), \"role_id\")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", role.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.roles.RoleDeleteParams; + + import + com.openai.models.admin.organization.roles.RoleDeleteResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + RoleDeleteResponse role = client.admin().organization().roles().delete("role_id"); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + role = openai.admin.organization.roles.delete("role_id") + + puts(role) response: | { "object": "role.deleted", @@ -17280,6 +21057,8 @@ paths: } /organization/usage/audio_speeches: get: + security: + - AdminApiKeyAuth: [] summary: Get audio speeches usage details for the organization. operationId: usage-audio-speeches tags: @@ -17395,6 +21174,71 @@ paths: -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const response = await + client.admin.organization.usage.audioSpeeches({ start_time: 0 }); + + + console.log(response.data); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + response = client.admin.organization.usage.audio_speeches( + start_time=0, + ) + print(response.data) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tresponse, err := client.Admin.Organization.Usage.AudioSpeeches(context.TODO(), openai.AdminOrganizationUsageAudioSpeechesParams{\n\t\tStartTime: 0,\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", response.Data)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.usage.UsageAudioSpeechesParams; + + import + com.openai.models.admin.organization.usage.UsageAudioSpeechesResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + UsageAudioSpeechesParams params = UsageAudioSpeechesParams.builder() + .startTime(0L) + .build(); + UsageAudioSpeechesResponse response = client.admin().organization().usage().audioSpeeches(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + response = + openai.admin.organization.usage.audio_speeches(start_time: 0) + + + puts(response) response: | { "object": "page", @@ -17421,6 +21265,8 @@ paths: } /organization/usage/audio_transcriptions: get: + security: + - AdminApiKeyAuth: [] summary: Get audio transcriptions usage details for the organization. operationId: usage-audio-transcriptions tags: @@ -17536,6 +21382,73 @@ paths: -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const response = await + client.admin.organization.usage.audioTranscriptions({ start_time: + 0 }); + + + console.log(response.data); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + response = client.admin.organization.usage.audio_transcriptions( + start_time=0, + ) + print(response.data) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tresponse, err := client.Admin.Organization.Usage.AudioTranscriptions(context.TODO(), openai.AdminOrganizationUsageAudioTranscriptionsParams{\n\t\tStartTime: 0,\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", response.Data)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.usage.UsageAudioTranscriptionsParams; + + import + com.openai.models.admin.organization.usage.UsageAudioTranscriptionsResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + UsageAudioTranscriptionsParams params = UsageAudioTranscriptionsParams.builder() + .startTime(0L) + .build(); + UsageAudioTranscriptionsResponse response = client.admin().organization().usage().audioTranscriptions(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + response = + openai.admin.organization.usage.audio_transcriptions(start_time: + 0) + + + puts(response) response: | { "object": "page", @@ -17562,6 +21475,8 @@ paths: } /organization/usage/code_interpreter_sessions: get: + security: + - AdminApiKeyAuth: [] summary: Get code interpreter sessions usage details for the organization. operationId: usage-code-interpreter-sessions tags: @@ -17649,6 +21564,78 @@ paths: -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const response = await + client.admin.organization.usage.codeInterpreterSessions({ + start_time: 0 }); + + + console.log(response.data); + python: >- + import os + + from openai import OpenAI + + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + + response = + client.admin.organization.usage.code_interpreter_sessions( + start_time=0, + ) + + print(response.data) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tresponse, err := client.Admin.Organization.Usage.CodeInterpreterSessions(context.TODO(), openai.AdminOrganizationUsageCodeInterpreterSessionsParams{\n\t\tStartTime: 0,\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", response.Data)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.usage.UsageCodeInterpreterSessionsParams; + + import + com.openai.models.admin.organization.usage.UsageCodeInterpreterSessionsResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + UsageCodeInterpreterSessionsParams params = UsageCodeInterpreterSessionsParams.builder() + .startTime(0L) + .build(); + UsageCodeInterpreterSessionsResponse response = client.admin().organization().usage().codeInterpreterSessions(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + response = + openai.admin.organization.usage.code_interpreter_sessions(start_time: + 0) + + + puts(response) response: | { "object": "page", @@ -17671,6 +21658,8 @@ paths: } /organization/usage/completions: get: + security: + - AdminApiKeyAuth: [] summary: Get completions usage details for the organization. operationId: usage-completions tags: @@ -17796,6 +21785,71 @@ paths: -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const response = await + client.admin.organization.usage.completions({ start_time: 0 }); + + + console.log(response.data); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + response = client.admin.organization.usage.completions( + start_time=0, + ) + print(response.data) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tresponse, err := client.Admin.Organization.Usage.Completions(context.TODO(), openai.AdminOrganizationUsageCompletionsParams{\n\t\tStartTime: 0,\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", response.Data)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.usage.UsageCompletionsParams; + + import + com.openai.models.admin.organization.usage.UsageCompletionsResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + UsageCompletionsParams params = UsageCompletionsParams.builder() + .startTime(0L) + .build(); + UsageCompletionsResponse response = client.admin().organization().usage().completions(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + response = openai.admin.organization.usage.completions(start_time: + 0) + + + puts(response) response: | { "object": "page", @@ -17828,6 +21882,8 @@ paths: } /organization/usage/embeddings: get: + security: + - AdminApiKeyAuth: [] summary: Get embeddings usage details for the organization. operationId: usage-embeddings tags: @@ -17943,6 +21999,71 @@ paths: -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const response = await + client.admin.organization.usage.embeddings({ start_time: 0 }); + + + console.log(response.data); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + response = client.admin.organization.usage.embeddings( + start_time=0, + ) + print(response.data) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tresponse, err := client.Admin.Organization.Usage.Embeddings(context.TODO(), openai.AdminOrganizationUsageEmbeddingsParams{\n\t\tStartTime: 0,\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", response.Data)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.usage.UsageEmbeddingsParams; + + import + com.openai.models.admin.organization.usage.UsageEmbeddingsResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + UsageEmbeddingsParams params = UsageEmbeddingsParams.builder() + .startTime(0L) + .build(); + UsageEmbeddingsResponse response = client.admin().organization().usage().embeddings(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + response = openai.admin.organization.usage.embeddings(start_time: + 0) + + + puts(response) response: | { "object": "page", @@ -17969,6 +22090,8 @@ paths: } /organization/usage/images: get: + security: + - AdminApiKeyAuth: [] summary: Get images usage details for the organization. operationId: usage-images tags: @@ -18118,6 +22241,67 @@ paths: -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const response = await client.admin.organization.usage.images({ + start_time: 0 }); + + + console.log(response.data); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + response = client.admin.organization.usage.images( + start_time=0, + ) + print(response.data) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tresponse, err := client.Admin.Organization.Usage.Images(context.TODO(), openai.AdminOrganizationUsageImagesParams{\n\t\tStartTime: 0,\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", response.Data)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.usage.UsageImagesParams; + + import + com.openai.models.admin.organization.usage.UsageImagesResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + UsageImagesParams params = UsageImagesParams.builder() + .startTime(0L) + .build(); + UsageImagesResponse response = client.admin().organization().usage().images(params); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + response = openai.admin.organization.usage.images(start_time: 0) + + puts(response) response: | { "object": "page", @@ -18146,6 +22330,8 @@ paths: } /organization/usage/moderations: get: + security: + - AdminApiKeyAuth: [] summary: Get moderations usage details for the organization. operationId: usage-moderations tags: @@ -18261,6 +22447,71 @@ paths: -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const response = await + client.admin.organization.usage.moderations({ start_time: 0 }); + + + console.log(response.data); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + response = client.admin.organization.usage.moderations( + start_time=0, + ) + print(response.data) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tresponse, err := client.Admin.Organization.Usage.Moderations(context.TODO(), openai.AdminOrganizationUsageModerationsParams{\n\t\tStartTime: 0,\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", response.Data)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.usage.UsageModerationsParams; + + import + com.openai.models.admin.organization.usage.UsageModerationsResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + UsageModerationsParams params = UsageModerationsParams.builder() + .startTime(0L) + .build(); + UsageModerationsResponse response = client.admin().organization().usage().moderations(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + response = openai.admin.organization.usage.moderations(start_time: + 0) + + + puts(response) response: | { "object": "page", @@ -18287,6 +22538,8 @@ paths: } /organization/usage/vector_stores: get: + security: + - AdminApiKeyAuth: [] summary: Get vector stores usage details for the organization. operationId: usage-vector-stores tags: @@ -18374,6 +22627,71 @@ paths: -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const response = await + client.admin.organization.usage.vectorStores({ start_time: 0 }); + + + console.log(response.data); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + response = client.admin.organization.usage.vector_stores( + start_time=0, + ) + print(response.data) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tresponse, err := client.Admin.Organization.Usage.VectorStores(context.TODO(), openai.AdminOrganizationUsageVectorStoresParams{\n\t\tStartTime: 0,\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", response.Data)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.usage.UsageVectorStoresParams; + + import + com.openai.models.admin.organization.usage.UsageVectorStoresResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + UsageVectorStoresParams params = UsageVectorStoresParams.builder() + .startTime(0L) + .build(); + UsageVectorStoresResponse response = client.admin().organization().usage().vectorStores(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + response = + openai.admin.organization.usage.vector_stores(start_time: 0) + + + puts(response) response: | { "object": "page", @@ -18396,6 +22714,8 @@ paths: } /organization/users: get: + security: + - AdminApiKeyAuth: [] summary: Lists all of the users in the organization. operationId: list-users tags: @@ -18446,6 +22766,57 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + // Automatically fetches more pages as needed. + + for await (const organizationUser of + client.admin.organization.users.list()) { + console.log(organizationUser.id); + } + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + page = client.admin.organization.users.list() + page = page.data[0] + print(page.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tpage, err := client.Admin.Organization.Users.List(context.TODO(), openai.AdminOrganizationUserListParams{})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", page)\n}\n" + java: |- + package com.openai.example; + + import com.openai.client.OpenAIClient; + import com.openai.client.okhttp.OpenAIOkHttpClient; + import com.openai.models.admin.organization.users.UserListPage; + import com.openai.models.admin.organization.users.UserListParams; + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + UserListPage page = client.admin().organization().users().list(); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + page = openai.admin.organization.users.list + + puts(page) response: | { "object": "list", @@ -18465,6 +22836,8 @@ paths: } /organization/users/{user_id}: get: + security: + - AdminApiKeyAuth: [] summary: Retrieves a user by their identifier. operationId: retrieve-user tags: @@ -18492,6 +22865,68 @@ paths: curl https://api.openai.com/v1/organization/users/user_abc \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const organizationUser = await + client.admin.organization.users.retrieve('user_id'); + + + console.log(organizationUser.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + organization_user = client.admin.organization.users.retrieve( + "user_id", + ) + print(organization_user.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\torganizationUser, err := client.Admin.Organization.Users.Get(context.TODO(), \"user_id\")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", organizationUser.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.users.OrganizationUser; + + import + com.openai.models.admin.organization.users.UserRetrieveParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + OrganizationUser organizationUser = client.admin().organization().users().retrieve("user_id"); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + organization_user = + openai.admin.organization.users.retrieve("user_id") + + + puts(organization_user) response: | { "object": "organization.user", @@ -18502,6 +22937,8 @@ paths: "added_at": 1711471533 } post: + security: + - AdminApiKeyAuth: [] summary: Modifies a user's role in the organization. operationId: modify-user tags: @@ -18540,6 +22977,68 @@ paths: -d '{ "role": "owner" }' + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const organizationUser = await + client.admin.organization.users.update('user_id'); + + + console.log(organizationUser.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + organization_user = client.admin.organization.users.update( + user_id="user_id", + ) + print(organization_user.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\torganizationUser, err := client.Admin.Organization.Users.Update(\n\t\tcontext.TODO(),\n\t\t\"user_id\",\n\t\topenai.AdminOrganizationUserUpdateParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", organizationUser.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.users.OrganizationUser; + + import + com.openai.models.admin.organization.users.UserUpdateParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + OrganizationUser organizationUser = client.admin().organization().users().update("user_id"); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + organization_user = + openai.admin.organization.users.update("user_id") + + + puts(organization_user) response: | { "object": "organization.user", @@ -18550,6 +23049,8 @@ paths: "added_at": 1711471533 } delete: + security: + - AdminApiKeyAuth: [] summary: Deletes a user from the organization. operationId: delete-user tags: @@ -18578,6 +23079,64 @@ paths: https://api.openai.com/v1/organization/users/user_abc \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const user = await + client.admin.organization.users.delete('user_id'); + + + console.log(user.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + user = client.admin.organization.users.delete( + "user_id", + ) + print(user.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tuser, err := client.Admin.Organization.Users.Delete(context.TODO(), \"user_id\")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", user.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.users.UserDeleteParams; + + import + com.openai.models.admin.organization.users.UserDeleteResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + UserDeleteResponse user = client.admin().organization().users().delete("user_id"); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + user = openai.admin.organization.users.delete("user_id") + + puts(user) response: | { "object": "organization.user.deleted", @@ -18586,6 +23145,8 @@ paths: } /organization/users/{user_id}/roles: get: + security: + - AdminApiKeyAuth: [] summary: Lists the organization roles assigned to a user within the organization. operationId: list-user-role-assignments tags: @@ -18639,6 +23200,66 @@ paths: https://api.openai.com/v1/organization/users/user_abc123/roles \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + // Automatically fetches more pages as needed. + + for await (const roleListResponse of + client.admin.organization.users.roles.list('user_id')) { + console.log(roleListResponse.id); + } + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + page = client.admin.organization.users.roles.list( + user_id="user_id", + ) + page = page.data[0] + print(page.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tpage, err := client.Admin.Organization.Users.Roles.List(\n\t\tcontext.TODO(),\n\t\t\"user_id\",\n\t\topenai.AdminOrganizationUserRoleListParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", page)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.users.roles.RoleListPage; + + import + com.openai.models.admin.organization.users.roles.RoleListParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + RoleListPage page = client.admin().organization().users().roles().list("user_id"); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + page = openai.admin.organization.users.roles.list("user_id") + + puts(page) response: | { "object": "list", @@ -18668,6 +23289,8 @@ paths: "next": null } post: + security: + - AdminApiKeyAuth: [] summary: Assigns an organization role to a user within the organization. operationId: assign-user-role tags: @@ -18706,6 +23329,74 @@ paths: -d '{ "role_id": "role_01J1F8ROLE01" }' + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const role = await + client.admin.organization.users.roles.create('user_id', { role_id: + 'role_id' }); + + + console.log(role.object); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + role = client.admin.organization.users.roles.create( + user_id="user_id", + role_id="role_id", + ) + print(role.object) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\trole, err := client.Admin.Organization.Users.Roles.New(\n\t\tcontext.TODO(),\n\t\t\"user_id\",\n\t\topenai.AdminOrganizationUserRoleNewParams{\n\t\t\tRoleID: \"role_id\",\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", role.Object)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.users.roles.RoleCreateParams; + + import + com.openai.models.admin.organization.users.roles.RoleCreateResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + RoleCreateParams params = RoleCreateParams.builder() + .userId("user_id") + .roleId("role_id") + .build(); + RoleCreateResponse role = client.admin().organization().users().roles().create(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + role = openai.admin.organization.users.roles.create("user_id", + role_id: "role_id") + + + puts(role) response: | { "object": "user.role", @@ -18732,6 +23423,8 @@ paths: } /organization/users/{user_id}/roles/{role_id}: delete: + security: + - AdminApiKeyAuth: [] summary: Unassigns an organization role from a user within the organization. operationId: unassign-user-role tags: @@ -18767,6 +23460,74 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const role = await + client.admin.organization.users.roles.delete('role_id', { user_id: + 'user_id' }); + + + console.log(role.deleted); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + role = client.admin.organization.users.roles.delete( + role_id="role_id", + user_id="user_id", + ) + print(role.deleted) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\trole, err := client.Admin.Organization.Users.Roles.Delete(\n\t\tcontext.TODO(),\n\t\t\"user_id\",\n\t\t\"role_id\",\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", role.Deleted)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.users.roles.RoleDeleteParams; + + import + com.openai.models.admin.organization.users.roles.RoleDeleteResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + RoleDeleteParams params = RoleDeleteParams.builder() + .userId("user_id") + .roleId("role_id") + .build(); + RoleDeleteResponse role = client.admin().organization().users().roles().delete(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + role = openai.admin.organization.users.roles.delete("role_id", + user_id: "user_id") + + + puts(role) response: | { "object": "user.role.deleted", @@ -18774,6 +23535,8 @@ paths: } /projects/{project_id}/groups/{group_id}/roles: get: + security: + - AdminApiKeyAuth: [] summary: Lists the project roles assigned to a group within a project. operationId: list-project-group-role-assignments tags: @@ -18834,6 +23597,79 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + // Automatically fetches more pages as needed. + + for await (const roleListResponse of + client.admin.organization.projects.groups.roles.list( + 'group_id', + { project_id: 'project_id' }, + )) { + console.log(roleListResponse.id); + } + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + page = client.admin.organization.projects.groups.roles.list( + group_id="group_id", + project_id="project_id", + ) + page = page.data[0] + print(page.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tpage, err := client.Admin.Organization.Projects.Groups.Roles.List(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\t\"group_id\",\n\t\topenai.AdminOrganizationProjectGroupRoleListParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", page)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.groups.roles.RoleListPage; + + import + com.openai.models.admin.organization.projects.groups.roles.RoleListParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + RoleListParams params = RoleListParams.builder() + .projectId("project_id") + .groupId("group_id") + .build(); + RoleListPage page = client.admin().organization().projects().groups().roles().list(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + page = + openai.admin.organization.projects.groups.roles.list("group_id", + project_id: "project_id") + + + puts(page) response: | { "object": "list", @@ -18863,6 +23699,8 @@ paths: "next": null } post: + security: + - AdminApiKeyAuth: [] summary: Assigns a project role to a group within a project. operationId: assign-project-group-role tags: @@ -18908,6 +23746,79 @@ paths: -d '{ "role_id": "role_01J1F8PROJ" }' + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const role = await + client.admin.organization.projects.groups.roles.create('group_id', + { + project_id: 'project_id', + role_id: 'role_id', + }); + + + console.log(role.group); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + role = client.admin.organization.projects.groups.roles.create( + group_id="group_id", + project_id="project_id", + role_id="role_id", + ) + print(role.group) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\trole, err := client.Admin.Organization.Projects.Groups.Roles.New(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\t\"group_id\",\n\t\topenai.AdminOrganizationProjectGroupRoleNewParams{\n\t\t\tRoleID: \"role_id\",\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", role.Group)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.groups.roles.RoleCreateParams; + + import + com.openai.models.admin.organization.projects.groups.roles.RoleCreateResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + RoleCreateParams params = RoleCreateParams.builder() + .projectId("project_id") + .groupId("group_id") + .roleId("role_id") + .build(); + RoleCreateResponse role = client.admin().organization().projects().groups().roles().create(params); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + role = openai.admin.organization.projects.groups.roles.create( + "group_id", + project_id: "project_id", + role_id: "role_id" + ) + + puts(role) response: | { "object": "group.role", @@ -18933,6 +23844,8 @@ paths: } /projects/{project_id}/groups/{group_id}/roles/{role_id}: delete: + security: + - AdminApiKeyAuth: [] summary: Unassigns a project role from a group within a project. operationId: unassign-project-group-role tags: @@ -18974,6 +23887,79 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const role = await + client.admin.organization.projects.groups.roles.delete('role_id', + { + project_id: 'project_id', + group_id: 'group_id', + }); + + + console.log(role.deleted); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + role = client.admin.organization.projects.groups.roles.delete( + role_id="role_id", + project_id="project_id", + group_id="group_id", + ) + print(role.deleted) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\trole, err := client.Admin.Organization.Projects.Groups.Roles.Delete(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\t\"group_id\",\n\t\t\"role_id\",\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", role.Deleted)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.groups.roles.RoleDeleteParams; + + import + com.openai.models.admin.organization.projects.groups.roles.RoleDeleteResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + RoleDeleteParams params = RoleDeleteParams.builder() + .projectId("project_id") + .groupId("group_id") + .roleId("role_id") + .build(); + RoleDeleteResponse role = client.admin().organization().projects().groups().roles().delete(params); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + role = openai.admin.organization.projects.groups.roles.delete( + "role_id", + project_id: "project_id", + group_id: "group_id" + ) + + puts(role) response: | { "object": "group.role.deleted", @@ -18981,6 +23967,8 @@ paths: } /projects/{project_id}/roles: get: + security: + - AdminApiKeyAuth: [] summary: Lists the roles configured for a project. operationId: list-project-roles tags: @@ -19036,6 +24024,66 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + // Automatically fetches more pages as needed. + + for await (const role of + client.admin.organization.projects.roles.list('project_id')) { + console.log(role.id); + } + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + page = client.admin.organization.projects.roles.list( + project_id="project_id", + ) + page = page.data[0] + print(page.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tpage, err := client.Admin.Organization.Projects.Roles.List(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\topenai.AdminOrganizationProjectRoleListParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", page)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.roles.RoleListPage; + + import + com.openai.models.admin.organization.projects.roles.RoleListParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + RoleListPage page = client.admin().organization().projects().roles().list("project_id"); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + page = openai.admin.organization.projects.roles.list("project_id") + + puts(page) response: | { "object": "list", @@ -19057,6 +24105,8 @@ paths: "next": null } post: + security: + - AdminApiKeyAuth: [] summary: Creates a custom role for a project. operationId: create-project-role tags: @@ -19100,6 +24150,77 @@ paths: ], "description": "Allows managing API keys for the project" }' + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const role = await + client.admin.organization.projects.roles.create('project_id', { + permissions: ['string'], + role_name: 'role_name', + }); + + + console.log(role.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + role = client.admin.organization.projects.roles.create( + project_id="project_id", + permissions=["string"], + role_name="role_name", + ) + print(role.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\trole, err := client.Admin.Organization.Projects.Roles.New(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\topenai.AdminOrganizationProjectRoleNewParams{\n\t\t\tPermissions: []string{\"string\"},\n\t\t\tRoleName: \"role_name\",\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", role.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.roles.RoleCreateParams; + + import com.openai.models.admin.organization.roles.Role; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + RoleCreateParams params = RoleCreateParams.builder() + .projectId("project_id") + .addPermission("string") + .roleName("role_name") + .build(); + Role role = client.admin().organization().projects().roles().create(params); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + role = openai.admin.organization.projects.roles.create( + "project_id", + permissions: ["string"], + role_name: "role_name" + ) + + puts(role) response: | { "object": "role", @@ -19115,6 +24236,8 @@ paths: } /projects/{project_id}/roles/{role_id}: post: + security: + - AdminApiKeyAuth: [] summary: Updates an existing project role. operationId: update-project-role tags: @@ -19165,6 +24288,74 @@ paths: ], "description": "Allows managing API keys for the project" }' + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const role = await + client.admin.organization.projects.roles.update('role_id', { + project_id: 'project_id', + }); + + + console.log(role.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + role = client.admin.organization.projects.roles.update( + role_id="role_id", + project_id="project_id", + ) + print(role.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\trole, err := client.Admin.Organization.Projects.Roles.Update(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\t\"role_id\",\n\t\topenai.AdminOrganizationProjectRoleUpdateParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", role.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.roles.RoleUpdateParams; + + import com.openai.models.admin.organization.roles.Role; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + RoleUpdateParams params = RoleUpdateParams.builder() + .projectId("project_id") + .roleId("role_id") + .build(); + Role role = client.admin().organization().projects().roles().update(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + role = openai.admin.organization.projects.roles.update("role_id", + project_id: "project_id") + + + puts(role) response: | { "object": "role", @@ -19179,6 +24370,8 @@ paths: "predefined_role": false } delete: + security: + - AdminApiKeyAuth: [] summary: Deletes a custom role from a project. operationId: delete-project-role tags: @@ -19214,6 +24407,75 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const role = await + client.admin.organization.projects.roles.delete('role_id', { + project_id: 'project_id', + }); + + + console.log(role.id); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + role = client.admin.organization.projects.roles.delete( + role_id="role_id", + project_id="project_id", + ) + print(role.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\trole, err := client.Admin.Organization.Projects.Roles.Delete(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\t\"role_id\",\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", role.ID)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.roles.RoleDeleteParams; + + import + com.openai.models.admin.organization.projects.roles.RoleDeleteResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + RoleDeleteParams params = RoleDeleteParams.builder() + .projectId("project_id") + .roleId("role_id") + .build(); + RoleDeleteResponse role = client.admin().organization().projects().roles().delete(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + role = openai.admin.organization.projects.roles.delete("role_id", + project_id: "project_id") + + + puts(role) response: | { "object": "role.deleted", @@ -19222,6 +24484,8 @@ paths: } /projects/{project_id}/users/{user_id}/roles: get: + security: + - AdminApiKeyAuth: [] summary: Lists the project roles assigned to a user within a project. operationId: list-project-user-role-assignments tags: @@ -19282,6 +24546,79 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + // Automatically fetches more pages as needed. + + for await (const roleListResponse of + client.admin.organization.projects.users.roles.list( + 'user_id', + { project_id: 'project_id' }, + )) { + console.log(roleListResponse.id); + } + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + page = client.admin.organization.projects.users.roles.list( + user_id="user_id", + project_id="project_id", + ) + page = page.data[0] + print(page.id) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\tpage, err := client.Admin.Organization.Projects.Users.Roles.List(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\t\"user_id\",\n\t\topenai.AdminOrganizationProjectUserRoleListParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", page)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.users.roles.RoleListPage; + + import + com.openai.models.admin.organization.projects.users.roles.RoleListParams; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + RoleListParams params = RoleListParams.builder() + .projectId("project_id") + .userId("user_id") + .build(); + RoleListPage page = client.admin().organization().projects().users().roles().list(params); + } + } + ruby: >- + require "openai" + + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + + page = + openai.admin.organization.projects.users.roles.list("user_id", + project_id: "project_id") + + + puts(page) response: | { "object": "list", @@ -19311,6 +24648,8 @@ paths: "next": null } post: + security: + - AdminApiKeyAuth: [] summary: Assigns a project role to a user within a project. operationId: assign-project-user-role tags: @@ -19356,6 +24695,78 @@ paths: -d '{ "role_id": "role_01J1F8PROJ" }' + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const role = await + client.admin.organization.projects.users.roles.create('user_id', { + project_id: 'project_id', + role_id: 'role_id', + }); + + + console.log(role.object); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + role = client.admin.organization.projects.users.roles.create( + user_id="user_id", + project_id="project_id", + role_id="role_id", + ) + print(role.object) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\trole, err := client.Admin.Organization.Projects.Users.Roles.New(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\t\"user_id\",\n\t\topenai.AdminOrganizationProjectUserRoleNewParams{\n\t\t\tRoleID: \"role_id\",\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", role.Object)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.users.roles.RoleCreateParams; + + import + com.openai.models.admin.organization.projects.users.roles.RoleCreateResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + RoleCreateParams params = RoleCreateParams.builder() + .projectId("project_id") + .userId("user_id") + .roleId("role_id") + .build(); + RoleCreateResponse role = client.admin().organization().projects().users().roles().create(params); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + role = openai.admin.organization.projects.users.roles.create( + "user_id", + project_id: "project_id", + role_id: "role_id" + ) + + puts(role) response: | { "object": "user.role", @@ -19382,6 +24793,8 @@ paths: } /projects/{project_id}/users/{user_id}/roles/{role_id}: delete: + security: + - AdminApiKeyAuth: [] summary: Unassigns a project role from a user within a project. operationId: unassign-project-user-role tags: @@ -19423,6 +24836,78 @@ paths: \ -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \ -H "Content-Type: application/json" + node.js: >- + import OpenAI from 'openai'; + + + const client = new OpenAI({ + adminAPIKey: process.env['OPENAI_ADMIN_KEY'], // This is the default and can be omitted + }); + + + const role = await + client.admin.organization.projects.users.roles.delete('role_id', { + project_id: 'project_id', + user_id: 'user_id', + }); + + + console.log(role.deleted); + python: |- + import os + from openai import OpenAI + + client = OpenAI( + admin_api_key=os.environ.get("OPENAI_ADMIN_KEY"), # This is the default and can be omitted + ) + role = client.admin.organization.projects.users.roles.delete( + role_id="role_id", + project_id="project_id", + user_id="user_id", + ) + print(role.deleted) + go: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/openai/openai-go\"\n\t\"github.com/openai/openai-go/option\"\n)\n\nfunc main() {\n\tclient := openai.NewClient(\n\t\toption.WithAdminAPIKey(\"My Admin API Key\"),\n\t)\n\trole, err := client.Admin.Organization.Projects.Users.Roles.Delete(\n\t\tcontext.TODO(),\n\t\t\"project_id\",\n\t\t\"user_id\",\n\t\t\"role_id\",\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", role.Deleted)\n}\n" + java: >- + package com.openai.example; + + + import com.openai.client.OpenAIClient; + + import com.openai.client.okhttp.OpenAIOkHttpClient; + + import + com.openai.models.admin.organization.projects.users.roles.RoleDeleteParams; + + import + com.openai.models.admin.organization.projects.users.roles.RoleDeleteResponse; + + + public final class Main { + private Main() {} + + public static void main(String[] args) { + OpenAIClient client = OpenAIOkHttpClient.fromEnv(); + + RoleDeleteParams params = RoleDeleteParams.builder() + .projectId("project_id") + .userId("user_id") + .roleId("role_id") + .build(); + RoleDeleteResponse role = client.admin().organization().projects().users().roles().delete(params); + } + } + ruby: |- + require "openai" + + openai = OpenAI::Client.new(admin_api_key: "My Admin API Key") + + role = openai.admin.organization.projects.users.roles.delete( + "role_id", + project_id: "project_id", + user_id: "user_id" + ) + + puts(role) response: | { "object": "user.role.deleted", @@ -20164,7 +25649,7 @@ paths: "speed": 1.1, "tracing": "auto", "client_secret": { - "value": "ek_abc123", + "value": "ek_abc123", "expires_at": 1234567890 } } @@ -20174,7 +25659,7 @@ paths: Create an ephemeral API token for use in client-side applications with the - Realtime API specifically for realtime transcriptions. + Realtime API specifically for realtime transcriptions. Can be configured with the same session parameters as the `transcription_session.update` client event. @@ -20239,6 +25724,102 @@ paths: }, "client_secret": null } + /realtime/translations/client_secrets: + post: + summary: > + Create a Realtime translation client secret with an associated + translation session configuration. + + + Client secrets are short-lived tokens that can be passed to a client + app, + + such as a web frontend or mobile client, which grants access to the + Realtime + + Translation API without leaking your main API key. You can configure a + custom + + TTL for each client secret. + + + Returns the created client secret and the effective translation session + object. + + The client secret is a string that looks like `ek_1234`. + operationId: create-realtime-translation-client-secret + tags: + - Realtime + requestBody: + description: >- + Create a client secret with the given translation session + configuration. + required: true + content: + application/json: + schema: + $ref: >- + #/components/schemas/RealtimeTranslationClientSecretCreateRequest + responses: + '200': + description: Translation client secret created successfully. + content: + application/json: + schema: + $ref: >- + #/components/schemas/RealtimeTranslationClientSecretCreateResponse + x-oaiMeta: + name: Create translation client secret + group: realtime + examples: + request: + curl: > + curl -X POST + https://api.openai.com/v1/realtime/translations/client_secrets \ + -H "Authorization: Bearer $OPENAI_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "expires_after": { + "anchor": "created_at", + "seconds": 600 + }, + "session": { + "model": "gpt-realtime-translate", + "audio": { + "input": { + "transcription": { + "model": "gpt-realtime-whisper" + }, + "noise_reduction": null + }, + "output": { + "language": "es" + } + } + } + }' + response: | + { + "value": "ek_68af296e8e408191a1120ab6383263c2", + "expires_at": 1756310470, + "session": { + "id": "sess_C9CiUVUzUzYIssh3ELY1d", + "type": "translation", + "expires_at": 1756310470, + "model": "gpt-realtime-translate", + "audio": { + "input": { + "transcription": { + "model": "gpt-realtime-whisper" + }, + "noise_reduction": null + }, + "output": { + "language": "es" + } + } + } + } /responses: post: operationId: createResponse @@ -22058,7 +27639,7 @@ paths: - Responses summary: | Cancels a model response with the given ID. Only responses created with - the `background` parameter set to `true` can be cancelled. + the `background` parameter set to `true` can be cancelled. [Learn more](/docs/guides/background). parameters: - in: path @@ -26339,9 +31920,9 @@ paths: For certain `purpose` values, the correct `mime_type` must be - specified. + specified. - Please refer to documentation for the + Please refer to documentation for the [supported MIME types for your use case](/docs/assistants/tools/file-search#supported-files). @@ -26559,7 +32140,7 @@ paths: tags: - Uploads summary: > - Completes the [Upload](/docs/api-reference/uploads/object). + Completes the [Upload](/docs/api-reference/uploads/object). Within the returned Upload object, there is a nested @@ -26697,7 +32278,7 @@ paths: summary: > Adds a [Part](/docs/api-reference/uploads/part-object) to an [Upload](/docs/api-reference/uploads/object) object. A Part represents a - chunk of bytes from the file you are trying to upload. + chunk of bytes from the file you are trying to upload. Each Part can be at most 64 MB, and you can add Parts until you hit the @@ -32498,6 +38079,262 @@ paths: "has_more": false, "object": "list" } +webhooks: + batch_cancelled: + post: + description: | + Sent when a batch has been cancelled. + requestBody: + description: The event payload sent by the API. + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookBatchCancelled' + responses: + '200': + description: > + Return a 200 status code to acknowledge receipt of the event. + Non-200 + + status codes will be retried. + batch_completed: + post: + description: | + Sent when a batch has completed processing. + requestBody: + description: The event payload sent by the API. + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookBatchCompleted' + responses: + '200': + description: > + Return a 200 status code to acknowledge receipt of the event. + Non-200 + + status codes will be retried. + batch_expired: + post: + description: | + Sent when a batch has expired before completion. + requestBody: + description: The event payload sent by the API. + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookBatchExpired' + responses: + '200': + description: > + Return a 200 status code to acknowledge receipt of the event. + Non-200 + + status codes will be retried. + batch_failed: + post: + description: | + Sent when a batch has failed. + requestBody: + description: The event payload sent by the API. + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookBatchFailed' + responses: + '200': + description: > + Return a 200 status code to acknowledge receipt of the event. + Non-200 + + status codes will be retried. + eval_run_canceled: + post: + description: | + Sent when an eval run has been canceled. + requestBody: + description: The event payload sent by the API. + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookEvalRunCanceled' + responses: + '200': + description: > + Return a 200 status code to acknowledge receipt of the event. + Non-200 + + status codes will be retried. + eval_run_failed: + post: + description: | + Sent when an eval run has failed. + requestBody: + description: The event payload sent by the API. + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookEvalRunFailed' + responses: + '200': + description: > + Return a 200 status code to acknowledge receipt of the event. + Non-200 + + status codes will be retried. + eval_run_succeeded: + post: + description: | + Sent when an eval run has succeeded. + requestBody: + description: The event payload sent by the API. + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookEvalRunSucceeded' + responses: + '200': + description: > + Return a 200 status code to acknowledge receipt of the event. + Non-200 + + status codes will be retried. + fine_tuning_job_cancelled: + post: + description: | + Sent when a fine-tuning job has been cancelled. + requestBody: + description: The event payload sent by the API. + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookFineTuningJobCancelled' + responses: + '200': + description: > + Return a 200 status code to acknowledge receipt of the event. + Non-200 + + status codes will be retried. + fine_tuning_job_failed: + post: + description: | + Sent when a fine-tuning job has failed. + requestBody: + description: The event payload sent by the API. + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookFineTuningJobFailed' + responses: + '200': + description: > + Return a 200 status code to acknowledge receipt of the event. + Non-200 + + status codes will be retried. + fine_tuning_job_succeeded: + post: + description: | + Sent when a fine-tuning job has succeeded. + requestBody: + description: The event payload sent by the API. + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookFineTuningJobSucceeded' + responses: + '200': + description: > + Return a 200 status code to acknowledge receipt of the event. + Non-200 + + status codes will be retried. + realtime_call_incoming: + post: + description: | + Sent when Realtime API Receives a incoming SIP call. + requestBody: + description: The event payload sent by the API. + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookRealtimeCallIncoming' + responses: + '200': + description: > + Return a 200 status code to acknowledge receipt of the event. + Non-200 + + status codes will be retried. + response_cancelled: + post: + description: | + Sent when a background response has been cancelled. + requestBody: + description: The event payload sent by the API. + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookResponseCancelled' + responses: + '200': + description: > + Return a 200 status code to acknowledge receipt of the event. + Non-200 + + status codes will be retried. + response_completed: + post: + description: | + Sent when a background response has completed successfully. + requestBody: + description: The event payload sent by the API. + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookResponseCompleted' + responses: + '200': + description: > + Return a 200 status code to acknowledge receipt of the event. + Non-200 + + status codes will be retried. + response_failed: + post: + description: | + Sent when a background response has failed. + requestBody: + description: The event payload sent by the API. + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookResponseFailed' + responses: + '200': + description: > + Return a 200 status code to acknowledge receipt of the event. + Non-200 + + status codes will be retried. + response_incomplete: + post: + description: | + Sent when a background response is incomplete. + requestBody: + description: The event payload sent by the API. + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookResponseIncomplete' + responses: + '200': + description: > + Return a 200 status code to acknowledge receipt of the event. + Non-200 + + status codes will be retried. components: schemas: AddUploadPartRequest: @@ -32517,7 +38354,8 @@ components: properties: object: type: string - example: organization.admin_api_key + enum: + - organization.admin_api_key description: The object type, which is always `organization.admin_api_key` x-stainless-const: true id: @@ -32525,26 +38363,24 @@ components: example: key_abc description: The identifier, which can be referenced in API endpoints name: - type: string + anyOf: + - type: string + - type: 'null' example: Administration Key description: The name of the API key redacted_value: type: string example: sk-admin...def description: The redacted value of the API key - value: - type: string - example: sk-admin-1234abcd - description: The value of the API key. Only shown on create. created_at: type: integer - format: int64 + format: unixtime example: 1711471533 description: The Unix timestamp (in seconds) of when the API key was created last_used_at: anyOf: - type: integer - format: int64 + format: unixtime example: 1711471534 description: >- The Unix timestamp (in seconds) of when the API key was last @@ -32571,7 +38407,7 @@ components: description: The name of the user created_at: type: integer - format: int64 + format: unixtime example: 1711471533 description: The Unix timestamp (in seconds) of when the user was created role: @@ -32581,9 +38417,7 @@ components: required: - object - redacted_value - - name - created_at - - last_used_at - id - owner x-oaiMeta: @@ -32605,12 +38439,29 @@ components: "role": "owner" } } + AdminApiKeyCreateResponse: + allOf: + - $ref: '#/components/schemas/AdminApiKey' + - type: object + description: >- + The newly created admin API key. The `value` field is only returned + once, when the key is created. + properties: + value: + type: string + example: sk-admin-1234abcd + description: The value of the API key. Only shown on create. + required: + - value ApiKeyList: type: object properties: object: type: string + enum: + - list example: list + x-stainless-const: true data: type: array items: @@ -32619,11 +38470,19 @@ components: type: boolean example: false first_id: - type: string + anyOf: + - type: string + - type: 'null' example: key_abc last_id: - type: string + anyOf: + - type: string + - type: 'null' example: key_xyz + required: + - object + - data + - has_more AssignedRoleDetails: type: object description: >- @@ -32656,7 +38515,7 @@ components: description: When the role was created. anyOf: - type: integer - format: int64 + format: unixtime - type: 'null' updated_at: description: When the role was last updated. @@ -32710,6 +38569,7 @@ components: created_at: description: The Unix timestamp (in seconds) for when the assistant was created. type: integer + format: unixtime name: anyOf: - description: | @@ -33139,9 +38999,9 @@ components: description: > The model to use for transcription. Current options are `whisper-1`, `gpt-4o-mini-transcribe`, `gpt-4o-mini-transcribe-2025-12-15`, - `gpt-4o-transcribe`, and `gpt-4o-transcribe-diarize`. Use - `gpt-4o-transcribe-diarize` when you need diarization with speaker - labels. + `gpt-4o-transcribe`, `gpt-4o-transcribe-diarize`, and + `gpt-realtime-whisper`. Use `gpt-4o-transcribe-diarize` when you + need diarization with speaker labels. anyOf: - type: string - type: string @@ -33151,6 +39011,7 @@ components: - gpt-4o-mini-transcribe-2025-12-15 - gpt-4o-transcribe - gpt-4o-transcribe-diarize + - gpt-realtime-whisper language: type: string description: > @@ -33174,6 +39035,52 @@ components: For `gpt-4o-transcribe` models (excluding `gpt-4o-transcribe-diarize`), the prompt is a free text string, for example "expect words related to technology". + + Prompt is not supported with `gpt-realtime-whisper` in GA Realtime + sessions. + delay: + type: string + description: > + Controls how long the model waits before emitting transcription + text. + + Higher values can improve transcription accuracy at the cost of + latency. + + Only supported with `gpt-realtime-whisper` in GA Realtime sessions. + enum: + - minimal + - low + - medium + - high + - xhigh + AudioTranscriptionResponse: + type: object + properties: + model: + description: > + The model used for transcription. Current options are `whisper-1`, + `gpt-4o-mini-transcribe`, `gpt-4o-mini-transcribe-2025-12-15`, + `gpt-4o-transcribe`, `gpt-4o-transcribe-diarize`, and + `gpt-realtime-whisper`. + anyOf: + - type: string + - type: string + enum: + - whisper-1 + - gpt-4o-mini-transcribe + - gpt-4o-mini-transcribe-2025-12-15 + - gpt-4o-transcribe + - gpt-4o-transcribe-diarize + - gpt-realtime-whisper + language: + type: string + description: | + The language of the input audio. + prompt: + type: string + description: | + The prompt configured for input audio transcription, when present. AuditLog: type: object description: A log of a user action or configuration change within this organization. @@ -33185,6 +39092,7 @@ components: $ref: '#/components/schemas/AuditLogEventType' effective_at: type: integer + format: unixtime description: The Unix timestamp (in seconds) of the event. project: type: object @@ -33200,7 +39108,9 @@ components: type: string description: The project title. actor: - $ref: '#/components/schemas/AuditLogActor' + anyOf: + - $ref: '#/components/schemas/AuditLogActor' + - type: 'null' api_key.created: type: object description: The details for events with this `type`. @@ -33852,7 +39762,6 @@ components: - id - type - effective_at - - actor x-oaiMeta: name: The audit log object example: | @@ -34092,36 +40001,45 @@ components: description: The ID of the file containing the outputs of requests with errors. created_at: type: integer + format: unixtime description: The Unix timestamp (in seconds) for when the batch was created. in_progress_at: type: integer + format: unixtime description: >- The Unix timestamp (in seconds) for when the batch started processing. expires_at: type: integer + format: unixtime description: The Unix timestamp (in seconds) for when the batch will expire. finalizing_at: type: integer + format: unixtime description: >- The Unix timestamp (in seconds) for when the batch started finalizing. completed_at: type: integer + format: unixtime description: The Unix timestamp (in seconds) for when the batch was completed. failed_at: type: integer + format: unixtime description: The Unix timestamp (in seconds) for when the batch failed. expired_at: type: integer + format: unixtime description: The Unix timestamp (in seconds) for when the batch expired. cancelling_at: type: integer + format: unixtime description: >- The Unix timestamp (in seconds) for when the batch started cancelling. cancelled_at: type: integer + format: unixtime description: The Unix timestamp (in seconds) for when the batch was cancelled. request_counts: type: object @@ -34263,6 +40181,7 @@ components: The number of seconds after the anchor time that the file will expire. Must be between 3600 (1 hour) and 2592000 (30 days). type: integer + format: int64 minimum: 3600 maximum: 2592000 required: @@ -34295,10 +40214,13 @@ components: type: string description: The identifier, which can be referenced in API endpoints name: - type: string + anyOf: + - type: string + - type: 'null' description: The name of the certificate. created_at: type: integer + format: unixtime description: >- The Unix timestamp (in seconds) of when the certificate was uploaded. @@ -34307,11 +40229,13 @@ components: properties: valid_at: type: integer + format: unixtime description: >- The Unix timestamp (in seconds) of when the certificate becomes valid. expires_at: type: integer + format: unixtime description: The Unix timestamp (in seconds) of when the certificate expires. content: type: string @@ -35015,14 +40939,14 @@ components: type: string description: > The name of the file, used when passing the file to the model as - a + a string. file_data: type: string description: > The base64 encoded file data, used when passing the file to the - model + model as a string. file_id: @@ -35280,6 +41204,7 @@ components: the message. url: type: string + format: uri description: The URL of the web resource. title: type: string @@ -35331,6 +41256,7 @@ components: description: Unique identifier for this audio response. expires_at: type: integer + format: unixtime description: > The Unix timestamp (in seconds) for when this audio response will @@ -35489,8 +41415,8 @@ components: top_logprobs: description: >- List of the most likely tokens and their log probability, at this - token position. In rare cases, there may be fewer than the number of - requested `top_logprobs` returned. + token position. The number of entries may be fewer than the + requested `top_logprobs`. type: array items: type: object @@ -35936,12 +41862,13 @@ components: default: computer_screenshot description: > Specifies the event type. For a computer screenshot, this property - is + is always set to `computer_screenshot`. x-stainless-const: true image_url: type: string + format: uri description: The URL of the screenshot image. file_id: type: string @@ -36110,6 +42037,7 @@ components: description: The container this file belongs to. created_at: type: integer + format: unixtime description: Unix timestamp (in seconds) when the file was created. bytes: type: integer @@ -36183,12 +42111,14 @@ components: description: Name of the container. created_at: type: integer + format: unixtime description: Unix timestamp (in seconds) when the container was created. status: type: string description: Status of the container (e.g., active, deleted). last_active_at: type: integer + format: unixtime description: Unix timestamp (in seconds) when the container was last active. expires_after: type: object @@ -36384,6 +42314,20 @@ components: When `group_by=project_id`, this field provides the project ID of the grouped costs result. - type: 'null' + api_key_id: + anyOf: + - type: string + description: >- + When `group_by=api_key_id`, this field provides the API Key ID + of the grouped costs result. + - type: 'null' + quantity: + anyOf: + - type: number + description: >- + When `group_by=line_item`, this field provides the quantity of + the grouped costs result. + - type: 'null' required: - object x-oaiMeta: @@ -36396,7 +42340,8 @@ components: "currency": "usd" }, "line_item": "Image models", - "project_id": "proj_abc" + "project_id": "proj_abc", + "quantity": 10000 } CreateAssistantRequest: type: object @@ -36722,11 +42667,16 @@ components: $ref: '#/components/schemas/WebSearchContextSize' top_logprobs: description: > - An integer between 0 and 20 specifying the number of most likely - tokens to + An integer between 0 and 20 specifying the maximum number of + most likely + + tokens to return at each token position, each with an associated + log - return at each token position, each with an associated log - probability. + probability. In some cases, the number of returned tokens may be + fewer than + + requested. `logprobs` must be set to `true` if this parameter is used. type: integer @@ -36927,8 +42877,8 @@ components: - $ref: '#/components/schemas/PredictionContent' seed: type: integer - minimum: -922337203685477600 - maximum: 922337203685477600 + minimum: -9223372036854776000 + maximum: 9223372036854776000 nullable: true deprecated: true description: > @@ -37091,6 +43041,7 @@ components: - type: 'null' created: type: integer + format: unixtime description: >- The Unix timestamp (in seconds) of when the chat completion was created. @@ -37168,7 +43119,7 @@ components: type: object description: | Represents a streamed chunk of a chat completion response returned - by the model, based on the provided input. + by the model, based on the provided input. [Learn more](/docs/guides/streaming-responses). properties: id: @@ -37243,6 +43194,7 @@ components: description: The index of the choice in the list of choices. created: type: integer + format: unixtime description: >- The Unix timestamp (in seconds) of when the chat completion was created. Each chunk has the same timestamp. @@ -37630,6 +43582,7 @@ components: type: string created: type: integer + format: unixtime description: The Unix timestamp (in seconds) of when the completion was created. model: type: string @@ -38110,7 +44063,7 @@ components: title: JsonlRunDataSource description: > A JsonlRunDataSource object with that specifies a JSONL file that - matches the eval + matches the eval properties: type: type: string @@ -38619,7 +44572,7 @@ components: x-stainless-const: true - type: number minimum: 0 - exclusiveMinimum: 0 + exclusiveMinimum: true default: auto n_epochs: description: > @@ -38887,22 +44840,32 @@ components: nullable: true description: The number of images to generate. Must be between 1 and 10. size: - type: string - enum: - - 256x256 - - 512x512 - - 1024x1024 - - 1536x1024 - - 1024x1536 - - auto + anyOf: + - type: string + - type: string + enum: + - 256x256 + - 512x512 + - 1024x1024 + - 1536x1024 + - 1024x1536 + - auto default: 1024x1024 example: 1024x1024 nullable: true description: >- - The size of the generated images. Must be one of `1024x1024`, - `1536x1024` (landscape), `1024x1536` (portrait), or `auto` (default - value) for the GPT image models, and one of `256x256`, `512x512`, or - `1024x1024` for `dall-e-2`. + The size of the generated images. For `gpt-image-2` and + `gpt-image-2-2026-04-21`, arbitrary resolutions are supported as + `WIDTHxHEIGHT` strings, for example `1536x864`. Width and height + must both be divisible by 16 and the requested aspect ratio must be + between 1:3 and 3:1. Resolutions above `2560x1440` are experimental, + and the maximum supported resolution is `3840x2160`. The requested + size must also satisfy the model's current pixel and edge limits. + The standard sizes `1024x1024`, `1536x1024`, and `1024x1536` are + supported by the GPT image models; `auto` is supported for models + that allow automatic sizing. For `dall-e-2`, use one of `256x256`, + `512x512`, or `1024x1024`. For `dall-e-3`, use one of `1024x1024`, + `1792x1024`, or `1024x1792`. response_format: type: string enum: @@ -39100,25 +45063,34 @@ components: partial_images: $ref: '#/components/schemas/PartialImages' size: - type: string - enum: - - auto - - 1024x1024 - - 1536x1024 - - 1024x1536 - - 256x256 - - 512x512 - - 1792x1024 - - 1024x1792 + anyOf: + - type: string + - type: string + enum: + - auto + - 1024x1024 + - 1536x1024 + - 1024x1536 + - 256x256 + - 512x512 + - 1792x1024 + - 1024x1792 default: auto example: 1024x1024 nullable: true description: >- - The size of the generated images. Must be one of `1024x1024`, - `1536x1024` (landscape), `1024x1536` (portrait), or `auto` (default - value) for the GPT image models, one of `256x256`, `512x512`, or - `1024x1024` for `dall-e-2`, and one of `1024x1024`, `1792x1024`, or - `1024x1792` for `dall-e-3`. + The size of the generated images. For `gpt-image-2` and + `gpt-image-2-2026-04-21`, arbitrary resolutions are supported as + `WIDTHxHEIGHT` strings, for example `1536x864`. Width and height + must both be divisible by 16 and the requested aspect ratio must be + between 1:3 and 3:1. Resolutions above `2560x1440` are experimental, + and the maximum supported resolution is `3840x2160`. The requested + size must also satisfy the model's current pixel and edge limits. + The standard sizes `1024x1024`, `1536x1024`, and `1024x1536` are + supported by the GPT image models; `auto` is supported for models + that allow automatic sizing. For `dall-e-2`, use one of `256x256`, + `512x512`, or `1024x1024`. For `dall-e-3`, use one of `1024x1024`, + `1792x1024`, or `1024x1792`. moderation: type: string enum: @@ -39318,11 +45290,16 @@ components: properties: top_logprobs: description: > - An integer between 0 and 20 specifying the number of most likely - tokens to + An integer between 0 and 20 specifying the maximum number of + most likely + + tokens to return at each token position, each with an associated + log - return at each token position, each with an associated log - probability. + probability. In some cases, the number of returned tokens may be + fewer than + + requested. type: integer minimum: 0 maximum: 20 @@ -40594,7 +46571,7 @@ components: object can be provided to tweak VAD detection parameters manually. If unset, the audio is transcribed as a single block. Required when using `gpt-4o-transcribe-diarize` for inputs - longer than 30 seconds. + longer than 30 seconds. anyOf: - type: string enum: @@ -40646,6 +46623,7 @@ components: x-stainless-const: true duration: type: number + format: double description: Duration of the input audio in seconds. text: type: string @@ -40779,6 +46757,7 @@ components: description: The language of the input audio. duration: type: number + format: double description: The duration of the input audio. text: type: string @@ -40899,6 +46878,7 @@ components: description: The language of the output translation (always `english`). duration: type: number + format: double description: The duration of the input audio. text: type: string @@ -41837,6 +47817,7 @@ components: - $ref: '#/components/schemas/EvalGraderScoreModel' created_at: type: integer + format: unixtime description: The Unix timestamp (in seconds) for when the eval was created. metadata: $ref: '#/components/schemas/Metadata' @@ -42150,6 +48131,7 @@ components: x-stainless-const: true image_url: type: string + format: uri description: | The URL of the image input. detail: @@ -42484,9 +48466,11 @@ components: description: The name of the evaluation run. created_at: type: integer + format: unixtime description: Unix timestamp (in seconds) when the evaluation run was created. report_url: type: string + format: uri description: The URL to the rendered evaluation run report on the UI dashboard. result_counts: type: object @@ -42861,6 +48845,7 @@ components: description: The identifier of the evaluation group. created_at: type: integer + format: unixtime description: Unix timestamp (in seconds) when the evaluation run was created. status: type: string @@ -43286,6 +49271,7 @@ components: The number of seconds after the anchor time that the file will expire. Must be between 3600 (1 hour) and 2592000 (30 days). type: integer + format: int64 minimum: 3600 maximum: 2592000 required: @@ -43450,7 +49436,7 @@ components: - type: number minimum: 0 maximum: 2 - exclusiveMinimum: 0 + exclusiveMinimum: true default: auto batch_size: description: > @@ -43477,7 +49463,7 @@ components: x-stainless-const: true - type: number minimum: 0 - exclusiveMinimum: 0 + exclusiveMinimum: true default: auto n_epochs: description: > @@ -43548,7 +49534,7 @@ components: x-stainless-const: true - type: number minimum: 0 - exclusiveMinimum: 0 + exclusiveMinimum: true default: auto n_epochs: description: > @@ -43585,7 +49571,7 @@ components: - type: number minimum: 0.00001 maximum: 10 - exclusiveMinimum: 10 + exclusiveMinimum: true default: auto eval_interval: description: | @@ -43655,7 +49641,7 @@ components: x-stainless-const: true - type: number minimum: 0 - exclusiveMinimum: 0 + exclusiveMinimum: true default: auto n_epochs: description: > @@ -43690,6 +49676,7 @@ components: endpoints. created_at: type: integer + format: unixtime description: The Unix timestamp (in seconds) for when the permission was created. project_id: type: string @@ -43786,6 +49773,7 @@ components: description: The object identifier, which can be referenced in the API endpoints. created_at: type: integer + format: unixtime description: >- The Unix timestamp (in seconds) for when the fine-tuning job was created. @@ -43825,6 +49813,7 @@ components: finished_at: anyOf: - type: integer + format: unixtime description: >- The Unix timestamp (in seconds) for when the fine-tuning job was finished. The value will be null if the fine-tuning job is still @@ -43866,7 +49855,7 @@ components: x-stainless-const: true - type: number minimum: 0 - exclusiveMinimum: 0 + exclusiveMinimum: true default: auto n_epochs: description: > @@ -43953,6 +49942,7 @@ components: estimated_finish: anyOf: - type: integer + format: unixtime description: >- The Unix timestamp (in seconds) for when the fine-tuning job is estimated to finish. The value will be null if the fine-tuning @@ -44032,6 +50022,7 @@ components: endpoints. created_at: type: integer + format: unixtime description: The Unix timestamp (in seconds) for when the checkpoint was created. fine_tuned_model_checkpoint: type: string @@ -44111,6 +50102,7 @@ components: description: The object identifier. created_at: type: integer + format: unixtime description: >- The Unix timestamp (in seconds) for when the fine-tuning job was created. @@ -44194,7 +50186,7 @@ components: See the [guide](/docs/guides/function-calling) for examples, and the [JSON Schema reference](https://json-schema.org/understanding-json-schema/) for - documentation about the format. + documentation about the format. Omitting `parameters` defines a function with an empty parameter list. @@ -44203,7 +50195,7 @@ components: type: object title: Function tool call description: > - A tool call to run a function. See the + A tool call to run a function. See the [function calling guide](/docs/guides/function-calling) for more information. @@ -44725,10 +50717,10 @@ components: - rouge_l description: > The evaluation metric to use. One of `cosine`, `fuzzy_match`, - `bleu`, + `bleu`, `gleu`, `meteor`, `rouge_1`, `rouge_2`, `rouge_3`, `rouge_4`, - `rouge_5`, + `rouge_5`, or `rouge_l`. required: @@ -44766,7 +50758,7 @@ components: description: Display name of the group. created_at: type: integer - format: int64 + format: unixtime description: Unix timestamp (in seconds) when the group was created. scim_managed: type: boolean @@ -44878,7 +50870,7 @@ components: description: Updated display name for the group. created_at: type: integer - format: int64 + format: unixtime description: Unix timestamp (in seconds) when the group was created. is_scim_managed: type: boolean @@ -44910,18 +50902,22 @@ components: description: Display name of the group. created_at: type: integer - format: int64 + format: unixtime description: Unix timestamp (in seconds) when the group was created. is_scim_managed: type: boolean description: >- Whether the group is managed through SCIM and controlled by your identity provider. + group_type: + type: string + description: The type of the group. required: - id - name - created_at - is_scim_managed + - group_type x-oaiMeta: name: Group example: | @@ -44929,7 +50925,8 @@ components: "id": "group_01J1F8ABCDXYZ", "name": "Support Team", "created_at": 1711471533, - "is_scim_managed": false + "is_scim_managed": false, + "group_type": "group" } GroupRoleAssignment: type: object @@ -44974,6 +50971,25 @@ components: "predefined_role": false } } + GroupUser: + type: object + description: Represents an individual user returned when inspecting group membership. + properties: + id: + type: string + description: The identifier, which can be referenced in API endpoints + name: + type: string + description: The name of the user. + email: + anyOf: + - type: string + - type: 'null' + description: The email address of the user. + required: + - id + - name + - email GroupUserAssignment: type: object description: Confirmation payload returned after adding a user to a group. @@ -45039,6 +51055,7 @@ components: set to `b64_json` for `dall-e-2` and `dall-e-3`. url: type: string + format: uri description: >- When using `dall-e-2` or `dall-e-3`, the URL of the generated image if `response_format` is set to `url` (default value). Unsupported @@ -45068,6 +51085,7 @@ components: image. created_at: type: integer + format: unixtime description: | The Unix timestamp when the event was created. size: @@ -45157,6 +51175,7 @@ components: image. created_at: type: integer + format: unixtime description: | The Unix timestamp when the event was created. size: @@ -45245,6 +51264,7 @@ components: Base64-encoded image data, suitable for rendering as an image. created_at: type: integer + format: unixtime description: | The Unix timestamp when the event was created. size: @@ -45334,6 +51354,7 @@ components: image. created_at: type: integer + format: unixtime description: | The Unix timestamp when the event was created. size: @@ -45439,15 +51460,27 @@ components: or `auto`. Default: `auto`. default: auto size: - type: string - enum: - - 1024x1024 - - 1024x1536 - - 1536x1024 - - auto - description: | - The size of the generated image. One of `1024x1024`, `1024x1536`, - `1536x1024`, or `auto`. Default: `auto`. + anyOf: + - type: string + - type: string + enum: + - 1024x1024 + - 1024x1536 + - 1536x1024 + - auto + description: >- + The size of the generated images. For `gpt-image-2` and + `gpt-image-2-2026-04-21`, arbitrary resolutions are supported as + `WIDTHxHEIGHT` strings, for example `1536x864`. Width and height + must both be divisible by 16 and the requested aspect ratio must be + between 1:3 and 3:1. Resolutions above `2560x1440` are experimental, + and the maximum supported resolution is `3840x2160`. The requested + size must also satisfy the model's current pixel and edge limits. + The standard sizes `1024x1024`, `1536x1024`, and `1024x1536` are + supported by the GPT image models; `auto` is supported for models + that allow automatic sizing. For `dall-e-2`, use one of `256x256`, + `512x512`, or `1024x1024`. For `dall-e-3`, use one of `1024x1024`, + `1792x1024`, or `1024x1792`. default: auto output_format: type: string @@ -45565,6 +51598,7 @@ components: properties: image_url: type: string + format: uri maxLength: 20971520 description: A fully qualified URL or base64-encoded data URL. example: https://example.com/source-image.png @@ -45589,6 +51623,7 @@ components: properties: created: type: integer + format: unixtime description: The Unix timestamp (in seconds) of when the image was created. data: type: array @@ -45796,7 +51831,7 @@ components: title: Input item content list description: > A list of one or many input items to the model, containing different - content + content types. items: @@ -45865,14 +51900,21 @@ components: - expired - pending description: '`accepted`,`expired`, or `pending`' - invited_at: + created_at: type: integer + format: unixtime description: The Unix timestamp (in seconds) of when the invite was sent. expires_at: - type: integer + anyOf: + - type: integer + format: unixtime + - type: 'null' description: The Unix timestamp (in seconds) of when the invite expires. accepted_at: - type: integer + anyOf: + - type: integer + format: unixtime + - type: 'null' description: The Unix timestamp (in seconds) of when the invite was accepted. projects: type: array @@ -45891,14 +51933,17 @@ components: - member - owner description: Project membership role + required: + - id + - role required: - object - id - email - role - status - - invited_at - - expires_at + - created_at + - projects x-oaiMeta: name: The invite object example: | @@ -45908,7 +51953,7 @@ components: "email": "user@example.com", "role": "owner", "status": "accepted", - "invited_at": 1711471533, + "created_at": 1711471533, "expires_at": 1711471533, "accepted_at": 1711471533, "projects": [ @@ -45949,10 +51994,14 @@ components: items: $ref: '#/components/schemas/Invite' first_id: - type: string + anyOf: + - type: string + - type: 'null' description: The first `invite_id` in the retrieved `list` last_id: - type: string + anyOf: + - type: string + - type: 'null' description: The last `invite_id` in the retrieved `list` has_more: type: boolean @@ -45962,6 +52011,7 @@ components: required: - object - data + - has_more InviteProjectGroupBody: type: object description: Request payload for granting a group access to a project. @@ -46177,18 +52227,20 @@ components: items: $ref: '#/components/schemas/AuditLog' first_id: - type: string + anyOf: + - type: string + - type: 'null' example: audit_log-defb456h8dks last_id: - type: string + anyOf: + - type: string + - type: 'null' example: audit_log-hnbkd8s93s has_more: type: boolean required: - object - data - - first_id - - last_id - has_more ListBatchesResponse: type: object @@ -46220,12 +52272,16 @@ components: data: type: array items: - $ref: '#/components/schemas/Certificate' + $ref: '#/components/schemas/OrganizationCertificate' first_id: - type: string + anyOf: + - type: string + - type: 'null' example: cert_abc last_id: - type: string + anyOf: + - type: string + - type: 'null' example: cert_abc has_more: type: boolean @@ -46238,6 +52294,8 @@ components: - object - data - has_more + - first_id + - last_id ListFilesResponse: type: object properties: @@ -46390,6 +52448,36 @@ components: - object - data - has_more + ListProjectCertificatesResponse: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/OrganizationProjectCertificate' + first_id: + anyOf: + - type: string + - type: 'null' + example: cert_abc + last_id: + anyOf: + - type: string + - type: 'null' + example: cert_abc + has_more: + type: boolean + object: + type: string + enum: + - list + x-stainless-const: true + required: + - object + - data + - has_more + - first_id + - last_id ListRunStepsResponse: properties: object: @@ -46560,6 +52648,7 @@ components: required: - id - type + - call_id - output LogProbProperties: type: object @@ -46654,6 +52743,7 @@ components: - type: 'null' required: - type + - request_id - approve - approval_request_id MCPApprovalResponseResource: @@ -46690,6 +52780,7 @@ components: required: - type - id + - request_id - approve - approval_request_id MCPListTools: @@ -46780,6 +52871,7 @@ components: A label for this MCP server, used to identify it in tool calls. server_url: type: string + format: uri description: > The URL for the MCP server. One of `server_url` or `connector_id` must be @@ -47242,6 +53334,7 @@ components: The URL of the image, must be a supported image types: jpeg, jpg, png, gif, webp. type: string + format: uri detail: type: string description: >- @@ -47454,6 +53547,7 @@ components: created_at: description: The Unix timestamp (in seconds) for when the message was created. type: integer + format: unixtime thread_id: description: >- The [thread](/docs/api-reference/threads) ID that this message @@ -47493,6 +53587,7 @@ components: The Unix timestamp (in seconds) for when the message was completed. type: integer + format: unixtime - type: 'null' incomplete_at: anyOf: @@ -47500,6 +53595,7 @@ components: The Unix timestamp (in seconds) for when the message was marked as incomplete. type: integer + format: unixtime - type: 'null' role: description: The entity that produced the message. One of `user` or `assistant`. @@ -47745,6 +53841,7 @@ components: description: The model identifier, which can be referenced in the API endpoints. created: type: integer + format: unixtime description: The Unix timestamp (in seconds) when the model was created. object: type: string @@ -47896,11 +53993,16 @@ components: top_logprobs: anyOf: - description: > - An integer between 0 and 20 specifying the number of most likely - tokens to + An integer between 0 and 20 specifying the maximum number of + most likely + + tokens to return at each token position, each with an associated + log - return at each token position, each with an associated log - probability. + probability. In some cases, the number of returned tokens may be + fewer than + + requested. type: integer minimum: 0 maximum: 20 @@ -47982,7 +54084,7 @@ components: anyOf: - type: string enum: - - in-memory + - in_memory - 24h description: > The retention policy for the prompt cache. Set to `24h` to @@ -48118,8 +54220,6 @@ components: name: type: string description: The updated name for the certificate - required: - - name ModifyMessageRequest: type: object additionalProperties: false @@ -48198,9 +54298,11 @@ components: description: The size of the file, in bytes. created_at: type: integer + format: unixtime description: The Unix timestamp (in seconds) for when the file was created. expires_at: type: integer + format: unixtime description: The Unix timestamp (in seconds) for when the file will expire. filename: type: string @@ -48262,6 +54364,168 @@ components: "filename": "salesOverview.pdf", "purpose": "assistants", } + OrganizationCertificate: + type: object + description: >- + Represents an individual certificate configured at the organization + level. + properties: + object: + type: string + enum: + - organization.certificate + description: The object type, which is always `organization.certificate`. + x-stainless-const: true + id: + type: string + description: The identifier, which can be referenced in API endpoints + name: + anyOf: + - type: string + - type: 'null' + description: The name of the certificate. + created_at: + type: integer + format: unixtime + description: >- + The Unix timestamp (in seconds) of when the certificate was + uploaded. + certificate_details: + type: object + properties: + valid_at: + type: integer + format: unixtime + description: >- + The Unix timestamp (in seconds) of when the certificate becomes + valid. + expires_at: + type: integer + format: unixtime + description: The Unix timestamp (in seconds) of when the certificate expires. + active: + type: boolean + description: >- + Whether the certificate is currently active at the organization + level. + required: + - object + - id + - name + - created_at + - certificate_details + - active + OrganizationCertificateActivationResponse: + type: object + properties: + object: + type: string + enum: + - organization.certificate.activation + description: The organization certificate activation result type. + x-stainless-const: true + data: + type: array + items: + $ref: '#/components/schemas/OrganizationCertificate' + required: + - object + - data + OrganizationCertificateDeactivationResponse: + type: object + properties: + object: + type: string + enum: + - organization.certificate.deactivation + description: The organization certificate deactivation result type. + x-stainless-const: true + data: + type: array + items: + $ref: '#/components/schemas/OrganizationCertificate' + required: + - object + - data + OrganizationProjectCertificate: + type: object + description: Represents an individual certificate configured at the project level. + properties: + object: + type: string + enum: + - organization.project.certificate + description: The object type, which is always `organization.project.certificate`. + x-stainless-const: true + id: + type: string + description: The identifier, which can be referenced in API endpoints + name: + anyOf: + - type: string + - type: 'null' + description: The name of the certificate. + created_at: + type: integer + format: unixtime + description: >- + The Unix timestamp (in seconds) of when the certificate was + uploaded. + certificate_details: + type: object + properties: + valid_at: + type: integer + format: unixtime + description: >- + The Unix timestamp (in seconds) of when the certificate becomes + valid. + expires_at: + type: integer + format: unixtime + description: The Unix timestamp (in seconds) of when the certificate expires. + active: + type: boolean + description: Whether the certificate is currently active at the project level. + required: + - object + - id + - name + - created_at + - certificate_details + - active + OrganizationProjectCertificateActivationResponse: + type: object + properties: + object: + type: string + enum: + - organization.project.certificate.activation + description: The project certificate activation result type. + x-stainless-const: true + data: + type: array + items: + $ref: '#/components/schemas/OrganizationProjectCertificate' + required: + - object + - data + OrganizationProjectCertificateDeactivationResponse: + type: object + properties: + object: + type: string + enum: + - organization.project.certificate.deactivation + description: The project certificate deactivation result type. + x-stainless-const: true + data: + type: array + items: + $ref: '#/components/schemas/OrganizationProjectCertificate' + required: + - object + - data OtherChunkingStrategyResponseParam: type: object title: Other Chunking Strategy @@ -48484,30 +54748,36 @@ components: description: The object type, which is always `organization.project` x-stainless-const: true name: - type: string + anyOf: + - type: string + - type: 'null' description: The name of the project. This appears in reporting. created_at: type: integer + format: unixtime description: The Unix timestamp (in seconds) of when the project was created. archived_at: anyOf: - type: integer + format: unixtime description: >- The Unix timestamp (in seconds) of when the project was archived or `null`. - type: 'null' status: - type: string - enum: - - active - - archived + anyOf: + - type: string + - type: 'null' description: '`active` or `archived`' + external_key_id: + anyOf: + - type: string + - type: 'null' + description: The external key associated with the project. required: - id - object - - name - created_at - - status x-oaiMeta: name: The project object example: | @@ -48517,7 +54787,8 @@ components: "name": "Project example", "created_at": 1711471533, "archived_at": null, - "status": "active" + "status": "active", + "external_key_id": null } ProjectApiKey: type: object @@ -48537,9 +54808,13 @@ components: description: The name of the API key created_at: type: integer + format: unixtime description: The Unix timestamp (in seconds) of when the API key was created last_used_at: - type: integer + anyOf: + - type: integer + format: unixtime + - type: 'null' description: The Unix timestamp (in seconds) of when the API key was last used. id: type: string @@ -48554,9 +54829,9 @@ components: - service_account description: '`user` or `service_account`' user: - $ref: '#/components/schemas/ProjectUser' + $ref: '#/components/schemas/ProjectApiKeyOwnerUser' service_account: - $ref: '#/components/schemas/ProjectServiceAccount' + $ref: '#/components/schemas/ProjectApiKeyOwnerServiceAccount' required: - object - redacted_value @@ -48578,7 +54853,6 @@ components: "owner": { "type": "user", "user": { - "object": "organization.project.user", "id": "user_abc", "name": "First Last", "email": "user@example.com", @@ -48616,17 +54890,69 @@ components: items: $ref: '#/components/schemas/ProjectApiKey' first_id: - type: string + anyOf: + - type: string + - type: 'null' last_id: - type: string + anyOf: + - type: string + - type: 'null' has_more: type: boolean required: - object - data - - first_id - - last_id - has_more + ProjectApiKeyOwnerServiceAccount: + type: object + description: The service account that owns a project API key. + properties: + id: + type: string + description: The identifier, which can be referenced in API endpoints + name: + type: string + description: The name of the service account. + created_at: + type: integer + format: unixtime + description: >- + The Unix timestamp (in seconds) of when the service account was + created. + role: + type: string + description: The service account's project role. + required: + - id + - name + - created_at + - role + ProjectApiKeyOwnerUser: + type: object + description: The user that owns a project API key. + properties: + id: + type: string + description: The identifier, which can be referenced in API endpoints + email: + type: string + description: The email address of the user. + name: + type: string + description: The name of the user. + created_at: + type: integer + format: unixtime + description: The Unix timestamp (in seconds) of when the user was created. + role: + type: string + description: The user's project role. + required: + - id + - email + - name + - created_at + - role ProjectCreateRequest: type: object properties: @@ -48634,22 +54960,20 @@ components: type: string description: The friendly name of the project, this name appears in reports. geography: - type: string - enum: - - US - - EU - - JP - - IN - - KR - - CA - - AU - - SG + anyOf: + - type: string + - type: 'null' description: >- Create the project with the specified data residency region. Your organization must have access to Data residency functionality in order to use. See [data residency controls](/docs/guides/your-data#data-residency-controls) to review the functionality and limitations of setting this field. + external_key_id: + anyOf: + - type: string + - type: 'null' + description: External key ID to associate with the project. required: - name ProjectGroup: @@ -48671,9 +54995,12 @@ components: group_name: type: string description: Display name of the group. + group_type: + type: string + description: The type of the group. created_at: type: integer - format: int64 + format: unixtime description: >- Unix timestamp (in seconds) when the group was granted project access. @@ -48682,6 +55009,7 @@ components: - project_id - group_id - group_name + - group_type - created_at x-oaiMeta: name: The project group object @@ -48691,6 +55019,7 @@ components: "project_id": "proj_abc123", "group_id": "group_01J1F8ABCDXYZ", "group_name": "Support Team", + "group_type": "group", "created_at": 1711471533 } ProjectGroupDeletedResource: @@ -48776,16 +55105,18 @@ components: items: $ref: '#/components/schemas/Project' first_id: - type: string + anyOf: + - type: string + - type: 'null' last_id: - type: string + anyOf: + - type: string + - type: 'null' has_more: type: boolean required: - object - data - - first_id - - last_id - has_more ProjectRateLimit: type: object @@ -48855,16 +55186,18 @@ components: items: $ref: '#/components/schemas/ProjectRateLimit' first_id: - type: string + anyOf: + - type: string + - type: 'null' last_id: - type: string + anyOf: + - type: string + - type: 'null' has_more: type: boolean required: - object - data - - first_id - - last_id - has_more ProjectRateLimitUpdateRequest: type: object @@ -48917,6 +55250,7 @@ components: description: '`owner` or `member`' created_at: type: integer + format: unixtime description: >- The Unix timestamp (in seconds) of when the service account was created @@ -48953,6 +55287,7 @@ components: type: string created_at: type: integer + format: unixtime id: type: string required: @@ -48989,8 +55324,11 @@ components: x-stainless-const: true created_at: type: integer + format: unixtime api_key: - $ref: '#/components/schemas/ProjectServiceAccountApiKey' + anyOf: + - $ref: '#/components/schemas/ProjectServiceAccountApiKey' + - type: 'null' required: - object - id @@ -49027,25 +55365,37 @@ components: items: $ref: '#/components/schemas/ProjectServiceAccount' first_id: - type: string + anyOf: + - type: string + - type: 'null' last_id: - type: string + anyOf: + - type: string + - type: 'null' has_more: type: boolean required: - object - data - - first_id - - last_id - has_more ProjectUpdateRequest: type: object properties: name: - type: string + anyOf: + - type: string + - type: 'null' description: The updated name of the project, this name appears in reports. - required: - - name + external_key_id: + anyOf: + - type: string + - type: 'null' + description: External key ID to associate with the project. + geography: + anyOf: + - type: string + - type: 'null' + description: Geography for the project. ProjectUser: type: object description: Represents an individual user in a project. @@ -49060,25 +55410,25 @@ components: type: string description: The identifier, which can be referenced in API endpoints name: - type: string + anyOf: + - type: string + - type: 'null' description: The name of the user email: - type: string + anyOf: + - type: string + - type: 'null' description: The email address of the user role: type: string - enum: - - owner - - member description: '`owner` or `member`' added_at: type: integer + format: unixtime description: The Unix timestamp (in seconds) of when the project was added. required: - object - id - - name - - email - role - added_at x-oaiMeta: @@ -49096,16 +55446,19 @@ components: type: object properties: user_id: - type: string + anyOf: + - type: string + - type: 'null' description: The ID of the user. + email: + anyOf: + - type: string + - type: 'null' + description: Email of the user to add. role: type: string - enum: - - owner - - member description: '`owner` or `member`' required: - - user_id - role ProjectUserDeleteResponse: type: object @@ -49133,28 +55486,27 @@ components: items: $ref: '#/components/schemas/ProjectUser' first_id: - type: string + anyOf: + - type: string + - type: 'null' last_id: - type: string + anyOf: + - type: string + - type: 'null' has_more: type: boolean required: - object - data - - first_id - - last_id - has_more ProjectUserUpdateRequest: type: object properties: role: - type: string - enum: - - owner - - member + anyOf: + - type: string + - type: 'null' description: '`owner` or `member`' - required: - - role Prompt: anyOf: - type: object @@ -49340,19 +55692,19 @@ components: type: object description: > Add a new Item to the Conversation's context, including messages, - function + function calls, and function call responses. This event can be used both to - populate a + populate a "history" of the conversation and to add new items mid-stream, but has - the + the current limitation that it cannot populate assistant audio messages. If successful, the server will respond with a - `conversation.item.created` + `conversation.item.created` event, otherwise an `error` event will be sent. properties: @@ -49370,7 +55722,7 @@ components: type: string description: > The ID of the preceding item after which the new item will be - inserted. + inserted. If not set, the new item will be appended to the end of the conversation. @@ -49409,13 +55761,13 @@ components: RealtimeBetaClientEventConversationItemDelete: type: object description: > - Send this event when you want to remove any item from the conversation + Send this event when you want to remove any item from the conversation history. The server will respond with a `conversation.item.deleted` - event, + event, unless the item does not exist in the conversation history, in which - case the + case the server will respond with an error. properties: @@ -49450,10 +55802,10 @@ components: a specific item in the conversation history. This is useful, for example, to inspect user audio after noise cancellation and VAD. - The server will respond with a `conversation.item.retrieved` event, + The server will respond with a `conversation.item.retrieved` event, unless the item does not exist in the conversation history, in which - case the + case the server will respond with an error. properties: @@ -49485,30 +55837,30 @@ components: type: object description: > Send this event to truncate a previous assistant message’s audio. The - server + server will produce audio faster than realtime, so this event is useful when - the user + the user interrupts to truncate audio that has already been sent to the client - but not + but not yet played. This will synchronize the server's understanding of the - audio with + audio with the client's playback. Truncating audio will delete the server-side text transcript to ensure - there + there is not text in the context that hasn't been heard by the user. If successful, the server will respond with a - `conversation.item.truncated` + `conversation.item.truncated` - event. + event. properties: event_id: type: string @@ -49523,7 +55875,7 @@ components: type: string description: > The ID of the assistant message item to truncate. Only assistant - message + message items can be truncated. content_index: @@ -49533,10 +55885,10 @@ components: type: integer description: > Inclusive duration up to which audio is truncated, in milliseconds. - If + If the audio_end_ms is greater than the actual audio duration, the - server + server will respond with an error. required: @@ -49559,13 +55911,13 @@ components: type: object description: > Send this event to append audio bytes to the input audio buffer. The - audio + audio buffer is temporary storage you can write to and later commit. In Server - VAD + VAD mode, the audio buffer is used to detect speech and the server will - decide + decide when to commit. When Server VAD is disabled, you must commit the audio buffer @@ -49574,13 +55926,13 @@ components: The client may choose how much audio to place in each event up to a - maximum + maximum of 15 MiB, for example streaming smaller chunks from the client may - allow the + allow the VAD to be more responsive. Unlike made other client events, the server - will + will not send a confirmation response to this event. properties: @@ -49597,7 +55949,7 @@ components: type: string description: > Base64-encoded audio bytes. This must be in the format specified by - the + the `input_audio_format` field in the session configuration. required: @@ -49615,7 +55967,7 @@ components: RealtimeBetaClientEventInputAudioBufferClear: type: object description: | - Send this event to clear the audio bytes in the buffer. The server will + Send this event to clear the audio bytes in the buffer. The server will respond with an `input_audio_buffer.cleared` event. properties: event_id: @@ -49641,27 +55993,27 @@ components: type: object description: > Send this event to commit the user input audio buffer, which will create - a + a new user message item in the conversation. This event will produce an - error + error if the input audio buffer is empty. When in Server VAD mode, the client - does + does - not need to send this event, the server will commit the audio buffer + not need to send this event, the server will commit the audio buffer automatically. Committing the input audio buffer will trigger input audio - transcription + transcription (if enabled in session configuration), but it will not create a - response + response from the model. The server will respond with an - `input_audio_buffer.committed` + `input_audio_buffer.committed` event. properties: @@ -49723,10 +56075,10 @@ components: type: object description: > Send this event to cancel an in-progress response. The server will - respond + respond with a `response.done` event with a status of - `response.status=cancelled`. If + `response.status=cancelled`. If there is no response to cancel, the server will respond with an error. properties: @@ -49742,7 +56094,7 @@ components: response_id: type: string description: | - A specific response ID to cancel - if not provided, will cancel an + A specific response ID to cancel - if not provided, will cancel an in-progress response in the default conversation. required: - type @@ -49758,36 +56110,36 @@ components: type: object description: > This event instructs the server to create a Response, which means - triggering + triggering model inference. When in Server VAD mode, the server will create - Responses + Responses automatically. A Response will include at least one Item, and may have two, in which - case + case - the second will be a function call. These Items will be appended to the + the second will be a function call. These Items will be appended to the conversation history. The server will respond with a `response.created` event, events for - Items + Items and content created, and finally a `response.done` event to indicate - the + the Response is complete. The `response.create` event can optionally include inference - configuration like + configuration like `instructions`, and `temperature`. These fields will override the - Session's + Session's configuration for this Response only. @@ -50010,7 +56362,7 @@ components: - in_progress description: > The final status of the response (`completed`, `cancelled`, - `failed`, or + `failed`, or `incomplete`, `in_progress`). status_details: @@ -50026,10 +56378,10 @@ components: - incomplete description: > The type of error that caused the response to fail, - corresponding + corresponding with the `status` field (`completed`, `cancelled`, - `incomplete`, + `incomplete`, `failed`). reason: @@ -50041,22 +56393,22 @@ components: - content_filter description: > The reason the Response did not complete. For a `cancelled` - Response, + Response, one of `turn_detected` (the server VAD detected a new start of - speech) + speech) - or `client_cancelled` (the client sent a cancel event). For an + or `client_cancelled` (the client sent a cancel event). For an `incomplete` Response, one of `max_output_tokens` or - `content_filter` + `content_filter` (the server-side safety filter activated and cut off the response). error: type: object description: | - A description of the error that caused the response to fail, + A description of the error that caused the response to fail, populated when the `status` is `failed`. properties: type: @@ -50076,13 +56428,13 @@ components: type: object description: > Usage statistics for the Response, this will correspond to billing. - A + A Realtime API session will maintain a conversation context and append - new + new Items to the Conversation, thus output from previous turns (text - and + and audio tokens) will become the input for later turns. properties: @@ -50090,21 +56442,21 @@ components: type: integer description: > The total number of tokens in the Response including input and - output + output text and audio tokens. input_tokens: type: integer description: > The number of input tokens used in the Response, including text - and + and audio tokens. output_tokens: type: integer description: > The number of output tokens sent in the Response, including text - and + and audio tokens. input_token_details: @@ -50242,33 +56594,33 @@ components: type: string description: > The default system instructions (i.e. system message) prepended to - model + model - calls. This field allows the client to guide the model on desired + calls. This field allows the client to guide the model on desired responses. The model can be instructed on response content and - format, + format, (e.g. "be extremely succinct", "act friendly", "here are examples of - good + good responses") and on audio behavior (e.g. "talk quickly", "inject - emotion + emotion into your voice", "laugh frequently"). The instructions are not - guaranteed + guaranteed to be followed by the model, but they provide guidance to the model - on the + on the desired behavior. Note that the server sets default instructions which will be used if - this + this field is not set and are visible in the `session.created` event at - the + the start of the session. voice: @@ -50314,10 +56666,10 @@ components: type: string description: > The description of the function, including guidance on when - and how + and how to call it, and guidance about what to tell the user when - calling + calling (if anything). parameters: @@ -50362,7 +56714,7 @@ components: means that the contents of the response will be added to the default conversation. Set this to `none` to create an out-of-band response - which + which will not add items to default conversation. oneOf: @@ -50452,9 +56804,9 @@ components: type: object description: > Returned when an item in the conversation is deleted by the client with - a + a - `conversation.item.delete` event. This event is used to synchronize the + `conversation.item.delete` event. This event is used to synchronize the server's understanding of the conversation history with the client's view. @@ -50626,9 +56978,9 @@ components: type: object description: > Returned when input audio transcription is configured, and a - transcription + transcription - request for a user message failed. These events are separate from other + request for a user message failed. These events are separate from other `error` events so that the client can identify the related Item. properties: @@ -50721,11 +57073,11 @@ components: description: The detected speaker label for this segment. start: type: number - format: float + format: double description: Start time of the segment in seconds. end: type: number - format: float + format: double description: End time of the segment in seconds. required: - event_id @@ -50800,16 +57152,16 @@ components: type: object description: > Returned when an earlier assistant audio message item is truncated by - the + the - client with a `conversation.item.truncate` event. This event is used to + client with a `conversation.item.truncate` event. This event is used to synchronize the server's understanding of the audio with the client's playback. This action will truncate the audio and remove the server-side text - transcript + transcript to ensure there is no text in the context that hasn't been heard by the user. @@ -50923,7 +57275,7 @@ components: RealtimeBetaServerEventInputAudioBufferCleared: type: object description: | - Returned when the input audio buffer is cleared by the client with a + Returned when the input audio buffer is cleared by the client with a `input_audio_buffer.clear` event. properties: event_id: @@ -50999,28 +57351,28 @@ components: type: object description: > Sent by the server when in `server_vad` mode to indicate that speech has - been + been detected in the audio buffer. This can happen any time audio is added to - the + the buffer (unless speech is already detected). The client may want to use - this + this event to interrupt audio playback or provide visual feedback to the - user. + user. The client should expect to receive a - `input_audio_buffer.speech_stopped` event + `input_audio_buffer.speech_stopped` event when speech stops. The `item_id` property is the ID of the user message - item + item - that will be created when speech stops and will also be included in the + that will be created when speech stops and will also be included in the `input_audio_buffer.speech_stopped` event (unless the client manually - commits + commits the audio buffer during VAD activation). properties: @@ -51037,11 +57389,11 @@ components: type: integer description: > Milliseconds from the start of all audio written to the buffer - during the + during the - session when speech was first detected. This will correspond to the + session when speech was first detected. This will correspond to the - beginning of audio sent to the model, and thus includes the + beginning of audio sent to the model, and thus includes the `prefix_padding_ms` configured in the Session. item_id: @@ -51068,10 +57420,10 @@ components: type: object description: > Returned in `server_vad` mode when the server detects the end of speech - in + in the audio buffer. The server will also send an - `conversation.item.created` + `conversation.item.created` event with the user message item that is created from the audio buffer. properties: @@ -51088,10 +57440,10 @@ components: type: integer description: > Milliseconds since the session started when speech stopped. This - will + will correspond to the end of audio sent to the model, and thus includes - the + the `min_silence_duration_ms` configured in the Session. item_id: @@ -51203,13 +57555,13 @@ components: type: object description: > Emitted at the beginning of a Response to indicate the updated rate - limits. + limits. When a Response is created some tokens will be "reserved" for the - output + output tokens, the rate limits shown here reflect that reservation, which is - then + then adjusted accordingly once the Response is completed. properties: @@ -51673,10 +58025,10 @@ components: type: object description: > Returned when a Response is done streaming. Always emitted, no matter - the + the final state. The Response object included in the `response.done` event - will + will include all output Items in the Response but will omit the raw audio data. @@ -52101,7 +58453,7 @@ components: type: object description: > Returned when an Item is done streaming. Also emitted when a Response - is + is interrupted, incomplete, or cancelled. properties: @@ -52418,7 +58770,7 @@ components: type: object description: > Returned when a transcription session is updated with a - `transcription_session.update` event, unless + `transcription_session.update` event, unless there is an error. properties: @@ -52559,19 +58911,19 @@ components: type: object description: > Add a new Item to the Conversation's context, including messages, - function + function calls, and function call responses. This event can be used both to - populate a + populate a "history" of the conversation and to add new items mid-stream, but has - the + the current limitation that it cannot populate assistant audio messages. If successful, the server will respond with a - `conversation.item.created` + `conversation.item.created` event, otherwise an `error` event will be sent. properties: @@ -52625,13 +58977,13 @@ components: RealtimeClientEventConversationItemDelete: type: object description: > - Send this event when you want to remove any item from the conversation + Send this event when you want to remove any item from the conversation history. The server will respond with a `conversation.item.deleted` - event, + event, unless the item does not exist in the conversation history, in which - case the + case the server will respond with an error. properties: @@ -52667,10 +59019,10 @@ components: a specific item in the conversation history. This is useful, for example, to inspect user audio after noise cancellation and VAD. - The server will respond with a `conversation.item.retrieved` event, + The server will respond with a `conversation.item.retrieved` event, unless the item does not exist in the conversation history, in which - case the + case the server will respond with an error. properties: @@ -52703,30 +59055,30 @@ components: type: object description: > Send this event to truncate a previous assistant message’s audio. The - server + server will produce audio faster than realtime, so this event is useful when - the user + the user interrupts to truncate audio that has already been sent to the client - but not + but not yet played. This will synchronize the server's understanding of the - audio with + audio with the client's playback. Truncating audio will delete the server-side text transcript to ensure - there + there is not text in the context that hasn't been heard by the user. If successful, the server will respond with a - `conversation.item.truncated` + `conversation.item.truncated` - event. + event. properties: event_id: type: string @@ -52742,7 +59094,7 @@ components: type: string description: > The ID of the assistant message item to truncate. Only assistant - message + message items can be truncated. content_index: @@ -52752,10 +59104,10 @@ components: type: integer description: > Inclusive duration up to which audio is truncated, in milliseconds. - If + If the audio_end_ms is greater than the actual audio duration, the - server + server will respond with an error. required: @@ -52778,7 +59130,7 @@ components: type: object description: > Send this event to append audio bytes to the input audio buffer. The - audio + audio buffer is temporary storage you can write to and later commit. A "commit" will create a new @@ -52791,7 +59143,7 @@ components: If VAD is enabled the audio buffer is used to detect speech and the - server will decide + server will decide when to commit. When Server VAD is disabled, you must commit the audio buffer @@ -52801,13 +59153,13 @@ components: The client may choose how much audio to place in each event up to a - maximum + maximum of 15 MiB, for example streaming smaller chunks from the client may - allow the + allow the VAD to be more responsive. Unlike most other client events, the server - will + will not send a confirmation response to this event. properties: @@ -52825,7 +59177,7 @@ components: type: string description: > Base64-encoded audio bytes. This must be in the format specified by - the + the `input_audio_format` field in the session configuration. required: @@ -52843,7 +59195,7 @@ components: RealtimeClientEventInputAudioBufferClear: type: object description: | - Send this event to clear the audio bytes in the buffer. The server will + Send this event to clear the audio bytes in the buffer. The server will respond with an `input_audio_buffer.cleared` event. properties: event_id: @@ -52940,10 +59292,10 @@ components: type: object description: > Send this event to cancel an in-progress response. The server will - respond + respond with a `response.done` event with a status of - `response.status=cancelled`. If + `response.status=cancelled`. If there is no response to cancel, the server will respond with an error. It's safe @@ -52966,7 +59318,7 @@ components: response_id: type: string description: | - A specific response ID to cancel - if not provided, will cancel an + A specific response ID to cancel - if not provided, will cancel an in-progress response in the default conversation. required: - type @@ -52982,35 +59334,35 @@ components: type: object description: > This event instructs the server to create a Response, which means - triggering + triggering model inference. When in Server VAD mode, the server will create - Responses + Responses automatically. A Response will include at least one Item, and may have two, in which - case + case - the second will be a function call. These Items will be appended to the + the second will be a function call. These Items will be appended to the conversation history by default. The server will respond with a `response.created` event, events for - Items + Items and content created, and finally a `response.done` event to indicate - the + the Response is complete. - The `response.create` event includes inference configuration like + The `response.create` event includes inference configuration like `instructions` and `tools`. If these are set, they will override the - Session's + Session's configuration for this Response only. @@ -53531,6 +59883,7 @@ components: specified. image_url: type: string + format: uri description: >- Base64-encoded image bytes (for `input_image`) as a data URI. For example @@ -53602,9 +59955,9 @@ components: - in_progress description: > The status of the item (`completed`, `incomplete`, `in_progress`). - These have no effect + These have no effect - on the conversation, but are accepted for consistency with the + on the conversation, but are accepted for consistency with the `conversation.item.created` event. role: @@ -53615,18 +59968,18 @@ components: - system description: > The role of the message sender (`user`, `assistant`, `system`), - only + only applicable for `message` items. content: type: array description: > - The content of the message, applicable for `message` items. + The content of the message, applicable for `message` items. - Message items of role `system` support only `input_text` content - Message items of role `user` support `input_text` and - `input_audio` + `input_audio` content - Message items of role `assistant` support `text` content. items: @@ -53670,13 +60023,13 @@ components: call_id: type: string description: > - The ID of the function call (for `function_call` and + The ID of the function call (for `function_call` and `function_call_output` items). If passed on a - `function_call_output` + `function_call_output` item, the server will check that a `function_call` item with the - same + same ID exists in the conversation history. name: @@ -53730,6 +60083,7 @@ components: x-stainless-const: true seconds: type: integer + format: int64 description: > The number of seconds from the anchor point to the expiration. Select a value between `10` and `7200` (2 hours). This default @@ -53758,6 +60112,7 @@ components: description: The generated client secret value. expires_at: type: integer + format: unixtime description: Expiration timestamp for the client secret, in seconds since epoch. session: title: Session configuration @@ -54033,6 +60388,29 @@ components: required: - type - message + RealtimeReasoning: + type: object + title: Realtime reasoning configuration + description: > + Configuration for reasoning-capable Realtime models such as + `gpt-realtime-2`. + properties: + effort: + $ref: '#/components/schemas/RealtimeReasoningEffort' + RealtimeReasoningEffort: + type: string + description: > + Constrains effort on reasoning for reasoning-capable Realtime models + such as + + `gpt-realtime-2`. + enum: + - minimal + - low + - medium + - high + - xhigh + default: low RealtimeResponse: type: object description: The response resource. @@ -54056,7 +60434,7 @@ components: - in_progress description: > The final status of the response (`completed`, `cancelled`, - `failed`, or + `failed`, or `incomplete`, `in_progress`). status_details: @@ -54072,10 +60450,10 @@ components: - incomplete description: > The type of error that caused the response to fail, - corresponding + corresponding with the `status` field (`completed`, `cancelled`, - `incomplete`, + `incomplete`, `failed`). reason: @@ -54095,7 +60473,7 @@ components: error: type: object description: | - A description of the error that caused the response to fail, + A description of the error that caused the response to fail, populated when the `status` is `failed`. properties: type: @@ -54142,13 +60520,13 @@ components: type: object description: > Usage statistics for the Response, this will correspond to billing. - A + A Realtime API session will maintain a conversation context and append - new + new Items to the Conversation, thus output from previous turns (text - and + and audio tokens) will become the input for later turns. properties: @@ -54156,21 +60534,21 @@ components: type: integer description: > The total number of tokens in the Response including input and - output + output text and audio tokens. input_tokens: type: integer description: > The number of input tokens used in the Response, including text - and + and audio tokens. output_tokens: type: integer description: > The number of output tokens sent in the Response, including text - and + and audio tokens. input_token_details: @@ -54352,6 +60730,15 @@ components: - $ref: '#/components/schemas/ToolChoiceFunction' - $ref: '#/components/schemas/ToolChoiceMCP' default: auto + parallel_tool_calls: + type: boolean + description: > + Whether the model may call multiple tools in parallel. Only + supported by + + reasoning Realtime models such as `gpt-realtime-2`. + reasoning: + $ref: '#/components/schemas/RealtimeReasoning' max_output_tokens: oneOf: - type: integer @@ -54637,9 +61024,9 @@ components: type: object description: > Returned when an item in the conversation is deleted by the client with - a + a - `conversation.item.delete` event. This event is used to synchronize the + `conversation.item.delete` event. This event is used to synchronize the server's understanding of the conversation history with the client's view. @@ -54876,9 +61263,9 @@ components: type: object description: > Returned when input audio transcription is configured, and a - transcription + transcription - request for a user message failed. These events are separate from other + request for a user message failed. These events are separate from other `error` events so that the client can identify the related Item. properties: @@ -54971,11 +61358,11 @@ components: description: The detected speaker label for this segment. start: type: number - format: float + format: double description: Start time of the segment in seconds. end: type: number - format: float + format: double description: End time of the segment in seconds. required: - event_id @@ -55053,16 +61440,16 @@ components: type: object description: > Returned when an earlier assistant audio message item is truncated by - the + the - client with a `conversation.item.truncate` event. This event is used to + client with a `conversation.item.truncate` event. This event is used to synchronize the server's understanding of the audio with the client's playback. This action will truncate the audio and remove the server-side text - transcript + transcript to ensure there is no text in the context that hasn't been heard by the user. @@ -55176,7 +61563,7 @@ components: RealtimeServerEventInputAudioBufferCleared: type: object description: | - Returned when the input audio buffer is cleared by the client with a + Returned when the input audio buffer is cleared by the client with a `input_audio_buffer.clear` event. properties: event_id: @@ -55292,28 +61679,28 @@ components: type: object description: > Sent by the server when in `server_vad` mode to indicate that speech has - been + been detected in the audio buffer. This can happen any time audio is added to - the + the buffer (unless speech is already detected). The client may want to use - this + this event to interrupt audio playback or provide visual feedback to the - user. + user. The client should expect to receive a - `input_audio_buffer.speech_stopped` event + `input_audio_buffer.speech_stopped` event when speech stops. The `item_id` property is the ID of the user message - item + item - that will be created when speech stops and will also be included in the + that will be created when speech stops and will also be included in the `input_audio_buffer.speech_stopped` event (unless the client manually - commits + commits the audio buffer during VAD activation). properties: @@ -55330,11 +61717,11 @@ components: type: integer description: > Milliseconds from the start of all audio written to the buffer - during the + during the - session when speech was first detected. This will correspond to the + session when speech was first detected. This will correspond to the - beginning of audio sent to the model, and thus includes the + beginning of audio sent to the model, and thus includes the `prefix_padding_ms` configured in the Session. item_id: @@ -55361,10 +61748,10 @@ components: type: object description: > Returned in `server_vad` mode when the server detects the end of speech - in + in the audio buffer. The server will also send an - `conversation.item.created` + `conversation.item.created` event with the user message item that is created from the audio buffer. properties: @@ -55381,10 +61768,10 @@ components: type: integer description: > Milliseconds since the session started when speech stopped. This - will + will correspond to the end of audio sent to the model, and thus includes - the + the `min_silence_duration_ms` configured in the Session. item_id: @@ -55691,13 +62078,13 @@ components: type: object description: > Emitted at the beginning of a Response to indicate the updated rate - limits. + limits. When a Response is created some tokens will be "reserved" for the - output + output tokens, the rate limits shown here reflect that reservation, which is - then + then adjusted accordingly once the Response is completed. properties: @@ -56160,10 +62547,10 @@ components: type: object description: > Returned when a Response is done streaming. Always emitted, no matter - the + the final state. The Response object included in the `response.done` event - will + will include all output Items in the Response but will omit the raw audio data. @@ -56617,7 +63004,7 @@ components: type: object description: > Returned when an Item is done streaming. Also emitted when a Response - is + is interrupted, incomplete, or cancelled. properties: @@ -56793,8 +63180,9 @@ components: session: description: The session configuration. oneOf: - - $ref: '#/components/schemas/RealtimeSessionCreateRequestGA' - - $ref: '#/components/schemas/RealtimeTranscriptionSessionCreateRequestGA' + - $ref: '#/components/schemas/RealtimeSessionCreateResponseGA' + - $ref: >- + #/components/schemas/RealtimeTranscriptionSessionCreateResponseGA required: - event_id - type @@ -56869,8 +63257,9 @@ components: session: description: The session configuration. oneOf: - - $ref: '#/components/schemas/RealtimeSessionCreateRequestGA' - - $ref: '#/components/schemas/RealtimeTranscriptionSessionCreateRequestGA' + - $ref: '#/components/schemas/RealtimeSessionCreateResponseGA' + - $ref: >- + #/components/schemas/RealtimeTranscriptionSessionCreateResponseGA required: - event_id - type @@ -56959,7 +63348,7 @@ components: type: object description: > Returned when a transcription session is updated with a - `transcription_session.update` event, unless + `transcription_session.update` event, unless there is an error. properties: @@ -57133,7 +63522,7 @@ components: input_audio_transcription: anyOf: - allOf: - - $ref: '#/components/schemas/AudioTranscription' + - $ref: '#/components/schemas/AudioTranscriptionResponse' description: > Configuration for input audio transcription, defaults to off and can be set to `null` to turn off once on. Input audio @@ -57259,6 +63648,7 @@ components: given model. Defaults to `inf`. expires_at: type: integer + format: unixtime description: Expiration timestamp for the session, in seconds since epoch. prompt: anyOf: @@ -57299,6 +63689,7 @@ components: a standard API token, which should only be used server-side. expires_at: type: integer + format: unixtime description: > Timestamp for when the token expires. Currently, all tokens expire @@ -57600,6 +63991,7 @@ components: enum: - gpt-realtime - gpt-realtime-1.5 + - gpt-realtime-2 - gpt-realtime-2025-08-28 - gpt-4o-realtime-preview - gpt-4o-realtime-preview-2024-10-01 @@ -57798,6 +64190,15 @@ components: - $ref: '#/components/schemas/ToolChoiceFunction' - $ref: '#/components/schemas/ToolChoiceMCP' default: auto + parallel_tool_calls: + type: boolean + description: > + Whether the model may call multiple tools in parallel. Only + supported by + + reasoning Realtime models such as `gpt-realtime-2`. + reasoning: + $ref: '#/components/schemas/RealtimeReasoning' max_output_tokens: oneOf: - type: integer @@ -57832,6 +64233,7 @@ components: description: The object type. Always `realtime.session`. expires_at: type: integer + format: unixtime description: Expiration timestamp for the session, in seconds since epoch. include: type: array @@ -57902,7 +64304,7 @@ components: transcription: description: | Configuration for input audio transcription. - $ref: '#/components/schemas/AudioTranscription' + $ref: '#/components/schemas/AudioTranscriptionResponse' noise_reduction: type: object description: | @@ -58083,31 +64485,10 @@ components: } RealtimeSessionCreateResponseGA: type: object + title: Realtime session configuration object description: | - A new Realtime session configuration, with an ephemeral key. Default TTL - for keys is one minute. + A Realtime session configuration object. properties: - client_secret: - type: object - description: Ephemeral key returned by the API. - properties: - value: - type: string - description: > - Ephemeral key usable in client environments to authenticate - connections to the Realtime API. Use this in client-side - environments rather than a standard API token, which should only - be used server-side. - expires_at: - type: integer - description: > - Timestamp for when the token expires. Currently, all tokens - expire - - after one minute. - required: - - value - - expires_at type: type: string description: > @@ -58116,6 +64497,21 @@ components: enum: - realtime x-stainless-const: true + id: + type: string + description: > + Unique identifier for the session that looks like + `sess_1234567890abcdef`. + object: + type: string + description: The object type. Always `realtime.session`. + enum: + - realtime.session + x-stainless-const: true + expires_at: + type: integer + format: unixtime + description: Expiration timestamp for the session, in seconds since epoch. output_modalities: type: array description: > @@ -58141,6 +64537,7 @@ components: enum: - gpt-realtime - gpt-realtime-1.5 + - gpt-realtime-2 - gpt-realtime-2025-08-28 - gpt-4o-realtime-preview - gpt-4o-realtime-preview-2024-10-01 @@ -58197,7 +64594,7 @@ components: optionally set the language and prompt for transcription, these offer additional guidance to the transcription service. - $ref: '#/components/schemas/AudioTranscription' + $ref: '#/components/schemas/AudioTranscriptionResponse' noise_reduction: type: object default: null @@ -58339,6 +64736,8 @@ components: - $ref: '#/components/schemas/ToolChoiceFunction' - $ref: '#/components/schemas/ToolChoiceMCP' default: auto + reasoning: + $ref: '#/components/schemas/RealtimeReasoning' max_output_tokens: oneOf: - type: integer @@ -58356,8 +64755,9 @@ components: prompt: $ref: '#/components/schemas/Prompt' required: - - client_secret - type + - id + - object x-oaiMeta: name: The session object group: realtime @@ -58548,6 +64948,7 @@ components: a standard API token, which should only be used server-side. expires_at: type: integer + format: unixtime description: > Timestamp for when the token expires. Currently, all tokens expire @@ -58573,205 +64974,1000 @@ components: input_audio_transcription: description: | Configuration of the transcription model. - $ref: '#/components/schemas/AudioTranscription' + $ref: '#/components/schemas/AudioTranscriptionResponse' turn_detection: type: object description: > Configuration for turn detection. Can be set to `null` to turn off. Server - VAD means that the model will detect the start and end of speech - based on + VAD means that the model will detect the start and end of speech + based on + + audio volume and respond at the end of user speech. + properties: + type: + type: string + description: > + Type of turn detection, only `server_vad` is currently + supported. + threshold: + type: number + description: > + Activation threshold for VAD (0.0 to 1.0), this defaults to 0.5. + A + + higher threshold will require louder audio to activate the + model, and + + thus might perform better in noisy environments. + prefix_padding_ms: + type: integer + description: | + Amount of audio to include before the VAD detected speech (in + milliseconds). Defaults to 300ms. + silence_duration_ms: + type: integer + description: > + Duration of silence to detect speech stop (in milliseconds). + Defaults + + to 500ms. With shorter values the model will respond more + quickly, + + but may jump in on short pauses from the user. + required: + - client_secret + x-oaiMeta: + name: The transcription session object + group: realtime + example: | + { + "id": "sess_BBwZc7cFV3XizEyKGDCGL", + "object": "realtime.transcription_session", + "expires_at": 1742188264, + "modalities": ["audio", "text"], + "turn_detection": { + "type": "server_vad", + "threshold": 0.5, + "prefix_padding_ms": 300, + "silence_duration_ms": 200 + }, + "input_audio_format": "pcm16", + "input_audio_transcription": { + "model": "gpt-4o-transcribe", + "language": null, + "prompt": "" + }, + "client_secret": null + } + RealtimeTranscriptionSessionCreateResponseGA: + type: object + title: Realtime transcription session configuration object + description: | + A Realtime transcription session configuration object. + properties: + type: + type: string + description: > + The type of session. Always `transcription` for transcription + sessions. + enum: + - transcription + x-stainless-const: true + id: + type: string + description: > + Unique identifier for the session that looks like + `sess_1234567890abcdef`. + object: + type: string + description: The object type. Always `realtime.transcription_session`. + expires_at: + type: integer + format: unixtime + description: Expiration timestamp for the session, in seconds since epoch. + include: + type: array + items: + type: string + enum: + - item.input_audio_transcription.logprobs + description: > + Additional fields to include in server outputs. + + - `item.input_audio_transcription.logprobs`: Include logprobs for + input audio transcription. + audio: + type: object + description: | + Configuration for input audio for the session. + properties: + input: + type: object + properties: + format: + $ref: '#/components/schemas/RealtimeAudioFormats' + transcription: + description: | + Configuration of the transcription model. + $ref: '#/components/schemas/AudioTranscriptionResponse' + noise_reduction: + type: object + description: | + Configuration for input audio noise reduction. + properties: + type: + $ref: '#/components/schemas/NoiseReductionType' + turn_detection: + description: > + Configuration for turn detection. For + `gpt-realtime-whisper`, this must be `null`; VAD is not + supported. + anyOf: + - type: object + description: > + Configuration for turn detection. Can be set to `null` + to turn off. Server + + VAD means that the model will detect the start and end + of speech based on + + audio volume and respond at the end of user speech. For + `gpt-realtime-whisper`, this must be `null`; VAD is not + supported. + properties: + type: + type: string + description: > + Type of turn detection, only `server_vad` is + currently supported. + threshold: + type: number + description: > + Activation threshold for VAD (0.0 to 1.0), this + defaults to 0.5. A + + higher threshold will require louder audio to + activate the model, and + + thus might perform better in noisy environments. + prefix_padding_ms: + type: integer + description: > + Amount of audio to include before the VAD detected + speech (in + + milliseconds). Defaults to 300ms. + silence_duration_ms: + type: integer + description: > + Duration of silence to detect speech stop (in + milliseconds). Defaults + + to 500ms. With shorter values the model will respond + more quickly, + + but may jump in on short pauses from the user. + - type: 'null' + required: + - type + - id + - object + x-oaiMeta: + name: The transcription session object + group: realtime + example: | + { + "id": "sess_BBwZc7cFV3XizEyKGDCGL", + "type": "transcription", + "object": "realtime.transcription_session", + "expires_at": 1742188264, + "include": ["item.input_audio_transcription.logprobs"], + "audio": { + "input": { + "format": "pcm16", + "transcription": { + "model": "gpt-4o-transcribe", + "language": null, + "prompt": "" + }, + "noise_reduction": null, + "turn_detection": { + "type": "server_vad", + "threshold": 0.5, + "prefix_padding_ms": 300, + "silence_duration_ms": 200 + } + } + } + } + RealtimeTranslationClientEvent: + discriminator: + propertyName: type + description: | + A Realtime translation client event. + anyOf: + - $ref: '#/components/schemas/RealtimeTranslationClientEventSessionUpdate' + - $ref: >- + #/components/schemas/RealtimeTranslationClientEventInputAudioBufferAppend + - $ref: '#/components/schemas/RealtimeTranslationClientEventSessionClose' + RealtimeTranslationClientEventInputAudioBufferAppend: + type: object + description: > + Send this event to append audio bytes to the translation session input + audio buffer. + + + WebSocket translation sessions accept base64-encoded 24 kHz PCM16 mono + + little-endian raw audio bytes. Unsupported websocket audio formats + return a + + validation error because lower-quality audio materially degrades + translation + + quality. + + + Translation consumes 200 ms engine frames. For best realtime behavior, + append + + audio in 200 ms chunks. If a chunk is shorter, the server buffers it + until it + + has enough audio for one frame. If a chunk is longer, the server splits + it into + + 200 ms frames and enqueues them back-to-back. + + + Keep appending silence while the session is active. If a client stops + sending + + audio and later resumes, model time treats the resumed audio as + contiguous with + + the previous audio rather than as a real-world pause. + properties: + event_id: + type: string + maxLength: 512 + description: Optional client-generated ID used to identify this event. + type: + type: string + enum: + - session.input_audio_buffer.append + description: The event type, must be `session.input_audio_buffer.append`. + x-stainless-const: true + audio: + type: string + description: Base64-encoded 24 kHz PCM16 mono audio bytes. + required: + - type + - audio + x-oaiMeta: + name: session.input_audio_buffer.append + group: realtime + example: | + { + "event_id": "event_456", + "type": "session.input_audio_buffer.append", + "audio": "Base64EncodedAudioData" + } + RealtimeTranslationClientEventSessionClose: + type: object + description: > + Gracefully close the realtime translation session. The server flushes + pending + + input audio and emits any remaining translated output before closing the + + session. + properties: + event_id: + type: string + maxLength: 512 + description: Optional client-generated ID used to identify this event. + type: + type: string + enum: + - session.close + description: The event type, must be `session.close`. + x-stainless-const: true + required: + - type + x-oaiMeta: + name: session.close + group: realtime + example: | + { + "event_id": "event_789", + "type": "session.close" + } + RealtimeTranslationClientEventSessionUpdate: + type: object + description: > + Send this event to update the translation session configuration. + Translation + + sessions support updates to `audio.output.language`, + `audio.input.transcription`, + + and `audio.input.noise_reduction`. + properties: + event_id: + type: string + maxLength: 512 + description: Optional client-generated ID used to identify this event. + type: + type: string + enum: + - session.update + description: The event type, must be `session.update`. + x-stainless-const: true + session: + $ref: '#/components/schemas/RealtimeTranslationSessionUpdateRequest' + description: > + Translation session fields to update. The session `type` and `model` + are set + + at creation and cannot be changed with `session.update`. + required: + - type + - session + x-oaiMeta: + name: session.update + group: realtime + example: | + { + "type": "session.update", + "session": { + "audio": { + "input": { + "transcription": { + "model": "gpt-realtime-whisper" + }, + "noise_reduction": null + }, + "output": { + "language": "es" + } + } + } + } + RealtimeTranslationClientSecretCreateRequest: + type: object + title: Realtime translation client secret creation request + description: | + Create a translation session and client secret for the Realtime API. + properties: + expires_after: + type: object + title: Client secret expiration + description: > + Configuration for the client secret expiration. Expiration refers to + the time after which + + a client secret will no longer be valid for creating sessions. The + session itself may + + continue after that time once started. A secret can be used to + create multiple sessions + + until it expires. + properties: + anchor: + type: string + enum: + - created_at + description: > + The anchor point for the client secret expiration, meaning that + `seconds` will be added to the `created_at` time of the client + secret to produce an expiration timestamp. Only `created_at` is + currently supported. + default: created_at + x-stainless-const: true + seconds: + type: integer + format: int64 + description: > + The number of seconds from the anchor point to the expiration. + Select a value between `10` and `7200` (2 hours). This default + to 600 seconds (10 minutes) if not specified. + minimum: 10 + maximum: 7200 + default: 600 + session: + $ref: '#/components/schemas/RealtimeTranslationSessionCreateRequest' + required: + - session + RealtimeTranslationClientSecretCreateResponse: + type: object + title: Realtime translation session and client secret + description: > + Response from creating a translation session and client secret for the + Realtime API. + properties: + value: + type: string + description: The generated client secret value. + expires_at: + type: integer + format: unixtime + description: Expiration timestamp for the client secret, in seconds since epoch. + session: + $ref: '#/components/schemas/RealtimeTranslationSession' + required: + - value + - expires_at + - session + x-oaiMeta: + name: Translation session response object + group: realtime + example: | + { + "value": "ek_68af296e8e408191a1120ab6383263c2", + "expires_at": 1756310470, + "session": { + "id": "sess_C9CiUVUzUzYIssh3ELY1d", + "type": "translation", + "expires_at": 1756310470, + "model": "gpt-realtime-translate", + "audio": { + "input": { + "transcription": null, + "noise_reduction": null + }, + "output": { + "language": "es" + } + } + } + } + RealtimeTranslationServerEvent: + discriminator: + propertyName: type + description: | + A Realtime translation server event. + anyOf: + - $ref: '#/components/schemas/RealtimeServerEventError' + - $ref: '#/components/schemas/RealtimeTranslationServerEventSessionCreated' + - $ref: '#/components/schemas/RealtimeTranslationServerEventSessionUpdated' + - $ref: '#/components/schemas/RealtimeTranslationServerEventSessionClosed' + - $ref: >- + #/components/schemas/RealtimeTranslationServerEventSessionInputTranscriptDelta + - $ref: >- + #/components/schemas/RealtimeTranslationServerEventSessionOutputTranscriptDelta + - $ref: >- + #/components/schemas/RealtimeTranslationServerEventSessionOutputAudioDelta + RealtimeTranslationServerEventSessionClosed: + type: object + description: | + Returned when a realtime translation session is closed. + properties: + event_id: + type: string + description: The unique ID of the server event. + type: + type: string + enum: + - session.closed + description: The event type, must be `session.closed`. + x-stainless-const: true + required: + - event_id + - type + x-oaiMeta: + name: session.closed + group: realtime + example: | + { + "event_id": "event_987", + "type": "session.closed" + } + RealtimeTranslationServerEventSessionCreated: + type: object + description: > + Returned when a translation session is created. Emitted automatically + when a + + new connection is established as the first server event. This event + contains + + the default translation session configuration. + properties: + event_id: + type: string + description: The unique ID of the server event. + type: + type: string + enum: + - session.created + description: The event type, must be `session.created`. + x-stainless-const: true + session: + $ref: '#/components/schemas/RealtimeTranslationSession' + description: The translation session configuration. + required: + - event_id + - type + - session + x-oaiMeta: + name: session.created + group: realtime + example: | + { + "type": "session.created", + "event_id": "event_123", + "session": { + "id": "sess_123", + "type": "translation", + "model": "gpt-realtime-translate", + "expires_at": 1714857600, + "audio": { + "input": { + "transcription": { + "model": "gpt-realtime-whisper", + "language": "en" + }, + "noise_reduction": { + "type": "near_field" + } + }, + "output": { + "language": "fr" + } + } + } + } + RealtimeTranslationServerEventSessionInputTranscriptDelta: + type: object + description: > + Returned when optional source-language transcript text is available. + This event + + is emitted only when `audio.input.transcription` is configured. + + + Transcript deltas are append-only text fragments. Clients should not + insert + + unconditional spaces between deltas. + properties: + event_id: + type: string + description: The unique ID of the server event. + type: + type: string + enum: + - session.input_transcript.delta + description: The event type, must be `session.input_transcript.delta`. + x-stainless-const: true + delta: + type: string + description: Append-only source-language transcript text. + elapsed_ms: + anyOf: + - type: integer + description: > + Timing metadata for stream alignment, derived from the + translation frame + + when available. It advances in 200 ms increments, but multiple + transcript + + deltas may share the same `elapsed_ms`. Treat it as alignment + metadata, + + not a unique transcript-delta identifier. + - type: 'null' + required: + - event_id + - type + - delta + x-oaiMeta: + name: session.input_transcript.delta + group: realtime + example: | + { + "event_id": "event_125", + "type": "session.input_transcript.delta", + "delta": " hear", + "elapsed_ms": 1200 + } + RealtimeTranslationServerEventSessionOutputAudioDelta: + type: object + description: > + Returned when translated output audio is available. Output audio deltas + are + + 200 ms frames of PCM16 audio. + properties: + event_id: + type: string + description: The unique ID of the server event. + type: + type: string + enum: + - session.output_audio.delta + description: The event type, must be `session.output_audio.delta`. + x-stainless-const: true + delta: + type: string + description: Base64-encoded translated audio data. + sample_rate: + type: integer + description: Sample rate of the audio delta. + default: 24000 + channels: + type: integer + description: Number of audio channels. + default: 1 + format: + type: string + enum: + - pcm16 + description: Audio encoding for `delta`. + x-stainless-const: true + elapsed_ms: + anyOf: + - type: integer + description: > + Timing metadata for stream alignment, derived from the + translation frame + + when available. Treat `elapsed_ms` as alignment metadata, not a + unique - audio volume and respond at the end of user speech. - properties: - type: - type: string - description: > - Type of turn detection, only `server_vad` is currently - supported. - threshold: - type: number - description: > - Activation threshold for VAD (0.0 to 1.0), this defaults to 0.5. - A + event identifier. + - type: 'null' + required: + - event_id + - type + - delta + x-oaiMeta: + name: session.output_audio.delta + group: realtime + example: | + { + "event_id": "event_123", + "type": "session.output_audio.delta", + "delta": "Base64EncodedAudioDelta", + "sample_rate": 24000, + "channels": 1, + "format": "pcm16", + "elapsed_ms": 1200 + } + RealtimeTranslationServerEventSessionOutputTranscriptDelta: + type: object + description: > + Returned when translated transcript text is available. - higher threshold will require louder audio to activate the - model, and - thus might perform better in noisy environments. - prefix_padding_ms: - type: integer - description: | - Amount of audio to include before the VAD detected speech (in - milliseconds). Defaults to 300ms. - silence_duration_ms: - type: integer + Transcript deltas are append-only text fragments. Clients should not + insert + + unconditional spaces between deltas. + properties: + event_id: + type: string + description: The unique ID of the server event. + type: + type: string + enum: + - session.output_transcript.delta + description: The event type, must be `session.output_transcript.delta`. + x-stainless-const: true + delta: + type: string + description: Append-only transcript text for the translated output audio. + elapsed_ms: + anyOf: + - type: integer description: > - Duration of silence to detect speech stop (in milliseconds). - Defaults + Timing metadata for stream alignment, derived from the + translation frame - to 500ms. With shorter values the model will respond more - quickly, + when available. It advances in 200 ms increments, but multiple + transcript - but may jump in on short pauses from the user. + deltas may share the same `elapsed_ms`. Treat it as alignment + metadata, + + not a unique transcript-delta identifier. + - type: 'null' required: - - client_secret + - event_id + - type + - delta x-oaiMeta: - name: The transcription session object + name: session.output_transcript.delta group: realtime example: | { - "id": "sess_BBwZc7cFV3XizEyKGDCGL", - "object": "realtime.transcription_session", - "expires_at": 1742188264, - "modalities": ["audio", "text"], - "turn_detection": { - "type": "server_vad", - "threshold": 0.5, - "prefix_padding_ms": 300, - "silence_duration_ms": 200 - }, - "input_audio_format": "pcm16", - "input_audio_transcription": { - "model": "gpt-4o-transcribe", - "language": null, - "prompt": "" - }, - "client_secret": null + "event_id": "event_124", + "type": "session.output_transcript.delta", + "delta": " escuch", + "elapsed_ms": 1200 } - RealtimeTranscriptionSessionCreateResponseGA: + RealtimeTranslationServerEventSessionUpdated: type: object - title: Realtime transcription session configuration object - description: | - A Realtime transcription session configuration object. + description: > + Returned when a translation session is updated with a `session.update` + event, + + unless there is an error. properties: + event_id: + type: string + description: The unique ID of the server event. type: type: string - description: > - The type of session. Always `transcription` for transcription - sessions. enum: - - transcription + - session.updated + description: The event type, must be `session.updated`. x-stainless-const: true + session: + $ref: '#/components/schemas/RealtimeTranslationSession' + description: The translation session configuration. + required: + - event_id + - type + - session + x-oaiMeta: + name: session.updated + group: realtime + example: | + { + "type": "session.updated", + "event_id": "event_124", + "session": { + "id": "sess_123", + "type": "translation", + "model": "gpt-realtime-translate", + "expires_at": 1714857600, + "audio": { + "input": { + "transcription": { + "model": "gpt-realtime-whisper", + "language": "en" + }, + "noise_reduction": { + "type": "near_field" + } + }, + "output": { + "language": "es" + } + } + } + } + RealtimeTranslationSession: + type: object + title: Realtime translation session + description: > + A Realtime translation session. Translation sessions continuously + translate input + + audio into the configured output language. + properties: id: type: string description: > Unique identifier for the session that looks like `sess_1234567890abcdef`. - object: + type: type: string - description: The object type. Always `realtime.transcription_session`. + enum: + - translation + description: > + The session type. Always `translation` for Realtime translation + sessions. + x-stainless-const: true expires_at: type: integer + format: unixtime description: Expiration timestamp for the session, in seconds since epoch. - include: - type: array - items: - type: string - enum: - - item.input_audio_transcription.logprobs + model: + type: string description: > - Additional fields to include in server outputs. + The Realtime translation model used for this session. This field is + set at - - `item.input_audio_transcription.logprobs`: Include logprobs for - input audio transcription. + session creation and cannot be changed with `session.update`. audio: type: object description: | - Configuration for input audio for the session. + Configuration for translation input and output audio. properties: input: type: object properties: - format: - $ref: '#/components/schemas/RealtimeAudioFormats' transcription: - description: | - Configuration of the transcription model. - $ref: '#/components/schemas/AudioTranscription' - noise_reduction: - type: object - description: | - Configuration for input audio noise reduction. - properties: - type: - $ref: '#/components/schemas/NoiseReductionType' - turn_detection: - type: object - description: > - Configuration for turn detection. Can be set to `null` to - turn off. Server - - VAD means that the model will detect the start and end of - speech based on - - audio volume and respond at the end of user speech. - properties: - type: - type: string - description: > - Type of turn detection, only `server_vad` is currently - supported. - threshold: - type: number - description: > - Activation threshold for VAD (0.0 to 1.0), this defaults - to 0.5. A - - higher threshold will require louder audio to activate - the model, and - - thus might perform better in noisy environments. - prefix_padding_ms: - type: integer - description: > - Amount of audio to include before the VAD detected - speech (in - - milliseconds). Defaults to 300ms. - silence_duration_ms: - type: integer + anyOf: + - type: object description: > - Duration of silence to detect speech stop (in - milliseconds). Defaults + Optional source-language transcription. When configured, + the server emits - to 500ms. With shorter values the model will respond - more quickly, + `session.input_transcript.delta` events. Translation + itself still runs from - but may jump in on short pauses from the user. + the input audio stream. + properties: + model: + type: string + description: >- + The transcription model used for source transcript + deltas. + required: + - model + - type: 'null' + noise_reduction: + anyOf: + - type: object + description: | + Optional input noise reduction. + properties: + type: + $ref: '#/components/schemas/NoiseReductionType' + required: + - type + - type: 'null' + output: + type: object + properties: + language: + type: string + description: > + Target language for translated output audio and transcript + deltas. required: - - type - id - - object + - type + - expires_at + - model + - audio x-oaiMeta: - name: The transcription session object + name: The translation session object group: realtime example: | { - "id": "sess_BBwZc7cFV3XizEyKGDCGL", - "type": "transcription", - "object": "realtime.transcription_session", - "expires_at": 1742188264, - "include": ["item.input_audio_transcription.logprobs"], + "id": "sess_C9G5QPteg4UIbotdKLoYQ", + "type": "translation", + "expires_at": 1756324625, + "model": "gpt-realtime-translate", "audio": { "input": { - "format": "pcm16", "transcription": { - "model": "gpt-4o-transcribe", - "language": null, - "prompt": "" + "model": "gpt-realtime-whisper" }, - "noise_reduction": null, - "turn_detection": { - "type": "server_vad", - "threshold": 0.5, - "prefix_padding_ms": 300, - "silence_duration_ms": 200 - } + "noise_reduction": null + }, + "output": { + "language": "es" } } } + RealtimeTranslationSessionCreateRequest: + type: object + title: Realtime translation session configuration + description: > + Realtime translation session configuration. Translation sessions stream + source + + audio in and translated audio plus transcript deltas out continuously. + properties: + model: + type: string + description: | + The Realtime translation model used for this session. + audio: + type: object + description: | + Configuration for translation input and output audio. + properties: + input: + type: object + properties: + transcription: + anyOf: + - type: object + description: > + Optional source-language transcription. When configured, + the server emits + + `session.input_transcript.delta` events. Translation + itself still runs from + + the input audio stream. + properties: + model: + type: string + description: >- + The transcription model to use for source transcript + deltas. + required: + - model + - type: 'null' + noise_reduction: + anyOf: + - type: object + description: > + Optional input noise reduction. Set to `null` to disable + it. + properties: + type: + $ref: '#/components/schemas/NoiseReductionType' + required: + - type + - type: 'null' + output: + type: object + properties: + language: + type: string + description: > + Target language for translated output audio and transcript + deltas. + required: + - model + RealtimeTranslationSessionUpdateRequest: + type: object + title: Realtime translation session update + description: > + Realtime translation session fields that can be updated with + `session.update`. + properties: + audio: + type: object + description: | + Configuration for translation input and output audio. + properties: + input: + type: object + properties: + transcription: + anyOf: + - type: object + description: > + Optional source-language transcription. When configured, + the server emits + + `session.input_transcript.delta` events. Translation + itself still runs from + + the input audio stream. + properties: + model: + type: string + description: >- + The transcription model to use for source transcript + deltas. + required: + - model + - type: 'null' + noise_reduction: + anyOf: + - type: object + description: > + Optional input noise reduction. Set to `null` to disable + it. + properties: + type: + $ref: '#/components/schemas/NoiseReductionType' + required: + - type + - type: 'null' + output: + type: object + properties: + language: + type: string + description: > + Target language for translated output audio and transcript + deltas. RealtimeTruncation: title: Realtime Truncation Controls description: > @@ -58868,6 +66064,12 @@ components: model will score a low probability of turn end and wait longer for the user to continue speaking. This can be useful for more natural conversations, but may have a higher latency. + + + For `gpt-realtime-whisper` transcription sessions, turn detection + must be + + set to `null`; VAD is not supported. oneOf: - type: object title: Server VAD @@ -59202,11 +66404,13 @@ components: - incomplete created_at: type: number + format: unixtime description: | Unix timestamp (in seconds) of when this Response was created. completed_at: anyOf: - type: number + format: unixtime description: > Unix timestamp (in seconds) of when this Response was completed. @@ -59417,10 +66621,6 @@ components: enum: - response.audio.done x-stainless-const: true - response_id: - type: string - description: | - The ID of the response. sequence_number: type: integer description: | @@ -59449,10 +66649,6 @@ components: enum: - response.audio.transcript.delta x-stainless-const: true - response_id: - type: string - description: | - The ID of the response. delta: type: string description: | @@ -59486,10 +66682,6 @@ components: enum: - response.audio.transcript.done x-stainless-const: true - response_id: - type: string - description: | - The ID of the response. sequence_number: type: integer description: The sequence number of this event. @@ -60510,6 +67702,7 @@ components: required: - type - item_id + - name - output_index - arguments - sequence_number @@ -60876,10 +68069,10 @@ components: type: object description: > A logprob is the logarithmic probability that the model assigns to - producing + producing a particular token at a given position in the sequence. Less-negative - (higher) + (higher) logprob values indicate greater model confidence in that token choice. properties: @@ -60892,7 +68085,7 @@ components: type: number top_logprobs: description: | - The log probability of the top 20 most likely tokens. + The log probabilities of up to 20 of the most likely tokens. type: array items: type: object @@ -62189,7 +69382,7 @@ components: cached_tokens: type: integer description: | - The number of tokens that were retrieved from the cache. + The number of tokens that were retrieved from the cache. [More on prompt caching](/docs/guides/prompt-caching). required: - cached_tokens @@ -62553,24 +69746,24 @@ components: type: object description: > The dataset item provided to the grader. This will be used to - populate + populate the `item` namespace. See [the guide](/docs/guides/graders) for more - details. + details. model_sample: type: string description: > The model sample to be evaluated. This value will be used to - populate + populate the `sample` namespace. See [the guide](/docs/guides/graders) for more details. The `output_json` variable will be populated if the model sample is - a + a valid JSON string. - + required: - grader - model_sample @@ -62687,6 +69880,7 @@ components: created_at: description: The Unix timestamp (in seconds) for when the run was created. type: integer + format: unixtime thread_id: description: >- The ID of the [thread](/docs/api-reference/threads) that was @@ -62765,22 +69959,27 @@ components: expires_at: description: The Unix timestamp (in seconds) for when the run will expire. type: integer + format: unixtime nullable: true started_at: description: The Unix timestamp (in seconds) for when the run was started. type: integer + format: unixtime nullable: true cancelled_at: description: The Unix timestamp (in seconds) for when the run was cancelled. type: integer + format: unixtime nullable: true failed_at: description: The Unix timestamp (in seconds) for when the run failed. type: integer + format: unixtime nullable: true completed_at: description: The Unix timestamp (in seconds) for when the run was completed. type: integer + format: unixtime nullable: true incomplete_details: description: >- @@ -63480,6 +70679,7 @@ components: created_at: description: The Unix timestamp (in seconds) for when the run step was created. type: integer + format: unixtime assistant_id: description: >- The ID of the [assistant](/docs/api-reference/assistants) associated @@ -63544,6 +70744,7 @@ components: The Unix timestamp (in seconds) for when the run step expired. A step is considered expired if the parent run is expired. type: integer + format: unixtime - type: 'null' cancelled_at: anyOf: @@ -63551,16 +70752,19 @@ components: The Unix timestamp (in seconds) for when the run step was cancelled. type: integer + format: unixtime - type: 'null' failed_at: anyOf: - description: The Unix timestamp (in seconds) for when the run step failed. type: integer + format: unixtime - type: 'null' completed_at: anyOf: - description: The Unix timestamp (in seconds) for when the run step completed. type: integer + format: unixtime - type: 'null' metadata: $ref: '#/components/schemas/Metadata' @@ -64139,10 +71343,10 @@ components: An object specifying the format that the model must output. - Configuring `{ "type": "json_schema" }` enables Structured Outputs, + Configuring `{ "type": "json_schema" }` enables Structured Outputs, which ensures the model will match your supplied JSON schema. Learn more - in the + in the [Structured Outputs guide](/docs/guides/structured-outputs). @@ -64232,6 +71436,7 @@ components: created_at: description: The Unix timestamp (in seconds) for when the thread was created. type: integer + format: unixtime tool_resources: anyOf: - type: object @@ -64694,11 +71899,11 @@ components: description: Unique identifier for the segment. start: type: number - format: float + format: double description: Start timestamp of the segment in seconds. end: type: number - format: float + format: double description: End timestamp of the segment in seconds. text: type: string @@ -64738,6 +71943,7 @@ components: x-stainless-const: true seconds: type: number + format: double description: Duration of the input audio in seconds. required: - type @@ -64789,7 +71995,7 @@ components: detection parameters manually. If unset, the audio is transcribed as a single - block. + block. oneOf: - type: string enum: @@ -64817,11 +72023,11 @@ components: description: Unique identifier for the segment. start: type: number - format: float + format: double description: Start timestamp of the segment in seconds. end: type: number - format: float + format: double description: End timestamp of the segment in seconds. text: type: string @@ -64855,11 +72061,11 @@ components: description: Seek offset of the segment. start: type: number - format: float + format: double description: Start time of the segment in seconds. end: type: number - format: float + format: double description: End time of the segment in seconds. text: type: string @@ -64910,11 +72116,11 @@ components: description: The text content of the word. start: type: number - format: float + format: double description: Start time of the word in seconds. end: type: number - format: float + format: double description: End time of the word in seconds. required: - word @@ -65010,6 +72216,7 @@ components: endpoints. created_at: type: integer + format: unixtime description: The Unix timestamp (in seconds) for when the Upload was created. filename: type: string @@ -65033,6 +72240,7 @@ components: - expired expires_at: type: integer + format: unixtime description: The Unix timestamp (in seconds) for when the Upload will expire. object: type: string @@ -65080,11 +72288,11 @@ components: name: type: string description: An optional name for the certificate - content: + certificate: type: string description: The certificate content in PEM format required: - - content + - certificate UploadPart: type: object title: UploadPart @@ -65099,6 +72307,7 @@ components: endpoints. created_at: type: integer + format: unixtime description: The Unix timestamp (in seconds) for when the Part was created. upload_id: type: string @@ -65195,6 +72404,7 @@ components: x-stainless-const: true seconds: type: integer + format: int64 description: The number of seconds processed. num_model_requests: type: integer @@ -65266,7 +72476,7 @@ components: - type: 'null' required: - object - - sessions + - num_sessions x-oaiMeta: name: Code interpreter sessions usage object example: | @@ -65586,7 +72796,9 @@ components: has_more: type: boolean next_page: - type: string + anyOf: + - type: string + - type: 'null' required: - object - data @@ -65604,7 +72816,7 @@ components: type: integer end_time: type: integer - result: + results: type: array items: oneOf: @@ -65617,11 +72829,13 @@ components: - $ref: '#/components/schemas/UsageVectorStoresResult' - $ref: '#/components/schemas/UsageCodeInterpreterSessionsResult' - $ref: '#/components/schemas/CostsResult' + discriminator: + propertyName: object required: - object - start_time - end_time - - result + - results UsageVectorStoresResult: type: object description: The aggregated vector stores usage details of the specific time bucket. @@ -65666,26 +72880,131 @@ components: type: string description: The identifier, which can be referenced in API endpoints name: - type: string + anyOf: + - type: string + - type: 'null' description: The name of the user email: - type: string + anyOf: + - type: string + - type: 'null' description: The email address of the user role: - type: string - enum: - - owner - - reader + anyOf: + - type: string + - type: 'null' description: '`owner` or `reader`' added_at: type: integer + format: unixtime description: The Unix timestamp (in seconds) of when the user was added. + is_default: + type: boolean + description: Whether this is the organization's default user. + created: + type: integer + format: unixtime + description: The Unix timestamp (in seconds) of when the user was created. + user: + type: object + description: Nested user details. + properties: + object: + type: string + enum: + - user + x-stainless-const: true + id: + type: string + email: + anyOf: + - type: string + - type: 'null' + name: + anyOf: + - type: string + - type: 'null' + picture: + anyOf: + - type: string + - type: 'null' + enabled: + anyOf: + - type: boolean + - type: 'null' + banned: + anyOf: + - type: boolean + - type: 'null' + banned_at: + anyOf: + - type: integer + format: unixtime + - type: 'null' + required: + - object + - id + is_service_account: + type: boolean + description: Whether the user is a service account. + is_scale_tier_authorized_purchaser: + anyOf: + - type: boolean + - type: 'null' + description: Whether the user is an authorized purchaser for Scale Tier. + is_scim_managed: + type: boolean + description: Whether the user is managed through SCIM. + api_key_last_used_at: + anyOf: + - type: integer + format: unixtime + - type: 'null' + description: The Unix timestamp (in seconds) of the user's last API key usage. + technical_level: + anyOf: + - type: string + - type: 'null' + description: The technical level metadata for the user. + developer_persona: + anyOf: + - type: string + - type: 'null' + description: The developer persona metadata for the user. + projects: + anyOf: + - type: object + properties: + object: + type: string + enum: + - list + x-stainless-const: true + data: + type: array + items: + type: object + properties: + id: + anyOf: + - type: string + - type: 'null' + name: + anyOf: + - type: string + - type: 'null' + role: + anyOf: + - type: string + - type: 'null' + required: + - object + - data + - type: 'null' + description: Projects associated with the user, if included. required: - object - id - - name - - email - - role - added_at x-oaiMeta: name: The user object @@ -65730,7 +73049,7 @@ components: type: array description: Users in the current page. items: - $ref: '#/components/schemas/User' + $ref: '#/components/schemas/GroupUser' has_more: type: boolean description: Whether more users are available when paginating. @@ -65753,12 +73072,9 @@ components: "object": "list", "data": [ { - "object": "organization.user", "id": "user_abc123", "name": "Ada Lovelace", - "email": "ada@example.com", - "role": "owner", - "added_at": 1711471533 + "email": "ada@example.com" } ], "has_more": false, @@ -65777,16 +73093,18 @@ components: items: $ref: '#/components/schemas/User' first_id: - type: string + anyOf: + - type: string + - type: 'null' last_id: - type: string + anyOf: + - type: string + - type: 'null' has_more: type: boolean required: - object - data - - first_id - - last_id - has_more UserRoleAssignment: type: object @@ -65836,13 +73154,25 @@ components: type: object properties: role: - type: string - enum: - - owner - - reader + anyOf: + - type: string + - type: 'null' description: '`owner` or `reader`' - required: - - role + role_id: + anyOf: + - type: string + - type: 'null' + description: Role ID to assign to the user. + technical_level: + anyOf: + - type: string + - type: 'null' + description: Technical level metadata. + developer_persona: + anyOf: + - type: string + - type: 'null' + description: Developer persona metadata. VadConfig: type: object additionalProperties: false @@ -65860,23 +73190,23 @@ components: type: integer default: 300 description: | - Amount of audio to include before the VAD detected speech (in + Amount of audio to include before the VAD detected speech (in milliseconds). silence_duration_ms: type: integer default: 200 description: | Duration of silence to detect speech stop (in milliseconds). - With shorter values the model will respond more quickly, + With shorter values the model will respond more quickly, but may jump in on short pauses from the user. threshold: type: number default: 0.5 description: > - Sensitivity threshold (0.0 to 1.0) for voice activity detection. A + Sensitivity threshold (0.0 to 1.0) for voice activity detection. A higher threshold will require louder audio to activate the model, - and + and thus might perform better in noisy environments. ValidateGraderRequest: @@ -65978,6 +73308,7 @@ components: The Unix timestamp (in seconds) for when the vector store files batch was created. type: integer + format: unixtime vector_store_id: description: >- The ID of the [vector @@ -66102,6 +73433,7 @@ components: The Unix timestamp (in seconds) for when the vector store file was created. type: integer + format: unixtime vector_store_id: description: >- The ID of the [vector @@ -66199,6 +73531,7 @@ components: The Unix timestamp (in seconds) for when the vector store was created. type: integer + format: unixtime name: description: The name of the vector store. type: string @@ -66247,6 +73580,7 @@ components: The Unix timestamp (in seconds) for when the vector store will expire. type: integer + format: unixtime - type: 'null' last_active_at: anyOf: @@ -66254,6 +73588,7 @@ components: The Unix timestamp (in seconds) for when the vector store was last active. type: integer + format: unixtime - type: 'null' metadata: $ref: '#/components/schemas/Metadata' @@ -66540,6 +73875,7 @@ components: `en-US`). created_at: type: integer + format: unixtime description: >- The Unix timestamp (in seconds) for when the consent recording was created. @@ -66611,6 +73947,7 @@ components: description: The name of the voice. created_at: type: integer + format: unixtime description: The Unix timestamp (in seconds) for when the voice was created. required: - object @@ -66720,6 +74057,7 @@ components: x-stainless-const: true url: type: string + format: uri description: | The URL of the source. required: @@ -66727,6 +74065,7 @@ components: - url required: - type + - query WebSearchApproximateLocation: anyOf: - type: object @@ -66776,7 +74115,7 @@ components: type: string description: > High level guidance for the amount of context window space to use for - the + the search. One of `low`, `medium`, or `high`. `medium` is the default. enum: @@ -66792,7 +74131,7 @@ components: country: type: string description: > - The two-letter + The two-letter [ISO country code](https://en.wikipedia.org/wiki/ISO_3166-1) of the user, @@ -66810,7 +74149,7 @@ components: type: string description: > The [IANA - timezone](https://timeapi.io/documentation/iana-timezones) + timezone](https://timeapi.io/documentation/iana-timezones) of the user, e.g. `America/Los_Angeles`. WebSearchTool: @@ -66929,6 +74268,7 @@ components: properties: created_at: type: integer + format: unixtime description: > The Unix timestamp (in seconds) of when the batch API request was cancelled. @@ -66986,6 +74326,7 @@ components: properties: created_at: type: integer + format: unixtime description: > The Unix timestamp (in seconds) of when the batch API request was completed. @@ -67043,6 +74384,7 @@ components: properties: created_at: type: integer + format: unixtime description: > The Unix timestamp (in seconds) of when the batch API request expired. @@ -67100,6 +74442,7 @@ components: properties: created_at: type: integer + format: unixtime description: > The Unix timestamp (in seconds) of when the batch API request failed. @@ -67157,6 +74500,7 @@ components: properties: created_at: type: integer + format: unixtime description: | The Unix timestamp (in seconds) of when the eval run was canceled. id: @@ -67199,7 +74543,7 @@ components: "data": { "id": "evalrun_abc123" } - } + } WebhookEvalRunFailed: type: object title: eval.run.failed @@ -67213,6 +74557,7 @@ components: properties: created_at: type: integer + format: unixtime description: | The Unix timestamp (in seconds) of when the eval run failed. id: @@ -67255,7 +74600,7 @@ components: "data": { "id": "evalrun_abc123" } - } + } WebhookEvalRunSucceeded: type: object title: eval.run.succeeded @@ -67269,6 +74614,7 @@ components: properties: created_at: type: integer + format: unixtime description: | The Unix timestamp (in seconds) of when the eval run succeeded. id: @@ -67311,7 +74657,7 @@ components: "data": { "id": "evalrun_abc123" } - } + } WebhookFineTuningJobCancelled: type: object title: fine_tuning.job.cancelled @@ -67325,6 +74671,7 @@ components: properties: created_at: type: integer + format: unixtime description: > The Unix timestamp (in seconds) of when the fine-tuning job was cancelled. @@ -67368,7 +74715,7 @@ components: "data": { "id": "ftjob_abc123" } - } + } WebhookFineTuningJobFailed: type: object title: fine_tuning.job.failed @@ -67382,6 +74729,7 @@ components: properties: created_at: type: integer + format: unixtime description: | The Unix timestamp (in seconds) of when the fine-tuning job failed. id: @@ -67424,7 +74772,7 @@ components: "data": { "id": "ftjob_abc123" } - } + } WebhookFineTuningJobSucceeded: type: object title: fine_tuning.job.succeeded @@ -67438,6 +74786,7 @@ components: properties: created_at: type: integer + format: unixtime description: > The Unix timestamp (in seconds) of when the fine-tuning job succeeded. @@ -67481,7 +74830,7 @@ components: "data": { "id": "ftjob_abc123" } - } + } WebhookRealtimeCallIncoming: type: object title: realtime.call.incoming @@ -67495,6 +74844,7 @@ components: properties: created_at: type: integer + format: unixtime description: > The Unix timestamp (in seconds) of when the model response was completed. @@ -67578,6 +74928,7 @@ components: properties: created_at: type: integer + format: unixtime description: > The Unix timestamp (in seconds) of when the model response was cancelled. @@ -67635,6 +74986,7 @@ components: properties: created_at: type: integer + format: unixtime description: > The Unix timestamp (in seconds) of when the model response was completed. @@ -67692,6 +75044,7 @@ components: properties: created_at: type: integer + format: unixtime description: | The Unix timestamp (in seconds) of when the model response failed. id: @@ -67748,6 +75101,7 @@ components: properties: created_at: type: integer + format: unixtime description: > The Unix timestamp (in seconds) of when the model response was interrupted. @@ -67942,6 +75296,9 @@ components: Specify additional output data to include in the model response. Currently supported values are: + - `web_search_call.results`: Include the search results of the web + search tool call. + - `web_search_call.action.sources`: Include the sources of the web search tool call. @@ -68037,6 +75394,7 @@ components: x-stainless-const: true url: type: string + format: uri description: The URL of the web resource. start_index: type: integer @@ -68262,6 +75620,7 @@ components: image_url: anyOf: - type: string + format: uri description: >- The URL of the image to be sent to the model. A fully qualified URL or base64 encoded image in a data URL. @@ -68298,6 +75657,7 @@ components: image_url: anyOf: - type: string + format: uri description: The URL of the screenshot image. - type: 'null' file_id: @@ -68346,6 +75706,7 @@ components: The content of the file to be sent to the model. file_url: type: string + format: uri description: The URL of the file to be sent to the model. detail: $ref: '#/components/schemas/FileInputDetail' @@ -69512,6 +76873,7 @@ components: x-stainless-const: true url: type: string + format: uri description: The URL of the image output from the code interpreter. type: object required: @@ -69587,7 +76949,7 @@ components: - max_output_length title: Shell exec action description: Execute a shell command. - LocalShellCallStatus: + FunctionShellCallStatus: type: string enum: - in_progress @@ -69647,7 +77009,7 @@ components: The shell commands and limits that describe how to run the tool call. status: - $ref: '#/components/schemas/LocalShellCallStatus' + $ref: '#/components/schemas/FunctionShellCallStatus' description: >- The status of the shell call. One of `in_progress`, `completed`, or `incomplete`. @@ -69674,7 +77036,7 @@ components: description: >- A tool call that executes one or more shell commands in a managed environment. - LocalShellCallOutputStatusEnum: + FunctionShellCallOutputStatusEnum: type: string enum: - in_progress @@ -69758,7 +77120,7 @@ components: type: string description: The unique ID of the shell tool call generated by the model. status: - $ref: '#/components/schemas/LocalShellCallOutputStatusEnum' + $ref: '#/components/schemas/FunctionShellCallOutputStatusEnum' description: >- The status of the shell call output. One of `in_progress`, `completed`, or `incomplete`. @@ -70046,6 +77408,7 @@ components: anyOf: - type: string maxLength: 20971520 + format: uri description: >- The URL of the image to be sent to the model. A fully qualified URL or base64 encoded image in a data URL. @@ -70104,6 +77467,7 @@ components: file_url: anyOf: - type: string + format: uri description: The URL of the file to be sent to the model. - type: 'null' detail: @@ -70684,6 +78048,7 @@ components: Keys are strings with a maximum length of 64 characters. Values are strings with a maximum length of 512 characters. created_at: type: integer + format: unixtime description: >- The time at which the conversation was created, measured in seconds since the Unix epoch. @@ -70941,10 +78306,12 @@ components: description: Approximate completion percentage for the generation task. created_at: type: integer + format: unixtime description: Unix timestamp (seconds) for when the job was created. completed_at: anyOf: - type: integer + format: unixtime description: >- Unix timestamp (seconds) for when the job completed, if finished. @@ -70952,6 +78319,7 @@ components: expires_at: anyOf: - type: integer + format: unixtime description: >- Unix timestamp (seconds) for when the downloadable assets expire, if set. @@ -71037,6 +78405,7 @@ components: image_url: type: string maxLength: 20971520 + format: uri description: A fully qualified URL or base64-encoded data URL. file_id: type: string @@ -71147,6 +78516,7 @@ components: - type: 'null' created_at: type: integer + format: unixtime description: Unix timestamp (in seconds) when the character was created. type: object required: @@ -71412,6 +78782,13 @@ components: enum: - in_memory - 24h + ServiceTierEnum: + type: string + enum: + - auto + - default + - flex + - priority CompactResponseMethodPublicBody: properties: model: @@ -71467,6 +78844,11 @@ components: - $ref: '#/components/schemas/PromptCacheRetentionEnum' description: How long to retain a prompt cache entry created by this request. - type: 'null' + service_tier: + anyOf: + - $ref: '#/components/schemas/ServiceTierEnum' + description: The service tier to use for this request. + - type: 'null' type: object required: - model @@ -71486,7 +78868,9 @@ components: - $ref: '#/components/schemas/CompactionBody' - $ref: '#/components/schemas/CodeInterpreterToolCall' - $ref: '#/components/schemas/LocalShellToolCall' + deprecated: true - $ref: '#/components/schemas/LocalShellToolCallOutput' + deprecated: true - $ref: '#/components/schemas/FunctionShellCall' - $ref: '#/components/schemas/FunctionShellCallOutput' - $ref: '#/components/schemas/ApplyPatchToolCall' @@ -71521,6 +78905,7 @@ components: description: The compacted list of output items. created_at: type: integer + format: unixtime description: >- Unix timestamp (in seconds) when the compacted conversation was created. @@ -71579,6 +78964,7 @@ components: description: Description of the skill. created_at: type: integer + format: unixtime description: Unix timestamp (seconds) for when the skill was created. default_version: type: string @@ -71696,6 +79082,7 @@ components: description: Version number for this skill. created_at: type: integer + format: unixtime description: Unix timestamp (seconds) for when the version was created. name: type: string @@ -71933,6 +79320,7 @@ components: x-stainless-const: true expires_at: type: integer + format: unixtime description: Unix timestamp (in seconds) for when the session expires. client_secret: type: string @@ -72051,6 +79439,7 @@ components: type: integer maximum: 600 minimum: 1 + format: int64 description: Number of seconds after the anchor when the session expires. type: object required: @@ -72228,6 +79617,7 @@ components: preview_url: anyOf: - type: string + format: uri description: Preview URL for rendering the attachment inline. - type: 'null' type: object @@ -72285,6 +79675,7 @@ components: x-stainless-const: true created_at: type: integer + format: unixtime description: Unix timestamp (in seconds) for when the item was created. thread_id: type: string @@ -72378,6 +79769,7 @@ components: x-stainless-const: true url: type: string + format: uri description: URL referenced by the annotation. type: object required: @@ -72446,6 +79838,7 @@ components: x-stainless-const: true created_at: type: integer + format: unixtime description: Unix timestamp (in seconds) for when the item was created. thread_id: type: string @@ -72486,6 +79879,7 @@ components: x-stainless-const: true created_at: type: integer + format: unixtime description: Unix timestamp (in seconds) for when the item was created. thread_id: type: string @@ -72529,6 +79923,7 @@ components: x-stainless-const: true created_at: type: integer + format: unixtime description: Unix timestamp (in seconds) for when the item was created. thread_id: type: string @@ -72592,6 +79987,7 @@ components: x-stainless-const: true created_at: type: integer + format: unixtime description: Unix timestamp (in seconds) for when the item was created. thread_id: type: string @@ -72672,6 +80068,7 @@ components: x-stainless-const: true created_at: type: integer + format: unixtime description: Unix timestamp (in seconds) for when the item was created. thread_id: type: string @@ -72817,6 +80214,7 @@ components: x-stainless-const: true created_at: type: integer + format: unixtime description: Unix timestamp (in seconds) for when the thread was created. title: anyOf: @@ -72932,6 +80330,9 @@ components: ApiKeyAuth: type: http scheme: bearer + AdminApiKeyAuth: + type: http + scheme: bearer x-oaiMeta: navigationGroups: - id: responses @@ -73380,6 +80781,50 @@ x-oaiMeta: - type: object key: RealtimeServerEventRateLimitsUpdated path: + - id: realtime-translation-client-events + title: Translation client events + description: > + These are events that the OpenAI Realtime Translation WebSocket server + will accept from the client. + navigationGroup: realtime + sections: + - type: object + key: RealtimeTranslationClientEventSessionUpdate + path: + - type: object + key: RealtimeTranslationClientEventInputAudioBufferAppend + path: + - type: object + key: RealtimeTranslationClientEventSessionClose + path: + - id: realtime-translation-server-events + title: Translation server events + description: > + These are events emitted from the OpenAI Realtime Translation WebSocket + server to the client. + navigationGroup: realtime + sections: + - type: object + key: RealtimeServerEventError + path: + - type: object + key: RealtimeTranslationServerEventSessionCreated + path: + - type: object + key: RealtimeTranslationServerEventSessionUpdated + path: + - type: object + key: RealtimeTranslationServerEventSessionClosed + path: + - type: object + key: RealtimeTranslationServerEventSessionInputTranscriptDelta + path: + - type: object + key: RealtimeTranslationServerEventSessionOutputTranscriptDelta + path: + - type: object + key: RealtimeTranslationServerEventSessionOutputAudioDelta + path: - id: chat-streaming title: Streaming description: | From 7d1e23d01918aa577167c3df6c7b456aa149a1e8 Mon Sep 17 00:00:00 2001 From: nezhyborets Date: Fri, 19 Jun 2026 19:22:11 +0300 Subject: [PATCH 2/9] Add reproducible OpenAPI generation workarounds --- Makefile | 16 ++- Scripts/fix_boolean_exclusive_minimum.py | 121 +++++++++++++++++++++++ Scripts/fix_recursive_reference.py | 72 ++++++++++++++ Scripts/fix_rounded_int64_bounds.py | 82 +++++++++++++++ Scripts/prepare_openapi.py | 77 +++++++++++++++ Scripts/remove_unsupported_webhooks.py | 85 ++++++++++++++++ 6 files changed, 449 insertions(+), 4 deletions(-) create mode 100644 Scripts/fix_boolean_exclusive_minimum.py create mode 100644 Scripts/fix_recursive_reference.py create mode 100644 Scripts/fix_rounded_int64_bounds.py create mode 100644 Scripts/prepare_openapi.py create mode 100644 Scripts/remove_unsupported_webhooks.py diff --git a/Makefile b/Makefile index 0d47e509..9e408c79 100644 --- a/Makefile +++ b/Makefile @@ -5,12 +5,20 @@ GENERATOR_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST))))/../ PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST)))) TYPES_SWIFT := $(GENERATOR_DIR)/Types.swift COMPONENTS_SWIFT := $(PROJECT_DIR)/Sources/OpenAI/Public/Schemas/Generated/Components.swift +PREPARED_OPENAPI := $(PROJECT_DIR)/.build/openapi-generator/openapi.yaml +OPENAPI_DIFF := $(PROJECT_DIR)/.build/openapi-generator/openapi.patch .PHONY: generate generate: + # Prepare a working copy with conditional, documented upstream-spec fixes. + # See the scripts called by prepare_openapi.py for each error and its fix. + python3 "$(PROJECT_DIR)/Scripts/prepare_openapi.py" \ + "$(PROJECT_DIR)/openapi.yaml" \ + "$(PREPARED_OPENAPI)" \ + --diff-output "$(OPENAPI_DIFF)" cd "$(GENERATOR_DIR)" && swift run swift-openapi-generator generate \ --config "$(PROJECT_DIR)/openapi-generator-config.yaml" \ - "$(PROJECT_DIR)/openapi.with-code-samples.yml" - python3 "$(PROJECT_DIR)/Scripts/extract_components.py" \ - "$(TYPES_SWIFT)" \ - "$(COMPONENTS_SWIFT)" + "$(PREPARED_OPENAPI)" +# python3 "$(PROJECT_DIR)/Scripts/extract_components.py" \ +# "$(TYPES_SWIFT)" \ +# "$(COMPONENTS_SWIFT)" diff --git a/Scripts/fix_boolean_exclusive_minimum.py b/Scripts/fix_boolean_exclusive_minimum.py new file mode 100644 index 00000000..f2b38647 --- /dev/null +++ b/Scripts/fix_boolean_exclusive_minimum.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python3 +"""Convert OpenAPI 3.0 boolean exclusiveMinimum syntax to OpenAPI 3.1. + +Symptom: + "Expected `exclusiveMinimum` value ... to be parsable as Double but it was + not." + +Cause: + The document declares OpenAPI 3.1 but contains the OpenAPI 3.0 form: + `minimum: X` together with `exclusiveMinimum: true`. In OpenAPI 3.1, + `exclusiveMinimum` itself must contain the numeric boundary. + +Fix: + Convert `minimum: X` plus `exclusiveMinimum: true` to + `exclusiveMinimum: X`. A false boolean is removed while its inclusive + `minimum` remains unchanged. + +Removal condition: + When no boolean exclusiveMinimum values remain upstream, this script is a + no-op. It can be removed from prepare_openapi.py after generation is + verified with the new spec. +""" + +from __future__ import annotations + +import argparse +import re +from pathlib import Path + + +BOOLEAN_EXCLUSIVE_MINIMUM_RE = re.compile( + r"^(?P\s*)exclusiveMinimum:\s*(?Ptrue|false)" + r"[ \t]*(?:#.*)?(?P\r?\n)?$" +) +NUMERIC_MINIMUM_RE = re.compile( + r"^(?P\s*)minimum:\s*" + r"(?P[-+]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][-+]?\d+)?)" + r"[ \t]*(?:#.*)?(?:\r?\n)?$" +) + + +def fix_boolean_exclusive_minimum(document: str) -> tuple[str, int]: + """Return an OpenAPI 3.1-compatible document and conversion count.""" + + lines = document.splitlines(keepends=True) + replacement_count = 0 + + for index, line in enumerate(lines): + exclusive_match = BOOLEAN_EXCLUSIVE_MINIMUM_RE.match(line) + if exclusive_match is None: + continue + + replacement_count += 1 + if exclusive_match.group("value") == "false": + lines[index] = "" + continue + + indent = exclusive_match.group("indent") + minimum_index = None + minimum_value = None + + # Find a preceding `minimum` sibling in this schema. Other siblings, + # such as `maximum`, may appear between the two constraints. + for candidate_index in range(index - 1, -1, -1): + candidate = lines[candidate_index] + if not candidate.strip() or candidate.lstrip().startswith("#"): + continue + + candidate_indent = candidate[: len(candidate) - len(candidate.lstrip())] + if len(candidate_indent) < len(indent): + break + + minimum_match = NUMERIC_MINIMUM_RE.match(candidate) + if minimum_match and minimum_match.group("indent") == indent: + minimum_index = candidate_index + minimum_value = minimum_match.group("value") + break + + if minimum_index is None or minimum_value is None: + line_number = index + 1 + raise ValueError( + "Cannot convert `exclusiveMinimum: true` on line " + f"{line_number}: no numeric sibling `minimum` was found." + ) + + newline = exclusive_match.group("newline") or "" + lines[minimum_index] = "" + lines[index] = f"{indent}exclusiveMinimum: {minimum_value}{newline}" + + return "".join(lines), replacement_count + + +def report_result(replacement_count: int) -> None: + if replacement_count: + print( + "Boolean exclusiveMinimum workaround applied: " + f"{replacement_count} replacement(s)." + ) + else: + print( + "Boolean exclusiveMinimum workaround not needed. The upstream spec " + "may be fixed; consider removing this workaround after generation " + "succeeds." + ) + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("input", type=Path, help="Input OpenAPI document") + parser.add_argument("output", type=Path, help="Fixed OpenAPI document") + args = parser.parse_args() + + document = args.input.read_text(encoding="utf-8") + fixed_document, replacement_count = fix_boolean_exclusive_minimum(document) + args.output.parent.mkdir(parents=True, exist_ok=True) + args.output.write_text(fixed_document, encoding="utf-8") + report_result(replacement_count) + + +if __name__ == "__main__": + main() diff --git a/Scripts/fix_recursive_reference.py b/Scripts/fix_recursive_reference.py new file mode 100644 index 00000000..d3c7ea50 --- /dev/null +++ b/Scripts/fix_recursive_reference.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 +"""Replace the unsupported CompoundFilter recursive reference. + +Symptom: + Validation warns that CompoundFilter's second item union member contains + nothing but unsupported attributes. + +Cause: + Swift OpenAPI Generator does not support JSON Schema `$recursiveRef`. + +Fix: + Replace the one known `$recursiveRef: '#'` with an ordinary component + reference to `CompoundFilter`, preserving the intended recursion. + +Semantic limitation: + This is not a general equivalent of `$recursiveRef`. `$recursiveRef` can + resolve through the active recursive-anchor scope, while `$ref` always + targets the named `CompoundFilter` component. They behave the same for this + self-contained document because CompoundFilter is the only recursive anchor + and the reference represents nested CompoundFilter values. Reassess this + workaround if the schema gains another recursive anchor, an external schema, + or recursive extension/composition. + +Removal condition: + Remove this workaround when the generator supports `$recursiveRef`, or when + the upstream spec no longer contains this exact reference. +""" + +from __future__ import annotations + +import argparse +from pathlib import Path + + +OLD_REFERENCE = "$recursiveRef: '#'" +NEW_REFERENCE = "$ref: '#/components/schemas/CompoundFilter'" + + +def fix_recursive_reference(document: str) -> tuple[str, int]: + count = document.count(OLD_REFERENCE) + if count > 1: + raise ValueError( + "Expected at most one CompoundFilter recursive reference; " + f"found {count}." + ) + return document.replace(OLD_REFERENCE, NEW_REFERENCE), count + + +def report_result(replacement_count: int) -> None: + if replacement_count: + print("Recursive reference workaround applied: 1 replacement.") + else: + print( + "Recursive reference workaround not needed. The upstream spec or " + "generator may be fixed; consider removing this workaround after " + "generation succeeds." + ) + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("input", type=Path) + parser.add_argument("output", type=Path) + args = parser.parse_args() + document, count = fix_recursive_reference(args.input.read_text(encoding="utf-8")) + args.output.parent.mkdir(parents=True, exist_ok=True) + args.output.write_text(document, encoding="utf-8") + report_result(count) + + +if __name__ == "__main__": + main() diff --git a/Scripts/fix_rounded_int64_bounds.py b/Scripts/fix_rounded_int64_bounds.py new file mode 100644 index 00000000..f34d90c7 --- /dev/null +++ b/Scripts/fix_rounded_int64_bounds.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python3 +"""Fix rounded Int64 constraints in an OpenAPI document. + +Symptom: + "Expected an Integer literal but found a floating point value + (9.223372036854776e+18)" while parsing an integer minimum/maximum. + +Cause: + The spec contains 9223372036854776000 and -9223372036854776000. Those + rounded values lie just outside Swift's Int64 range, so the YAML parser + represents them as floating point values before the generator validates + the integer schema. + +Fix: + Replace only those exact constraint values with Int64.max and Int64.min. + +Removal condition: + When neither rounded value is present upstream, this script is a no-op. It + can be removed from prepare_openapi.py after generation is verified with + the new spec. +""" + +from __future__ import annotations + +import argparse +import re +from pathlib import Path + + +ROUNDED_INT64_BOUNDS = { + "-9223372036854776000": "-9223372036854775808", + "9223372036854776000": "9223372036854775807", +} + +# Match YAML constraint lines rather than replacing the same digits in examples, +# descriptions, or unrelated extension data. +CONSTRAINT_RE = re.compile( + r"^(?P\s*(?:minimum|maximum):\s*)" + r"(?P-?9223372036854776000)" + r"(?P\s*(?:#.*)?(?:\r?\n)?)$", + re.MULTILINE, +) + + +def fix_rounded_int64_bounds(document: str) -> tuple[str, int]: + """Return the normalized document and the number of replaced constraints.""" + + def replace(match: re.Match[str]) -> str: + value = ROUNDED_INT64_BOUNDS[match.group("value")] + return f'{match.group("prefix")}{value}{match.group("suffix")}' + + return CONSTRAINT_RE.subn(replace, document) + + +def report_result(replacement_count: int) -> None: + if replacement_count: + print( + "Rounded Int64 bounds workaround applied: " + f"{replacement_count} replacement(s)." + ) + else: + print( + "Rounded Int64 bounds workaround not needed. The upstream spec may " + "be fixed; consider removing this workaround after generation succeeds." + ) + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("input", type=Path, help="Input OpenAPI document") + parser.add_argument("output", type=Path, help="Fixed OpenAPI document") + args = parser.parse_args() + + document = args.input.read_text(encoding="utf-8") + fixed_document, replacement_count = fix_rounded_int64_bounds(document) + args.output.parent.mkdir(parents=True, exist_ok=True) + args.output.write_text(fixed_document, encoding="utf-8") + report_result(replacement_count) + + +if __name__ == "__main__": + main() diff --git a/Scripts/prepare_openapi.py b/Scripts/prepare_openapi.py new file mode 100644 index 00000000..a264e15b --- /dev/null +++ b/Scripts/prepare_openapi.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +"""Apply the documented OpenAPI workarounds required before generation. + +Each workaround lives in its own independently runnable script. Keep this file +as the ordered pipeline only: read the upstream spec, apply every conditional +transformation in memory, then write one prepared copy for the generator. +""" + +from __future__ import annotations + +import argparse +import difflib +from pathlib import Path + +from fix_boolean_exclusive_minimum import ( + fix_boolean_exclusive_minimum, + report_result as report_boolean_exclusive_minimum_result, +) +from fix_rounded_int64_bounds import ( + fix_rounded_int64_bounds, + report_result as report_rounded_int64_bounds_result, +) +from fix_recursive_reference import ( + fix_recursive_reference, + report_result as report_recursive_reference_result, +) +from remove_unsupported_webhooks import ( + remove_unsupported_webhooks, + report_result as report_unsupported_webhooks_result, +) + + +def main() -> None: + parser = argparse.ArgumentParser( + description="Create a generator-compatible working copy of an OpenAPI spec." + ) + parser.add_argument("input", type=Path, help="Upstream OpenAPI document") + parser.add_argument("output", type=Path, help="Prepared working copy") + parser.add_argument( + "--diff-output", type=Path, help="Write a unified diff of input and output" + ) + args = parser.parse_args() + + original_document = args.input.read_text(encoding="utf-8") + document = original_document + + document, int64_replacement_count = fix_rounded_int64_bounds(document) + report_rounded_int64_bounds_result(int64_replacement_count) + + document, exclusive_minimum_replacement_count = fix_boolean_exclusive_minimum( + document + ) + report_boolean_exclusive_minimum_result(exclusive_minimum_replacement_count) + + document, webhook_removal_count = remove_unsupported_webhooks(document) + report_unsupported_webhooks_result(webhook_removal_count) + + document, recursive_reference_replacement_count = fix_recursive_reference(document) + report_recursive_reference_result(recursive_reference_replacement_count) + + args.output.parent.mkdir(parents=True, exist_ok=True) + args.output.write_text(document, encoding="utf-8") + + if args.diff_output is not None: + diff = difflib.unified_diff( + original_document.splitlines(keepends=True), + document.splitlines(keepends=True), + fromfile=str(args.input), + tofile=str(args.output), + ) + args.diff_output.parent.mkdir(parents=True, exist_ok=True) + args.diff_output.write_text("".join(diff), encoding="utf-8") + print(f"Prepared OpenAPI diff written to: {args.diff_output.resolve()}") + + +if __name__ == "__main__": + main() diff --git a/Scripts/remove_unsupported_webhooks.py b/Scripts/remove_unsupported_webhooks.py new file mode 100644 index 00000000..05277995 --- /dev/null +++ b/Scripts/remove_unsupported_webhooks.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 +"""Remove unsupported top-level webhooks before Swift code generation. + +Symptom: + Validation reports that JSONSchema references under `.webhooks...` cannot + be found in `components/schemas`, even though they exist in the source spec. + +Cause: + Swift OpenAPI Generator's document filter keeps the top-level `webhooks` + section while rebuilding `components` with only schemas required by the + configured paths and explicit schemas. That leaves webhook references + dangling. This generator version does not generate webhook operations. + +Fix: + Remove exactly the top-level `webhooks` block from the prepared working + copy. The downloaded source spec remains unchanged. + +Removal condition: + Remove this workaround if a future generator supports or correctly filters + OpenAPI webhooks. If the upstream spec contains no top-level webhooks, this + script is a no-op. +""" + +from __future__ import annotations + +import argparse +import re +from pathlib import Path + + +WEBHOOKS_KEY_RE = re.compile(r"^webhooks:[ \t]*(?:#.*)?(?:\r?\n)?$") +TOP_LEVEL_KEY_RE = re.compile(r"^[A-Za-z0-9_.-]+:") + + +def remove_unsupported_webhooks(document: str) -> tuple[str, int]: + """Return the document without its top-level webhooks block.""" + + lines = document.splitlines(keepends=True) + starts = [index for index, line in enumerate(lines) if WEBHOOKS_KEY_RE.match(line)] + + if not starts: + return document, 0 + if len(starts) > 1: + raise ValueError("Cannot remove webhooks: multiple top-level `webhooks` keys found.") + + start = starts[0] + end = len(lines) + for index in range(start + 1, len(lines)): + line = lines[index] + if not line.strip() or line.lstrip().startswith("#"): + continue + if TOP_LEVEL_KEY_RE.match(line): + end = index + break + + del lines[start:end] + return "".join(lines), 1 + + +def report_result(removal_count: int) -> None: + if removal_count: + print("Unsupported webhooks workaround applied: removed 1 top-level block.") + else: + print( + "Unsupported webhooks workaround not needed. The upstream spec may " + "no longer contain webhooks; consider removing this workaround after " + "generation succeeds." + ) + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("input", type=Path, help="Input OpenAPI document") + parser.add_argument("output", type=Path, help="Fixed OpenAPI document") + args = parser.parse_args() + + document = args.input.read_text(encoding="utf-8") + fixed_document, removal_count = remove_unsupported_webhooks(document) + args.output.parent.mkdir(parents=True, exist_ok=True) + args.output.write_text(fixed_document, encoding="utf-8") + report_result(removal_count) + + +if __name__ == "__main__": + main() From 54efa77719bf390e4605b5009135af9d369d77a0 Mon Sep 17 00:00:00 2001 From: nezhyborets Date: Fri, 19 Jun 2026 20:10:59 +0300 Subject: [PATCH 3/9] Regenerate components with generator workarounds --- Makefile | 44 ++- Scripts/remove_required_properties.py | 158 ++++++++ .../Public/Schemas/Generated/Components.swift | 343 ++++++++++++------ Tests/OpenAITests/StreamingClientTests.swift | 2 +- 4 files changed, 428 insertions(+), 119 deletions(-) create mode 100644 Scripts/remove_required_properties.py diff --git a/Makefile b/Makefile index 9e408c79..5447002f 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,32 @@ # Requires a local fork of swift-openapi-generator to be checked out as a # sibling directory named `swift-openapi-generator` (i.e. ../swift-openapi-generator). # See https://github.com/apple/swift-openapi-generator for the upstream repo. +# +# The fork must include these changes, which are not available in the official +# generator at the time of writing: +# +# - Handle OpenAPI 3.1 nullable schemas expressed as +# `anyOf: [, { type: null }]`. The generator must ignore the null +# branch while assigning the Swift type, then make the resulting type +# optional. Without this change, nullable properties are unsupported or are +# generated as an anyOf wrapper instead of the expected optional Swift type. +# This is implemented by local commit fe49fc3f7e17b255012ab11925f53863e4972933. +# +# - When a oneOf discriminator has no explicit mapping, also match the string +# enum values declared by the referenced schemas' discriminator property. +# The OpenAI spec uses runtime values such as `input_text`, which do not match +# schema names such as `InputTextContent`; without this change, decoding a +# valid response throws unknownOneOfDiscriminator. This is implemented by +# local commit 33a4f7ccdc4adb577e20033562858ffc657a589a and corresponds to +# https://github.com/openai/openai-openapi/issues/542. +# +# Expected diagnostic: +# The generator warns that `InputMessageResource/value2` requires `type` even +# though that property is declared by the sibling `InputMessage` schema in the +# same `allOf`. JSON Schema applies both members to the same object, while the +# generator validates each generated allOf payload independently. The property +# remains available through the generated `InputMessage` payload, so this +# warning is intentionally ignored. GENERATOR_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST))))/../swift-openapi-generator PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST)))) TYPES_SWIFT := $(GENERATOR_DIR)/Types.swift @@ -12,13 +38,23 @@ OPENAPI_DIFF := $(PROJECT_DIR)/.build/openapi-generator/openapi.patch generate: # Prepare a working copy with conditional, documented upstream-spec fixes. # See the scripts called by prepare_openapi.py for each error and its fix. - python3 "$(PROJECT_DIR)/Scripts/prepare_openapi.py" \ + python3 -B "$(PROJECT_DIR)/Scripts/prepare_openapi.py" \ "$(PROJECT_DIR)/openapi.yaml" \ + "$(PREPARED_OPENAPI)" + python3 -B "$(PROJECT_DIR)/Scripts/remove_required_properties.py" \ + "$(PREPARED_OPENAPI)" \ "$(PREPARED_OPENAPI)" \ + --remove-required "LocalShellToolCallOutput" "call_id" \ + --remove-required "MCPApprovalResponse" "request_id" \ + --remove-required "MCPApprovalResponseResource" "request_id" \ + --remove-required "ResponseAudioDoneEvent" "response_id" \ + --remove-required "ResponseAudioTranscriptDeltaEvent" "response_id" \ + --remove-required "ResponseAudioTranscriptDoneEvent" "response_id" \ + --diff-source "$(PROJECT_DIR)/openapi.yaml" \ --diff-output "$(OPENAPI_DIFF)" cd "$(GENERATOR_DIR)" && swift run swift-openapi-generator generate \ --config "$(PROJECT_DIR)/openapi-generator-config.yaml" \ "$(PREPARED_OPENAPI)" -# python3 "$(PROJECT_DIR)/Scripts/extract_components.py" \ -# "$(TYPES_SWIFT)" \ -# "$(COMPONENTS_SWIFT)" + python3 -B "$(PROJECT_DIR)/Scripts/extract_components.py" \ + "$(TYPES_SWIFT)" \ + "$(COMPONENTS_SWIFT)" diff --git a/Scripts/remove_required_properties.py b/Scripts/remove_required_properties.py new file mode 100644 index 00000000..3d2995e1 --- /dev/null +++ b/Scripts/remove_required_properties.py @@ -0,0 +1,158 @@ +#!/usr/bin/env python3 +"""Remove selected component properties from OpenAPI `required` lists. + +Some upstream component schemas contain stale names in their `required` lists: +the named property is not present in the schema's `properties` map and is not +part of the corresponding types generated by the official OpenAI SDKs. + +Pass each removal as two arguments: `SchemaName property_name`. Every requested +schema, schema-level `required` list, and property entry must exist exactly +once. This strictness makes an upstream schema change visible instead of +silently applying the workaround in the wrong place. +""" + +from __future__ import annotations + +import argparse +import difflib +import re +from dataclasses import dataclass +from pathlib import Path + + +COMPONENT_SCHEMA_RE = re.compile(r"^ (?P[^\s][^:]*):(?:\r?\n)?$") +REQUIRED_KEY_RE = re.compile(r"^ required:[ \t]*(?:#.*)?(?:\r?\n)?$") +REQUIRED_ITEM_RE = re.compile( + r"^ - (?P[^\s#]+)[ \t]*(?:#.*)?(?:\r?\n)?$" +) + + +@dataclass(frozen=True) +class RequiredProperty: + schema: str + property: str + + @property + def description(self) -> str: + return f"{self.schema}/{self.property}" + + +def remove_required_properties( + document: str, removals: list[RequiredProperty] +) -> tuple[str, list[RequiredProperty]]: + """Return the document after applying all requested strict removals.""" + + lines = document.splitlines(keepends=True) + schema_starts = [ + (index, match.group("name")) + for index, line in enumerate(lines) + if (match := COMPONENT_SCHEMA_RE.match(line)) is not None + ] + indexes_to_remove: list[int] = [] + + for removal in removals: + matching_starts = [ + index for index, name in schema_starts if name == removal.schema + ] + if len(matching_starts) != 1: + raise ValueError( + f"Expected exactly one component schema {removal.schema!r}; " + f"found {len(matching_starts)}." + ) + + schema_start = matching_starts[0] + schema_end = next( + ( + index + for index, _ in schema_starts + if index > schema_start + ), + len(lines), + ) + required_starts = [ + index + for index in range(schema_start + 1, schema_end) + if REQUIRED_KEY_RE.match(lines[index]) + ] + if len(required_starts) != 1: + raise ValueError( + f"Expected exactly one schema-level required list in " + f"{removal.schema!r}; found {len(required_starts)}." + ) + + required_start = required_starts[0] + matching_items = [] + for index in range(required_start + 1, schema_end): + match = REQUIRED_ITEM_RE.match(lines[index]) + if match is None: + break + if match.group("name") == removal.property: + matching_items.append(index) + + if len(matching_items) != 1: + raise ValueError( + f"Expected exactly one required entry {removal.description!r}; " + f"found {len(matching_items)}." + ) + indexes_to_remove.append(matching_items[0]) + + for index in sorted(indexes_to_remove, reverse=True): + del lines[index] + + return "".join(lines), removals + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("input", type=Path) + parser.add_argument("output", type=Path) + parser.add_argument( + "--remove-required", + action="append", + nargs=2, + required=True, + metavar=("SCHEMA", "PROPERTY"), + help="Remove one property from a component schema's required list", + ) + parser.add_argument( + "--diff-source", + type=Path, + help="Original document to compare with the final output", + ) + parser.add_argument( + "--diff-output", + type=Path, + help="Write a unified diff from --diff-source to the final output", + ) + args = parser.parse_args() + + if (args.diff_source is None) != (args.diff_output is None): + parser.error("--diff-source and --diff-output must be provided together") + + document = args.input.read_text(encoding="utf-8") + removals = [ + RequiredProperty(schema=schema, property=property_name) + for schema, property_name in args.remove_required + ] + fixed_document, removals = remove_required_properties(document, removals) + args.output.parent.mkdir(parents=True, exist_ok=True) + args.output.write_text(fixed_document, encoding="utf-8") + + removed = ", ".join(removal.description for removal in removals) + print(f"Stale required properties workaround applied: removed {removed}.") + + if args.diff_source is not None and args.diff_output is not None: + original_document = args.diff_source.read_text(encoding="utf-8") + diff = difflib.unified_diff( + original_document.splitlines(keepends=True), + fixed_document.splitlines(keepends=True), + fromfile=str(args.diff_source), + tofile=str(args.output), + ) + args.diff_output.parent.mkdir(parents=True, exist_ok=True) + args.diff_output.write_text("".join(diff), encoding="utf-8") + print(f"Prepared OpenAPI diff written to: {args.diff_output.resolve()}") + + +if __name__ == "__main__": + main() diff --git a/Sources/OpenAI/Public/Schemas/Generated/Components.swift b/Sources/OpenAI/Public/Schemas/Generated/Components.swift index dc064a7f..ab7d3388 100644 --- a/Sources/OpenAI/Public/Schemas/Generated/Components.swift +++ b/Sources/OpenAI/Public/Schemas/Generated/Components.swift @@ -434,11 +434,20 @@ public enum Components { /// Type of operation: `and` or `or`. /// /// - Remark: Generated from `#/components/schemas/CompoundFilter/type`. - public var _type: Components.Schemas.CompoundFilter._TypePayload + public var _type: Components.Schemas.CompoundFilter._TypePayload { + get { + self.storage.value._type + } + _modify { + yield &self.storage.value._type + } + } /// - Remark: Generated from `#/components/schemas/CompoundFilter/FiltersPayload`. @frozen public enum FiltersPayloadPayload: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/CompoundFilter/FiltersPayload/ComparisonFilter`. case comparisonFilter(Components.Schemas.ComparisonFilter) + /// - Remark: Generated from `#/components/schemas/CompoundFilter/FiltersPayload/CompoundFilter`. + case compoundFilter(Components.Schemas.CompoundFilter) public enum CodingKeys: String, CodingKey { case _type = "type" } @@ -451,6 +460,8 @@ public enum Components { switch discriminator { case "ComparisonFilter", "#/components/schemas/ComparisonFilter", "eq", "ne", "gt", "gte", "lt", "lte", "in", "nin": self = .comparisonFilter(try .init(from: decoder)) + case "CompoundFilter", "#/components/schemas/CompoundFilter", "and", "or": + self = .compoundFilter(try .init(from: decoder)) default: throw Swift.DecodingError.unknownOneOfDiscriminator( discriminatorKey: CodingKeys._type, @@ -463,6 +474,8 @@ public enum Components { switch self { case let .comparisonFilter(value): try value.encode(to: encoder) + case let .compoundFilter(value): + try value.encode(to: encoder) } } } @@ -473,7 +486,14 @@ public enum Components { /// Array of filters to combine. Items can be `ComparisonFilter` or `CompoundFilter`. /// /// - Remark: Generated from `#/components/schemas/CompoundFilter/filters`. - public var filters: Components.Schemas.CompoundFilter.FiltersPayload + public var filters: Components.Schemas.CompoundFilter.FiltersPayload { + get { + self.storage.value.filters + } + _modify { + yield &self.storage.value.filters + } + } /// Creates a new `CompoundFilter`. /// /// - Parameters: @@ -483,27 +503,103 @@ public enum Components { _type: Components.Schemas.CompoundFilter._TypePayload, filters: Components.Schemas.CompoundFilter.FiltersPayload ) { - self._type = _type - self.filters = filters + self.storage = .init(value: .init( + _type: _type, + filters: filters + )) } public enum CodingKeys: String, CodingKey { case _type = "type" case filters } public init(from decoder: any Swift.Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - self._type = try container.decode( - Components.Schemas.CompoundFilter._TypePayload.self, - forKey: ._type - ) - self.filters = try container.decode( - Components.Schemas.CompoundFilter.FiltersPayload.self, - forKey: .filters - ) - try decoder.ensureNoAdditionalProperties(knownKeys: [ - "type", - "filters" - ]) + self.storage = try .init(from: decoder) + } + public func encode(to encoder: any Swift.Encoder) throws { + try self.storage.encode(to: encoder) + } + /// Internal reference storage to allow type recursion. + private var storage: OpenAPIRuntime.CopyOnWriteBox + private struct Storage: Codable, Hashable, Sendable { + /// Type of operation: `and` or `or`. + /// + /// - Remark: Generated from `#/components/schemas/CompoundFilter/type`. + enum _TypePayload: String, Codable, Hashable, Sendable, CaseIterable { + case and = "and" + case or = "or" + } + /// Type of operation: `and` or `or`. + /// + /// - Remark: Generated from `#/components/schemas/CompoundFilter/type`. + var _type: Components.Schemas.CompoundFilter._TypePayload + /// - Remark: Generated from `#/components/schemas/CompoundFilter/FiltersPayload`. + enum FiltersPayloadPayload: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/CompoundFilter/FiltersPayload/ComparisonFilter`. + case comparisonFilter(Components.Schemas.ComparisonFilter) + /// - Remark: Generated from `#/components/schemas/CompoundFilter/FiltersPayload/CompoundFilter`. + case compoundFilter(Components.Schemas.CompoundFilter) + public enum CodingKeys: String, CodingKey { + case _type = "type" + } + public init(from decoder: any Swift.Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + let discriminator = try container.decode( + Swift.String.self, + forKey: ._type + ) + switch discriminator { + case "ComparisonFilter", "#/components/schemas/ComparisonFilter", "eq", "ne", "gt", "gte", "lt", "lte", "in", "nin": + self = .comparisonFilter(try .init(from: decoder)) + case "CompoundFilter", "#/components/schemas/CompoundFilter", "and", "or": + self = .compoundFilter(try .init(from: decoder)) + default: + throw Swift.DecodingError.unknownOneOfDiscriminator( + discriminatorKey: CodingKeys._type, + discriminatorValue: discriminator, + codingPath: decoder.codingPath + ) + } + } + public func encode(to encoder: any Swift.Encoder) throws { + switch self { + case let .comparisonFilter(value): + try value.encode(to: encoder) + case let .compoundFilter(value): + try value.encode(to: encoder) + } + } + } + /// Array of filters to combine. Items can be `ComparisonFilter` or `CompoundFilter`. + /// + /// - Remark: Generated from `#/components/schemas/CompoundFilter/filters`. + typealias FiltersPayload = [Components.Schemas.CompoundFilter.FiltersPayloadPayload] + /// Array of filters to combine. Items can be `ComparisonFilter` or `CompoundFilter`. + /// + /// - Remark: Generated from `#/components/schemas/CompoundFilter/filters`. + var filters: Components.Schemas.CompoundFilter.FiltersPayload + init( + _type: Components.Schemas.CompoundFilter._TypePayload, + filters: Components.Schemas.CompoundFilter.FiltersPayload + ) { + self._type = _type + self.filters = filters + } + typealias CodingKeys = Components.Schemas.CompoundFilter.CodingKeys + init(from decoder: any Swift.Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + self._type = try container.decode( + Components.Schemas.CompoundFilter._TypePayload.self, + forKey: ._type + ) + self.filters = try container.decode( + Components.Schemas.CompoundFilter.FiltersPayload.self, + forKey: .filters + ) + try decoder.ensureNoAdditionalProperties(knownKeys: [ + "type", + "filters" + ]) + } } } /// - Remark: Generated from `#/components/schemas/ComputerAction`. @@ -596,7 +692,7 @@ public enum Components { /// /// - Remark: Generated from `#/components/schemas/ComputerScreenshotImage`. public struct ComputerScreenshotImage: Codable, Hashable, Sendable { - /// Specifies the event type. For a computer screenshot, this property is + /// Specifies the event type. For a computer screenshot, this property is /// always set to `computer_screenshot`. /// /// @@ -604,7 +700,7 @@ public enum Components { @frozen public enum _TypePayload: String, Codable, Hashable, Sendable, CaseIterable { case computerScreenshot = "computer_screenshot" } - /// Specifies the event type. For a computer screenshot, this property is + /// Specifies the event type. For a computer screenshot, this property is /// always set to `computer_screenshot`. /// /// @@ -621,7 +717,7 @@ public enum Components { /// Creates a new `ComputerScreenshotImage`. /// /// - Parameters: - /// - _type: Specifies the event type. For a computer screenshot, this property is + /// - _type: Specifies the event type. For a computer screenshot, this property is /// - imageUrl: The URL of the screenshot image. /// - fileId: The identifier of an uploaded file that contains the screenshot. public init( @@ -924,8 +1020,10 @@ public enum Components { public var value1: Components.Schemas.ModelResponseProperties /// - Remark: Generated from `#/components/schemas/CreateModelResponseProperties/value2`. public struct Value2Payload: Codable, Hashable, Sendable { - /// An integer between 0 and 20 specifying the number of most likely tokens to - /// return at each token position, each with an associated log probability. + /// An integer between 0 and 20 specifying the maximum number of most likely + /// tokens to return at each token position, each with an associated log + /// probability. In some cases, the number of returned tokens may be fewer than + /// requested. /// /// /// - Remark: Generated from `#/components/schemas/CreateModelResponseProperties/value2/top_logprobs`. @@ -933,7 +1031,7 @@ public enum Components { /// Creates a new `Value2Payload`. /// /// - Parameters: - /// - topLogprobs: An integer between 0 and 20 specifying the number of most likely tokens to + /// - topLogprobs: An integer between 0 and 20 specifying the maximum number of most likely public init(topLogprobs: Swift.Int? = nil) { self.topLogprobs = topLogprobs } @@ -1175,7 +1273,7 @@ public enum Components { case timestampGranularities(OpenAPIRuntime.MultipartPart) /// - Remark: Generated from `#/components/schemas/CreateTranscriptionRequest/chunking_strategy`. public struct ChunkingStrategyPayload: Sendable, Hashable { - /// Controls how the audio is cut into chunks. When set to `"auto"`, the server first normalizes loudness and then uses voice activity detection (VAD) to choose boundaries. `server_vad` object can be provided to tweak VAD detection parameters manually. If unset, the audio is transcribed as a single block. Required when using `gpt-4o-transcribe-diarize` for inputs longer than 30 seconds. + /// Controls how the audio is cut into chunks. When set to `"auto"`, the server first normalizes loudness and then uses voice activity detection (VAD) to choose boundaries. `server_vad` object can be provided to tweak VAD detection parameters manually. If unset, the audio is transcribed as a single block. Required when using `gpt-4o-transcribe-diarize` for inputs longer than 30 seconds. /// /// - Remark: Generated from `#/components/schemas/CreateTranscriptionRequest/chunking_strategy/content/body`. public struct BodyPayload: Codable, Hashable, Sendable { @@ -2285,7 +2383,7 @@ public enum Components { } } } - /// A tool call to run a function. See the + /// A tool call to run a function. See the /// [function calling guide](/docs/guides/function-calling) for more information. /// /// @@ -2732,20 +2830,63 @@ public enum Components { /// /// - Remark: Generated from `#/components/schemas/ImageGenTool/quality`. public var quality: Components.Schemas.ImageGenTool.QualityPayload? - /// The size of the generated image. One of `1024x1024`, `1024x1536`, - /// `1536x1024`, or `auto`. Default: `auto`. - /// + /// The size of the generated images. For `gpt-image-2` and `gpt-image-2-2026-04-21`, arbitrary resolutions are supported as `WIDTHxHEIGHT` strings, for example `1536x864`. Width and height must both be divisible by 16 and the requested aspect ratio must be between 1:3 and 3:1. Resolutions above `2560x1440` are experimental, and the maximum supported resolution is `3840x2160`. The requested size must also satisfy the model's current pixel and edge limits. The standard sizes `1024x1024`, `1536x1024`, and `1024x1536` are supported by the GPT image models; `auto` is supported for models that allow automatic sizing. For `dall-e-2`, use one of `256x256`, `512x512`, or `1024x1024`. For `dall-e-3`, use one of `1024x1024`, `1792x1024`, or `1024x1792`. /// /// - Remark: Generated from `#/components/schemas/ImageGenTool/size`. - @frozen public enum SizePayload: String, Codable, Hashable, Sendable, CaseIterable { - case _1024x1024 = "1024x1024" - case _1024x1536 = "1024x1536" - case _1536x1024 = "1536x1024" - case auto = "auto" + public struct SizePayload: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/ImageGenTool/size/value1`. + public var value1: Swift.String? + /// - Remark: Generated from `#/components/schemas/ImageGenTool/size/value2`. + @frozen public enum Value2Payload: String, Codable, Hashable, Sendable, CaseIterable { + case _1024x1024 = "1024x1024" + case _1024x1536 = "1024x1536" + case _1536x1024 = "1536x1024" + case auto = "auto" + } + /// - Remark: Generated from `#/components/schemas/ImageGenTool/size/value2`. + public var value2: Components.Schemas.ImageGenTool.SizePayload.Value2Payload? + /// Creates a new `SizePayload`. + /// + /// - Parameters: + /// - value1: + /// - value2: + public init( + value1: Swift.String? = nil, + value2: Components.Schemas.ImageGenTool.SizePayload.Value2Payload? = nil + ) { + self.value1 = value1 + self.value2 = value2 + } + public init(from decoder: any Swift.Decoder) throws { + var errors: [any Swift.Error] = [] + do { + self.value1 = try decoder.decodeFromSingleValueContainer() + } catch { + errors.append(error) + } + do { + self.value2 = try decoder.decodeFromSingleValueContainer() + } catch { + errors.append(error) + } + try Swift.DecodingError.verifyAtLeastOneSchemaIsNotNil( + [ + self.value1, + self.value2 + ], + type: Self.self, + codingPath: decoder.codingPath, + errors: errors + ) + } + public func encode(to encoder: any Swift.Encoder) throws { + try encoder.encodeFirstNonNilValueToSingleValueContainer([ + self.value1, + self.value2 + ]) + } } - /// The size of the generated image. One of `1024x1024`, `1024x1536`, - /// `1536x1024`, or `auto`. Default: `auto`. - /// + /// The size of the generated images. For `gpt-image-2` and `gpt-image-2-2026-04-21`, arbitrary resolutions are supported as `WIDTHxHEIGHT` strings, for example `1536x864`. Width and height must both be divisible by 16 and the requested aspect ratio must be between 1:3 and 3:1. Resolutions above `2560x1440` are experimental, and the maximum supported resolution is `3840x2160`. The requested size must also satisfy the model's current pixel and edge limits. The standard sizes `1024x1024`, `1536x1024`, and `1024x1536` are supported by the GPT image models; `auto` is supported for models that allow automatic sizing. For `dall-e-2`, use one of `256x256`, `512x512`, or `1024x1024`. For `dall-e-3`, use one of `1024x1024`, `1792x1024`, or `1024x1792`. /// /// - Remark: Generated from `#/components/schemas/ImageGenTool/size`. public var size: Components.Schemas.ImageGenTool.SizePayload? @@ -2873,7 +3014,7 @@ public enum Components { /// - _type: The type of the image generation tool. Always `image_generation`. /// - model: /// - quality: The quality of the generated image. One of `low`, `medium`, `high`, - /// - size: The size of the generated image. One of `1024x1024`, `1024x1536`, + /// - size: The size of the generated images. For `gpt-image-2` and `gpt-image-2-2026-04-21`, arbitrary resolutions are supported as `WIDTHxHEIGHT` strings, for example `1536x864`. Width and height must both be divisible by 16 and the requested aspect ratio must be between 1:3 and 3:1. Resolutions above `2560x1440` are experimental, and the maximum supported resolution is `3840x2160`. The requested size must also satisfy the model's current pixel and edge limits. The standard sizes `1024x1024`, `1536x1024`, and `1024x1536` are supported by the GPT image models; `auto` is supported for models that allow automatic sizing. For `dall-e-2`, use one of `256x256`, `512x512`, or `1024x1024`. For `dall-e-3`, use one of `1024x1024`, `1792x1024`, or `1024x1792`. /// - outputFormat: The output format of the generated image. One of `png`, `webp`, or /// - outputCompression: Compression level for the output image. Default: 100. /// - moderation: Moderation level for the generated image. Default: `auto`. @@ -3150,7 +3291,7 @@ public enum Components { case content } } - /// A list of one or many input items to the model, containing different content + /// A list of one or many input items to the model, containing different content /// types. /// /// @@ -4765,7 +4906,7 @@ public enum Components { /// /// - Remark: Generated from `#/components/schemas/ModelResponseProperties/prompt_cache_retention`. @frozen public enum PromptCacheRetentionPayload: String, Codable, Hashable, Sendable, CaseIterable { - case inMemory = "in-memory" + case inMemory = "in_memory" case _24h = "24h" } /// - Remark: Generated from `#/components/schemas/ModelResponseProperties/prompt_cache_retention`. @@ -5682,11 +5823,6 @@ public enum Components { /// /// - Remark: Generated from `#/components/schemas/ResponseAudioDoneEvent/type`. public var _type: Components.Schemas.ResponseAudioDoneEvent._TypePayload - /// The ID of the response. - /// - /// - /// - Remark: Generated from `#/components/schemas/ResponseAudioDoneEvent/response_id`. - public var responseId: Swift.String /// The sequence number of the delta. /// /// @@ -5696,20 +5832,16 @@ public enum Components { /// /// - Parameters: /// - _type: The type of the event. Always `response.audio.done`. - /// - responseId: The ID of the response. /// - sequenceNumber: The sequence number of the delta. public init( _type: Components.Schemas.ResponseAudioDoneEvent._TypePayload, - responseId: Swift.String, sequenceNumber: Swift.Int ) { self._type = _type - self.responseId = responseId self.sequenceNumber = sequenceNumber } public enum CodingKeys: String, CodingKey { case _type = "type" - case responseId = "response_id" case sequenceNumber = "sequence_number" } } @@ -5729,11 +5861,6 @@ public enum Components { /// /// - Remark: Generated from `#/components/schemas/ResponseAudioTranscriptDeltaEvent/type`. public var _type: Components.Schemas.ResponseAudioTranscriptDeltaEvent._TypePayload - /// The ID of the response. - /// - /// - /// - Remark: Generated from `#/components/schemas/ResponseAudioTranscriptDeltaEvent/response_id`. - public var responseId: Swift.String /// The partial transcript of the audio response. /// /// @@ -5747,23 +5874,19 @@ public enum Components { /// /// - Parameters: /// - _type: The type of the event. Always `response.audio.transcript.delta`. - /// - responseId: The ID of the response. /// - delta: The partial transcript of the audio response. /// - sequenceNumber: The sequence number of this event. public init( _type: Components.Schemas.ResponseAudioTranscriptDeltaEvent._TypePayload, - responseId: Swift.String, delta: Swift.String, sequenceNumber: Swift.Int ) { self._type = _type - self.responseId = responseId self.delta = delta self.sequenceNumber = sequenceNumber } public enum CodingKeys: String, CodingKey { case _type = "type" - case responseId = "response_id" case delta case sequenceNumber = "sequence_number" } @@ -5784,11 +5907,6 @@ public enum Components { /// /// - Remark: Generated from `#/components/schemas/ResponseAudioTranscriptDoneEvent/type`. public var _type: Components.Schemas.ResponseAudioTranscriptDoneEvent._TypePayload - /// The ID of the response. - /// - /// - /// - Remark: Generated from `#/components/schemas/ResponseAudioTranscriptDoneEvent/response_id`. - public var responseId: Swift.String /// The sequence number of this event. /// /// - Remark: Generated from `#/components/schemas/ResponseAudioTranscriptDoneEvent/sequence_number`. @@ -5797,20 +5915,16 @@ public enum Components { /// /// - Parameters: /// - _type: The type of the event. Always `response.audio.transcript.done`. - /// - responseId: The ID of the response. /// - sequenceNumber: The sequence number of this event. public init( _type: Components.Schemas.ResponseAudioTranscriptDoneEvent._TypePayload, - responseId: Swift.String, sequenceNumber: Swift.Int ) { self._type = _type - self.responseId = responseId self.sequenceNumber = sequenceNumber } public enum CodingKeys: String, CodingKey { case _type = "type" - case responseId = "response_id" case sequenceNumber = "sequence_number" } } @@ -6925,7 +7039,7 @@ public enum Components { /// The name of the function that was called. /// /// - Remark: Generated from `#/components/schemas/ResponseFunctionCallArgumentsDoneEvent/name`. - public var name: Swift.String? + public var name: Swift.String /// The index of the output item. /// /// - Remark: Generated from `#/components/schemas/ResponseFunctionCallArgumentsDoneEvent/output_index`. @@ -6950,7 +7064,7 @@ public enum Components { public init( _type: Components.Schemas.ResponseFunctionCallArgumentsDoneEvent._TypePayload, itemId: Swift.String, - name: Swift.String? = nil, + name: Swift.String, outputIndex: Swift.Int, sequenceNumber: Swift.Int, arguments: Swift.String @@ -7347,8 +7461,8 @@ public enum Components { case lastId = "last_id" } } - /// A logprob is the logarithmic probability that the model assigns to producing - /// a particular token at a given position in the sequence. Less-negative (higher) + /// A logprob is the logarithmic probability that the model assigns to producing + /// a particular token at a given position in the sequence. Less-negative (higher) /// logprob values indicate greater model confidence in that token choice. /// /// @@ -7390,12 +7504,12 @@ public enum Components { case logprob } } - /// The log probability of the top 20 most likely tokens. + /// The log probabilities of up to 20 of the most likely tokens. /// /// /// - Remark: Generated from `#/components/schemas/ResponseLogProb/top_logprobs`. public typealias TopLogprobsPayload = [Components.Schemas.ResponseLogProb.TopLogprobsPayloadPayload] - /// The log probability of the top 20 most likely tokens. + /// The log probabilities of up to 20 of the most likely tokens. /// /// /// - Remark: Generated from `#/components/schemas/ResponseLogProb/top_logprobs`. @@ -7405,7 +7519,7 @@ public enum Components { /// - Parameters: /// - token: A possible text token. /// - logprob: The log probability of this token. - /// - topLogprobs: The log probability of the top 20 most likely tokens. + /// - topLogprobs: The log probabilities of up to 20 of the most likely tokens. public init( token: Swift.String, logprob: Swift.Double, @@ -9812,7 +9926,7 @@ public enum Components { /// /// - Remark: Generated from `#/components/schemas/ResponseUsage/input_tokens_details`. public struct InputTokensDetailsPayload: Codable, Hashable, Sendable { - /// The number of tokens that were retrieved from the cache. + /// The number of tokens that were retrieved from the cache. /// [More on prompt caching](/docs/guides/prompt-caching). /// /// @@ -9821,7 +9935,7 @@ public enum Components { /// Creates a new `InputTokensDetailsPayload`. /// /// - Parameters: - /// - cachedTokens: The number of tokens that were retrieved from the cache. + /// - cachedTokens: The number of tokens that were retrieved from the cache. public init(cachedTokens: Swift.Int) { self.cachedTokens = cachedTokens } @@ -10077,8 +10191,8 @@ public enum Components { } /// An object specifying the format that the model must output. /// - /// Configuring `{ "type": "json_schema" }` enables Structured Outputs, - /// which ensures the model will match your supplied JSON schema. Learn more in the + /// Configuring `{ "type": "json_schema" }` enables Structured Outputs, + /// which ensures the model will match your supplied JSON schema. Learn more in the /// [Structured Outputs guide](/docs/guides/structured-outputs). /// /// The default format is `{ "type": "text" }` with no additional options. @@ -10946,11 +11060,11 @@ public enum Components { /// Start timestamp of the segment in seconds. /// /// - Remark: Generated from `#/components/schemas/TranscriptTextSegmentEvent/start`. - public var start: Swift.Float + public var start: Swift.Double /// End timestamp of the segment in seconds. /// /// - Remark: Generated from `#/components/schemas/TranscriptTextSegmentEvent/end`. - public var end: Swift.Float + public var end: Swift.Double /// Transcript text for this segment. /// /// - Remark: Generated from `#/components/schemas/TranscriptTextSegmentEvent/text`. @@ -10971,8 +11085,8 @@ public enum Components { public init( _type: Components.Schemas.TranscriptTextSegmentEvent._TypePayload, id: Swift.String, - start: Swift.Float, - end: Swift.Float, + start: Swift.Double, + end: Swift.Double, text: Swift.String, speaker: Swift.String ) { @@ -11138,11 +11252,11 @@ public enum Components { /// Start timestamp of the segment in seconds. /// /// - Remark: Generated from `#/components/schemas/TranscriptionDiarizedSegment/start`. - public var start: Swift.Float + public var start: Swift.Double /// End timestamp of the segment in seconds. /// /// - Remark: Generated from `#/components/schemas/TranscriptionDiarizedSegment/end`. - public var end: Swift.Float + public var end: Swift.Double /// Transcript text for this segment. /// /// - Remark: Generated from `#/components/schemas/TranscriptionDiarizedSegment/text`. @@ -11164,8 +11278,8 @@ public enum Components { public init( _type: Components.Schemas.TranscriptionDiarizedSegment._TypePayload, id: Swift.String, - start: Swift.Float, - end: Swift.Float, + start: Swift.Double, + end: Swift.Double, text: Swift.String, speaker: Swift.String ) { @@ -11202,11 +11316,11 @@ public enum Components { /// Start time of the segment in seconds. /// /// - Remark: Generated from `#/components/schemas/TranscriptionSegment/start`. - public var start: Swift.Float + public var start: Swift.Double /// End time of the segment in seconds. /// /// - Remark: Generated from `#/components/schemas/TranscriptionSegment/end`. - public var end: Swift.Float + public var end: Swift.Double /// Text content of the segment. /// /// - Remark: Generated from `#/components/schemas/TranscriptionSegment/text`. @@ -11247,8 +11361,8 @@ public enum Components { public init( id: Swift.Int, seek: Swift.Int, - start: Swift.Float, - end: Swift.Float, + start: Swift.Double, + end: Swift.Double, text: Swift.String, tokens: [Swift.Int], temperature: Swift.Float, @@ -11289,11 +11403,11 @@ public enum Components { /// Start time of the word in seconds. /// /// - Remark: Generated from `#/components/schemas/TranscriptionWord/start`. - public var start: Swift.Float + public var start: Swift.Double /// End time of the word in seconds. /// /// - Remark: Generated from `#/components/schemas/TranscriptionWord/end`. - public var end: Swift.Float + public var end: Swift.Double /// Creates a new `TranscriptionWord`. /// /// - Parameters: @@ -11302,8 +11416,8 @@ public enum Components { /// - end: End time of the word in seconds. public init( word: Swift.String, - start: Swift.Float, - end: Swift.Float + start: Swift.Double, + end: Swift.Double ) { self.word = word self.start = start @@ -11327,21 +11441,21 @@ public enum Components { /// /// - Remark: Generated from `#/components/schemas/VadConfig/type`. public var _type: Components.Schemas.VadConfig._TypePayload - /// Amount of audio to include before the VAD detected speech (in + /// Amount of audio to include before the VAD detected speech (in /// milliseconds). /// /// /// - Remark: Generated from `#/components/schemas/VadConfig/prefix_padding_ms`. public var prefixPaddingMs: Swift.Int? /// Duration of silence to detect speech stop (in milliseconds). - /// With shorter values the model will respond more quickly, + /// With shorter values the model will respond more quickly, /// but may jump in on short pauses from the user. /// /// /// - Remark: Generated from `#/components/schemas/VadConfig/silence_duration_ms`. public var silenceDurationMs: Swift.Int? - /// Sensitivity threshold (0.0 to 1.0) for voice activity detection. A - /// higher threshold will require louder audio to activate the model, and + /// Sensitivity threshold (0.0 to 1.0) for voice activity detection. A + /// higher threshold will require louder audio to activate the model, and /// thus might perform better in noisy environments. /// /// @@ -11351,9 +11465,9 @@ public enum Components { /// /// - Parameters: /// - _type: Must be set to `server_vad` to enable manual chunking using server side VAD. - /// - prefixPaddingMs: Amount of audio to include before the VAD detected speech (in + /// - prefixPaddingMs: Amount of audio to include before the VAD detected speech (in /// - silenceDurationMs: Duration of silence to detect speech stop (in milliseconds). - /// - threshold: Sensitivity threshold (0.0 to 1.0) for voice activity detection. A + /// - threshold: Sensitivity threshold (0.0 to 1.0) for voice activity detection. A public init( _type: Components.Schemas.VadConfig._TypePayload, prefixPaddingMs: Swift.Int? = nil, @@ -11588,7 +11702,7 @@ public enum Components { /// /// /// - Remark: Generated from `#/components/schemas/WebSearchActionSearch/query`. - public var query: Swift.String? + public var query: Swift.String /// The search queries. /// /// @@ -11652,7 +11766,7 @@ public enum Components { /// - sources: The sources used in the search. public init( _type: Components.Schemas.WebSearchActionSearch._TypePayload, - query: Swift.String? = nil, + query: Swift.String, queries: [Swift.String]? = nil, sources: Components.Schemas.WebSearchActionSearch.SourcesPayload? = nil ) { @@ -11720,7 +11834,7 @@ public enum Components { case timezone } } - /// High level guidance for the amount of context window space to use for the + /// High level guidance for the amount of context window space to use for the /// search. One of `low`, `medium`, or `high`. `medium` is the default. /// /// @@ -11734,7 +11848,7 @@ public enum Components { /// /// - Remark: Generated from `#/components/schemas/WebSearchLocation`. public struct WebSearchLocation: Codable, Hashable, Sendable { - /// The two-letter + /// The two-letter /// [ISO country code](https://en.wikipedia.org/wiki/ISO_3166-1) of the user, /// e.g. `US`. /// @@ -11751,7 +11865,7 @@ public enum Components { /// /// - Remark: Generated from `#/components/schemas/WebSearchLocation/city`. public var city: Swift.String? - /// The [IANA timezone](https://timeapi.io/documentation/iana-timezones) + /// The [IANA timezone](https://timeapi.io/documentation/iana-timezones) /// of the user, e.g. `America/Los_Angeles`. /// /// @@ -11760,10 +11874,10 @@ public enum Components { /// Creates a new `WebSearchLocation`. /// /// - Parameters: - /// - country: The two-letter + /// - country: The two-letter /// - region: Free text input for the region of the user, e.g. `California`. /// - city: Free text input for the city of the user, e.g. `San Francisco`. - /// - timezone: The [IANA timezone](https://timeapi.io/documentation/iana-timezones) + /// - timezone: The [IANA timezone](https://timeapi.io/documentation/iana-timezones) public init( country: Swift.String? = nil, region: Swift.String? = nil, @@ -12213,6 +12327,7 @@ public enum Components { } } /// Specify additional output data to include in the model response. Currently supported values are: + /// - `web_search_call.results`: Include the search results of the web search tool call. /// - `web_search_call.action.sources`: Include the sources of the web search tool call. /// - `code_interpreter_call.outputs`: Includes the outputs of python code execution in code interpreter tool call items. /// - `computer_call_output.output.image_url`: Include image urls from the computer call output. @@ -14988,8 +15103,8 @@ public enum Components { case maxOutputLength = "max_output_length" } } - /// - Remark: Generated from `#/components/schemas/LocalShellCallStatus`. - @frozen public enum LocalShellCallStatus: String, Codable, Hashable, Sendable, CaseIterable { + /// - Remark: Generated from `#/components/schemas/FunctionShellCallStatus`. + @frozen public enum FunctionShellCallStatus: String, Codable, Hashable, Sendable, CaseIterable { case inProgress = "in_progress" case completed = "completed" case incomplete = "incomplete" @@ -15081,7 +15196,7 @@ public enum Components { /// The status of the shell call. One of `in_progress`, `completed`, or `incomplete`. /// /// - Remark: Generated from `#/components/schemas/FunctionShellCall/status`. - public var status: Components.Schemas.LocalShellCallStatus + public var status: Components.Schemas.FunctionShellCallStatus /// - Remark: Generated from `#/components/schemas/FunctionShellCall/environment`. @frozen public enum EnvironmentPayload: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/FunctionShellCall/environment/LocalEnvironmentResource`. @@ -15140,7 +15255,7 @@ public enum Components { id: Swift.String, callId: Swift.String, action: Components.Schemas.FunctionShellAction, - status: Components.Schemas.LocalShellCallStatus, + status: Components.Schemas.FunctionShellCallStatus, environment: Components.Schemas.FunctionShellCall.EnvironmentPayload? = nil, createdBy: Swift.String? = nil ) { @@ -15162,8 +15277,8 @@ public enum Components { case createdBy = "created_by" } } - /// - Remark: Generated from `#/components/schemas/LocalShellCallOutputStatusEnum`. - @frozen public enum LocalShellCallOutputStatusEnum: String, Codable, Hashable, Sendable, CaseIterable { + /// - Remark: Generated from `#/components/schemas/FunctionShellCallOutputStatusEnum`. + @frozen public enum FunctionShellCallOutputStatusEnum: String, Codable, Hashable, Sendable, CaseIterable { case inProgress = "in_progress" case completed = "completed" case incomplete = "incomplete" @@ -15337,7 +15452,7 @@ public enum Components { /// The status of the shell call output. One of `in_progress`, `completed`, or `incomplete`. /// /// - Remark: Generated from `#/components/schemas/FunctionShellCallOutput/status`. - public var status: Components.Schemas.LocalShellCallOutputStatusEnum + public var status: Components.Schemas.FunctionShellCallOutputStatusEnum /// An array of shell call output contents /// /// - Remark: Generated from `#/components/schemas/FunctionShellCallOutput/output`. @@ -15362,7 +15477,7 @@ public enum Components { _type: Components.Schemas.FunctionShellCallOutput._TypePayload, id: Swift.String, callId: Swift.String, - status: Components.Schemas.LocalShellCallOutputStatusEnum, + status: Components.Schemas.FunctionShellCallOutputStatusEnum, output: [Components.Schemas.FunctionShellCallOutputContent], maxOutputLength: Swift.Int? = nil, createdBy: Swift.String? = nil diff --git a/Tests/OpenAITests/StreamingClientTests.swift b/Tests/OpenAITests/StreamingClientTests.swift index 273f0977..6f8c3557 100644 --- a/Tests/OpenAITests/StreamingClientTests.swift +++ b/Tests/OpenAITests/StreamingClientTests.swift @@ -57,7 +57,7 @@ struct StreamingClientTests { } @Test func interceptResponsesRequest() async throws { - mockSession.dataTask = try DataTaskMock.successfulJson(with: ResponseStreamEvent.audio(.done(.init(_type: .response_audio_done, responseId: "", sequenceNumber: 0)))) + mockSession.dataTask = try DataTaskMock.successfulJson(with: ResponseStreamEvent.audio(.done(.init(_type: .response_audio_done, sequenceNumber: 0)))) mockMiddleware.interceptRequestReturnValue = .init(url: interceptedURL) _ = client.performResponsesStreamingRequest( request: JSONRequest(url: originalURL), From e6987db95c0b166619f8a9e602c2568fafa20b8f Mon Sep 17 00:00:00 2001 From: nezhyborets Date: Fri, 19 Jun 2026 23:11:17 +0300 Subject: [PATCH 4/9] Handle colliding message discriminator --- Makefile | 7 +++ .../Public/Schemas/Generated/Components.swift | 23 ++++++++- Tests/OpenAITests/ItemCodingTests.swift | 51 +++++++++++++++++++ 3 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 Tests/OpenAITests/ItemCodingTests.swift diff --git a/Makefile b/Makefile index 5447002f..2c29177d 100644 --- a/Makefile +++ b/Makefile @@ -20,6 +20,13 @@ # local commit 33a4f7ccdc4adb577e20033562858ffc657a589a and corresponds to # https://github.com/openai/openai-openapi/issues/542. # +# - When inferred discriminator values collide across multiple oneOf schemas, +# fall back to structural decoding for the colliding value instead of +# generating duplicate switch patterns. The OpenAI spec uses `message` for +# both InputMessage and OutputMessage, so the discriminator alone cannot +# select the correct schema. This is implemented by local commit +# 052065978bacae66db746ee5565dc36bd434b413. +# # Expected diagnostic: # The generator warns that `InputMessageResource/value2` requires `type` even # though that property is declared by the sibling `InputMessage` schema in the diff --git a/Sources/OpenAI/Public/Schemas/Generated/Components.swift b/Sources/OpenAI/Public/Schemas/Generated/Components.swift index ab7d3388..075c0f87 100644 --- a/Sources/OpenAI/Public/Schemas/Generated/Components.swift +++ b/Sources/OpenAI/Public/Schemas/Generated/Components.swift @@ -3456,15 +3456,16 @@ public enum Components { case _type = "type" } public init(from decoder: any Swift.Decoder) throws { + var errors: [any Swift.Error] = [] let container = try decoder.container(keyedBy: CodingKeys.self) let discriminator = try container.decode( Swift.String.self, forKey: ._type ) switch discriminator { - case "InputMessage", "#/components/schemas/InputMessage", "message": + case "InputMessage", "#/components/schemas/InputMessage": self = .inputMessage(try .init(from: decoder)) - case "OutputMessage", "#/components/schemas/OutputMessage", "message": + case "OutputMessage", "#/components/schemas/OutputMessage": self = .outputMessage(try .init(from: decoder)) case "FileSearchToolCall", "#/components/schemas/FileSearchToolCall", "file_search_call": self = .fileSearchToolCall(try .init(from: decoder)) @@ -3514,6 +3515,24 @@ public enum Components { self = .customToolCallOutput(try .init(from: decoder)) case "CustomToolCall", "#/components/schemas/CustomToolCall", "custom_tool_call": self = .customToolCall(try .init(from: decoder)) + case "message": + do { + self = .inputMessage(try .init(from: decoder)) + return + } catch { + errors.append(error) + } + do { + self = .outputMessage(try .init(from: decoder)) + return + } catch { + errors.append(error) + } + throw Swift.DecodingError.failedToDecodeOneOfSchema( + type: Self.self, + codingPath: decoder.codingPath, + errors: errors + ) default: throw Swift.DecodingError.unknownOneOfDiscriminator( discriminatorKey: CodingKeys._type, diff --git a/Tests/OpenAITests/ItemCodingTests.swift b/Tests/OpenAITests/ItemCodingTests.swift new file mode 100644 index 00000000..ff6fe0f3 --- /dev/null +++ b/Tests/OpenAITests/ItemCodingTests.swift @@ -0,0 +1,51 @@ +import Foundation +import Testing +@testable import OpenAI + +struct ItemCodingTests { + @Test func messageWithUserRoleDecodesAsInputMessage() throws { + let item = try decode( + """ + { + "type": "message", + "role": "user", + "content": [] + } + """ + ) + + #expect(item.isInputMessage) + } + + @Test func messageWithAssistantRoleAndOutputFieldsDecodesAsOutputMessage() throws { + let item = try decode( + """ + { + "id": "msg_123", + "type": "message", + "role": "assistant", + "content": [], + "status": "completed" + } + """ + ) + + #expect(item.isOutputMessage) + } + + private func decode(_ json: String) throws -> Components.Schemas.Item { + try JSONDecoder().decode(Components.Schemas.Item.self, from: Data(json.utf8)) + } +} + +private extension Components.Schemas.Item { + var isInputMessage: Bool { + if case .inputMessage = self { return true } + return false + } + + var isOutputMessage: Bool { + if case .outputMessage = self { return true } + return false + } +} From 0937f5714cff47d226190f595dc09d7ce9f20ed8 Mon Sep 17 00:00:00 2001 From: nezhyborets Date: Fri, 19 Jun 2026 23:13:13 +0300 Subject: [PATCH 5/9] Document generator changes without local hashes --- Makefile | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 2c29177d..d6ab3146 100644 --- a/Makefile +++ b/Makefile @@ -10,22 +10,19 @@ # branch while assigning the Swift type, then make the resulting type # optional. Without this change, nullable properties are unsupported or are # generated as an anyOf wrapper instead of the expected optional Swift type. -# This is implemented by local commit fe49fc3f7e17b255012ab11925f53863e4972933. # # - When a oneOf discriminator has no explicit mapping, also match the string # enum values declared by the referenced schemas' discriminator property. # The OpenAI spec uses runtime values such as `input_text`, which do not match # schema names such as `InputTextContent`; without this change, decoding a -# valid response throws unknownOneOfDiscriminator. This is implemented by -# local commit 33a4f7ccdc4adb577e20033562858ffc657a589a and corresponds to -# https://github.com/openai/openai-openapi/issues/542. +# valid response throws unknownOneOfDiscriminator. See +# https://github.com/openai/openai-openapi/issues/542 for the spec issue. # # - When inferred discriminator values collide across multiple oneOf schemas, # fall back to structural decoding for the colliding value instead of # generating duplicate switch patterns. The OpenAI spec uses `message` for # both InputMessage and OutputMessage, so the discriminator alone cannot -# select the correct schema. This is implemented by local commit -# 052065978bacae66db746ee5565dc36bd434b413. +# select the correct schema. # # Expected diagnostic: # The generator warns that `InputMessageResource/value2` requires `type` even From b475feb5aa4cba543a5090bfe47a169945c4394e Mon Sep 17 00:00:00 2001 From: nezhyborets Date: Sat, 20 Jun 2026 23:50:07 +0300 Subject: [PATCH 6/9] Fix web search action decoding --- Makefile | 9 +++++++ Scripts/remove_required_properties.py | 9 +++---- .../Public/Schemas/Generated/Components.swift | 4 +-- Tests/OpenAITests/ItemCodingTests.swift | 26 +++++++++++++++++++ 4 files changed, 40 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index d6ab3146..3da5f244 100644 --- a/Makefile +++ b/Makefile @@ -45,6 +45,14 @@ generate: python3 -B "$(PROJECT_DIR)/Scripts/prepare_openapi.py" \ "$(PROJECT_DIR)/openapi.yaml" \ "$(PREPARED_OPENAPI)" + # The LocalShellToolCallOutput, MCP approval response, and response audio + # event removals are required-list entries without matching schema properties. + # They otherwise produce swift-openapi-generator warnings that the names are + # likely typos and will be skipped. + # + # WebSearchActionSearch/query is different: the property is declared, but the + # live API can omit the deprecated singular query and return queries instead. + # It must be optional so valid web-search response items decode successfully. python3 -B "$(PROJECT_DIR)/Scripts/remove_required_properties.py" \ "$(PREPARED_OPENAPI)" \ "$(PREPARED_OPENAPI)" \ @@ -54,6 +62,7 @@ generate: --remove-required "ResponseAudioDoneEvent" "response_id" \ --remove-required "ResponseAudioTranscriptDeltaEvent" "response_id" \ --remove-required "ResponseAudioTranscriptDoneEvent" "response_id" \ + --remove-required "WebSearchActionSearch" "query" \ --diff-source "$(PROJECT_DIR)/openapi.yaml" \ --diff-output "$(OPENAPI_DIFF)" cd "$(GENERATOR_DIR)" && swift run swift-openapi-generator generate \ diff --git a/Scripts/remove_required_properties.py b/Scripts/remove_required_properties.py index 3d2995e1..277ae554 100644 --- a/Scripts/remove_required_properties.py +++ b/Scripts/remove_required_properties.py @@ -1,14 +1,11 @@ #!/usr/bin/env python3 """Remove selected component properties from OpenAPI `required` lists. -Some upstream component schemas contain stale names in their `required` lists: -the named property is not present in the schema's `properties` map and is not -part of the corresponding types generated by the official OpenAI SDKs. - Pass each removal as two arguments: `SchemaName property_name`. Every requested schema, schema-level `required` list, and property entry must exist exactly once. This strictness makes an upstream schema change visible instead of -silently applying the workaround in the wrong place. +silently applying the transformation in the wrong place. The caller is +responsible for documenting why each removal is needed. """ from __future__ import annotations @@ -139,7 +136,7 @@ def main() -> None: args.output.write_text(fixed_document, encoding="utf-8") removed = ", ".join(removal.description for removal in removals) - print(f"Stale required properties workaround applied: removed {removed}.") + print(f"Required properties workaround applied: removed {removed}.") if args.diff_source is not None and args.diff_output is not None: original_document = args.diff_source.read_text(encoding="utf-8") diff --git a/Sources/OpenAI/Public/Schemas/Generated/Components.swift b/Sources/OpenAI/Public/Schemas/Generated/Components.swift index 075c0f87..7148cc6e 100644 --- a/Sources/OpenAI/Public/Schemas/Generated/Components.swift +++ b/Sources/OpenAI/Public/Schemas/Generated/Components.swift @@ -11721,7 +11721,7 @@ public enum Components { /// /// /// - Remark: Generated from `#/components/schemas/WebSearchActionSearch/query`. - public var query: Swift.String + public var query: Swift.String? /// The search queries. /// /// @@ -11785,7 +11785,7 @@ public enum Components { /// - sources: The sources used in the search. public init( _type: Components.Schemas.WebSearchActionSearch._TypePayload, - query: Swift.String, + query: Swift.String? = nil, queries: [Swift.String]? = nil, sources: Components.Schemas.WebSearchActionSearch.SourcesPayload? = nil ) { diff --git a/Tests/OpenAITests/ItemCodingTests.swift b/Tests/OpenAITests/ItemCodingTests.swift index ff6fe0f3..05bd1935 100644 --- a/Tests/OpenAITests/ItemCodingTests.swift +++ b/Tests/OpenAITests/ItemCodingTests.swift @@ -33,6 +33,24 @@ struct ItemCodingTests { #expect(item.isOutputMessage) } + @Test func webSearchActionWithQueriesDecodesWhenDeprecatedQueryIsMissing() throws { + let item = try decode( + """ + { + "id": "ws_123", + "type": "web_search_call", + "status": "completed", + "action": { + "type": "search", + "queries": ["baseball in Ukraine"] + } + } + """ + ) + + #expect(item.webSearchQueries == ["baseball in Ukraine"]) + } + private func decode(_ json: String) throws -> Components.Schemas.Item { try JSONDecoder().decode(Components.Schemas.Item.self, from: Data(json.utf8)) } @@ -48,4 +66,12 @@ private extension Components.Schemas.Item { if case .outputMessage = self { return true } return false } + + var webSearchQueries: [String]? { + guard case let .webSearchToolCall(call) = self, + case let .webSearchActionSearch(action) = call.action else { + return nil + } + return action.queries + } } From b3d418f34994eeed34f56e26fdea36412474b75e Mon Sep 17 00:00:00 2001 From: nezhyborets Date: Sat, 20 Jun 2026 23:50:38 +0300 Subject: [PATCH 7/9] Add print for easier debugging --- .../Streaming/ModelResponseEventsStreamInterpreter.swift | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Sources/OpenAI/Private/Streaming/ModelResponseEventsStreamInterpreter.swift b/Sources/OpenAI/Private/Streaming/ModelResponseEventsStreamInterpreter.swift index e6cd9b95..4d891c19 100644 --- a/Sources/OpenAI/Private/Streaming/ModelResponseEventsStreamInterpreter.swift +++ b/Sources/OpenAI/Private/Streaming/ModelResponseEventsStreamInterpreter.swift @@ -68,8 +68,13 @@ final class ModelResponseEventsStreamInterpreter: @unchecked Sendable, StreamInt throw InterpreterError.unknownEventType(eventType) } - let responseStreamEvent = try responseStreamEvent(modelResponseEventType: modelResponseEventType, data: event.data) - onEventDispatched?(responseStreamEvent) + do { + let responseStreamEvent = try responseStreamEvent(modelResponseEventType: modelResponseEventType, data: event.data) + onEventDispatched?(responseStreamEvent) + } catch { + print("Decoding failed for modelResponseEventType: \(modelResponseEventType), String(data: event.data, encoding: .utf8): \(String(data: event.data, encoding: .utf8))") + throw error + } } private func processError(_ error: Error) { From a7a2f91d09f61bf5c3bd574c361129d62a913a3c Mon Sep 17 00:00:00 2001 From: nezhyborets Date: Sun, 21 Jun 2026 00:03:41 +0300 Subject: [PATCH 8/9] Fix non-streaming web search responses --- Demo/DemoChat/Sources/ResponsesStore.swift | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Demo/DemoChat/Sources/ResponsesStore.swift b/Demo/DemoChat/Sources/ResponsesStore.swift index 68156094..df059321 100644 --- a/Demo/DemoChat/Sources/ResponsesStore.swift +++ b/Demo/DemoChat/Sources/ResponsesStore.swift @@ -485,7 +485,15 @@ public final class ResponsesStore: ObservableObject { ) ) case .functionToolCall(let functionToolCall): + guard functionToolCall.name == weatherFunctionTool.name else { + throw StoreError.unknownFunctionCalled(name: functionToolCall.name) + } + lastFinishedFunctionToolCall = functionToolCall + case .webSearchToolCall: + // The non-streaming response includes the completed web-search call + // alongside the assistant message. There is no incremental state to update. + webSearchInProgress = false default: throw StoreError.unhandledOutputItem(output) } From 16f718020a096d54e692c5976d28c424dd2931db Mon Sep 17 00:00:00 2001 From: nezhyborets Date: Sun, 21 Jun 2026 00:16:46 +0300 Subject: [PATCH 9/9] docs: update code generation guide --- CONTRIBUTING.md | 117 +++++++++++++++++++++++++----------------------- 1 file changed, 62 insertions(+), 55 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1b63da2a..cf53c9ea 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,65 +31,72 @@ We'll appreciate you including tests to your code if it is needed and possible. ## Implementing an API -> Using Code generation in this project is a bit nuanced. For small additions and edits it is OK to write everything manually. For larger changes consider asking a maintaner to implement the wanted piece. Read on if you'd like to implement larger parts and you're ok to dig into the nits-and-bits of the approach. +There are two ways to add or change an API in this project: write the required +methods and types by hand, or use the OpenAPI specification to generate the +supporting types. Code generation is especially useful for a large API with many +nested schemas, but it is not a requirement for every change. -Currently there are 2 ways we can implement or edit an API: -1. By implementing all the needed methods and types ourselves manually. -2. By generating Types and using them in the code we write. - -Before attempting the Code Generation, see if the spec contains what you need: -1. When a need to implement a new API arises - check if it's implemented in [openai-openapi](https://github.com/openai/openai-openapi)*. For an easier exploration use [Swagger Editor](https://editor.swagger.io) to browse `OpenAPI Specification` file and see if the needed Types are described there (yes, it may not be there, it may take time for OpenAI to update the spec). -2. If the Paths and Types required for implementation are not in the spec file - [implement everything by hand](#implementing-by-hand). -3. If the spec contains what's needed - proceed to [generate the code](#implementing-using-code-generation). - -> * [openai-openapi](https://github.com/openai/openai-openapi) repo may not contain the latest spec. Try checking `.stats.yml` of an official OpenAI SDK like [openai-python](https://github.com/openai/openai-python) or [openai-node](https://github.com/openai/openai-node), it may contain a more up-to-date spec. - -#### Pros and cons of using Code Generation - -##### + Implementation speed - -It's super fast to implement a large API like Responses API using Code Generation. Even though top-level types of the API are hand-crafted, they use so many smaller generated types, it would take very long to implement myself. - -##### + The generated types are structured - -OpenAPI spec is provided by OpenAPI - it has all the insights on the DB scheme used by OpenAI. It may contain insights about the schemes future which we, as an outside developers, may not be able to see. - -For example, a generated `EasyInputMessage` type is used in both `Responses` and `Evals` APIs. - -##### - OpenAI lags behind - -OpenAI doesn't update the OpenAPI spec too frequently, which may lead to a nede to extract a generated type. - -##### - Generated code is not "beautiful" - -There are drawbacks in the looks of the generated code, like enums have upper case etc., which may lead to a desire to extract a type to make the code look more user friendly. +Start by checking the repository's [`openapi.yaml`](openapi.yaml). A tool such as +[Swagger Editor](https://editor.swagger.io) can make the document easier to +explore. If it describes the paths and schemas you need, use the generation +workflow below. If it does not, implement the missing API by hand rather than +editing the generated file. See [openai-openapi](https://github.com/openai/openai-openapi) for the latest spec. ### Implementing by hand -Implementing by hand is straightforward. See `ChatQuery`, `ChatResult` and their dependant types for an example. +See `ChatQuery`, `ChatResult`, and their dependent types for examples. Handwritten +top-level types are often preferable because they let us present a focused Swift +API with carefully written documentation. Generated types can still supply the +larger collection of nested schemas behind that API. ### Implementing using Code Generation -#### What we generate and what we don't -1. Currently the only thing we generate is Types. I.e. we don't generate API methods. So for example, during implementing `Responses API` I didn't generate `ResponsesEndpoint` file and its `createResponse` and `createResponseStreaming` methods. -2. This is optional, but I haven't used generated types at the top level. In the `Reponses API` example, the 3 main (top level) types are `CreateModelResponseQuery`, `ResponseObject` and `ResponseStreamEvent`. They are all written by hand to make the API and documentation comments look good and full. What's generated are the types they depend on. `CreateModelResponseQuery` depends on `Schemas.Includable`, `ResponseObject` depends on `Schemas.ResponseError` and so on. - -#### How to generate Types -1. Use [Swift OpenAPI Generator](https://github.com/apple/swift-openapi-generator) to generate the code using OpenAI's OpenAPI spec file. See comments at the top of `Components.swift` on the configuration that was used for the last generation, append your configs to that so that a new generation doesn't miss something out. I used CLI to generate the files outside of the project folder and then just copied the generated code into the project. -2. When you've got `Types.swift` generated - copy only the `Components` enum into `/Sources/OpenAI/Public/Schemas/Generated/Components.swift`. Replace the existing enum. See comments at the top of `Components.swift` file (section "Manual operations after Types.swift file was generated") for any operations that have to be done manually after the generated code is in place. If you need to edit anything manually in `Components` enum - note it in the mentioned section. -3. Use the types from `Components.Schemas` as you need. - -#### What to do if a Generated Type is incomplete -Let's say you've [come across an issue](https://github.com/MacPaw/OpenAI/issues/347) when a generated Types has missing fields, and the latest OpenAI-OpenAPI spec still doesn't have it implemented. Consider the constraints: - -1. We can't wait for them to update the spec, we don't even know if they are going to. -2. We don't want to edit `Components.swift`, as we want to keep it easily replacable with new generations. - -So, this is a case where we would [extract a type](#extracting-a-generated-type). - -#### Extracting a generated Type -If for any reason a generated Type doesn't meet your needs - you can always just extract it and edit, or just write a type manually. - -If a type is a direct edit or extension of a type - put it into `Sources/OpenAI/Public/Schemas/Edited/`. It is preferred to keep the name and the structure of a file so that when OpenAPI spec is updated we could removed the edited file and use a generated code. - -If the new type is not part of OpenAI provided spec - just name it the way you think right and put it into another folder. See `Sources/OpenAI/Public/Schemas/Facade/` for examples, where new types are introduced facading the generated code to make the Responses API in Swift more friendly. \ No newline at end of file +Generation produces types only. API methods, endpoints, and the public top-level +models that wrap those types remain handwritten. For example, the Responses API +uses handwritten `CreateModelResponseQuery`, `ResponseObject`, and +`ResponseStreamEvent` types, while their supporting schemas come from +`Components.Schemas`. + +The workflow is automated by [`make generate`](Makefile). The Makefile is the +source of truth for prerequisites and the exact commands; in particular, it +documents the required sibling checkout of the project's Swift OpenAPI Generator +fork and the generator changes that fork must contain. + +Before running generation, update +[`openapi-generator-config.yaml`](openapi-generator-config.yaml) with every path +and standalone schema the change needs. Then run: + +```sh +make generate +``` + +The command: + +1. prepares a generator-compatible copy of `openapi.yaml` under `.build/`; +2. applies the narrowly scoped workarounds documented in [`Scripts/`](Scripts/); +3. runs Swift OpenAPI Generator with the repository's configuration; and +4. extracts the generated `Components` enum into + `Sources/OpenAI/Public/Schemas/Generated/Components.swift` while preserving + that file's imports and header. + +The source specification is not modified during this process. The final +preparation diff is written to `.build/openapi-generator/openapi.patch`; review +it along with the generated Swift diff. Build the package and run the relevant +tests before submitting the change. + +Do not edit `Components.swift` by hand. It is deliberately replaceable output, +so a later generation would discard such edits. + +#### When a generated type is not suitable + +The specification can lag behind the live API, and generated types are not +always the best public Swift interface. If a generated type is incomplete or +awkward, extract or recreate it as a handwritten type instead of patching the +generated file. + +Put a direct replacement or adaptation in +`Sources/OpenAI/Public/Schemas/Edited/`. Keep its name and structure close to the +generated schema where practical so it can be replaced again when the upstream +specification catches up. Types that are not part of the specification belong in +an appropriate handwritten area; `Sources/OpenAI/Public/Schemas/Facade/` +contains examples that provide a friendlier API over generated schemas.