diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 29a759eb4..8088f7a36 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "6.48.0"
+ ".": "6.49.0"
}
diff --git a/.stats.yml b/.stats.yml
index 6cf2e1841..382c79283 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 271
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai/openai-8ed7dcb0d163e7f5205dbe172d6ad5b7ce367b23c20629830e39a0aee920a029.yml
-openapi_spec_hash: 011cdae0c67909fb80a4a5eb54ca5bca
-config_hash: 896f0f71bc7d1ee09435813cdef97523
+configured_endpoints: 277
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai/openai-0650ebae454b4200491980d7663cb7ceabcff90dcb3ed9f67c3bca3e861a2bf6.yml
+openapi_spec_hash: e9576bced964246b7e685a5ad30afffa
+config_hash: 43e311595bcc4fb6b32eba0684de48d8
diff --git a/CHANGELOG.md b/CHANGELOG.md
index bc3a3fc55..e8257549f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,37 @@
# Changelog
+## 6.49.0 (2026-07-23)
+
+Full Changelog: [v6.48.0...v6.49.0](https://github.com/openai/openai-node/compare/v6.48.0...v6.49.0)
+
+### Features
+
+* **api:** accept `None` for prompt_cache_key/safety_identifier ([c54a7f3](https://github.com/openai/openai-node/commit/c54a7f3b01760b705ebca1e88738fb649187ffe0))
+* **api:** add support for `spend_limit` admin apis ([e8238b0](https://github.com/openai/openai-node/commit/e8238b085de715dbf0c0cb64e7e6207314b12954))
+* **helpers:** add standard schema support ([#1997](https://github.com/openai/openai-node/issues/1997)) ([4ced1a8](https://github.com/openai/openai-node/commit/4ced1a8eaba3f5e960b94090a75e8048f7642439))
+* **helpers:** add zod realtime function helper ([#1996](https://github.com/openai/openai-node/issues/1996)) ([ee59911](https://github.com/openai/openai-node/commit/ee59911804fa56e1bcac01a127108b63a7cd28e5))
+* **stlc:** configurable CI runner and private-production-repo support in workflow templates ([967a66b](https://github.com/openai/openai-node/commit/967a66b2349c5ce5d45fbe902287f121d6b3cf64))
+* **zod:** support schema definitions ([#1993](https://github.com/openai/openai-node/issues/1993)) ([eb04567](https://github.com/openai/openai-node/commit/eb04567313c6296b80fc3c47306ee96b9c34456f))
+
+
+### Bug Fixes
+
+* address code scanning findings ([#2007](https://github.com/openai/openai-node/issues/2007)) ([2706888](https://github.com/openai/openai-node/commit/2706888499a777b47d851aeb479f846f80932765))
+* address remaining Dependabot alerts ([#2005](https://github.com/openai/openai-node/issues/2005)) ([6ab3428](https://github.com/openai/openai-node/commit/6ab34285f02d6e9fb4eb1779fca13e51d1be3e10))
+* **azure:** normalize endpoint trailing slashes ([#1995](https://github.com/openai/openai-node/issues/1995)) ([39a15b4](https://github.com/openai/openai-node/commit/39a15b412fc129df15339ebd6e3e6547854aa81f))
+* **ci:** restore explicit TypeScript SDK runner selection ([fe79401](https://github.com/openai/openai-node/commit/fe79401763f192a2705204c7235c21b036fdb238))
+* **runTools:** sanitize replayed messages ([#1990](https://github.com/openai/openai-node/issues/1990)) ([a60cc25](https://github.com/openai/openai-node/commit/a60cc250d4c442bae25e05c67c6bd30d18fc87e6))
+* **stream:** handle audio completion markers ([#1991](https://github.com/openai/openai-node/issues/1991)) ([bd86817](https://github.com/openai/openai-node/commit/bd86817ea0c9ebe233f30d80c9b98b80a8b30be1))
+* **zod:** escape schema definition refs before strict validation ([bff2b10](https://github.com/openai/openai-node/commit/bff2b104f53fde6d620327790a8a5cb6dfd5ff0c))
+* **zod:** infer parsed tool callback arguments ([#1992](https://github.com/openai/openai-node/issues/1992)) ([83cdb79](https://github.com/openai/openai-node/commit/83cdb79e62c24dbf0cd27d893c8b792dadf6bcf8))
+* **zod:** preserve schema types while escaping refs ([cb7e195](https://github.com/openai/openai-node/commit/cb7e19539160d71b381a7e2ff6c98fe4981c52eb))
+
+
+### Chores
+
+* exclude Brewfile from language detection ([#2006](https://github.com/openai/openai-node/issues/2006)) ([9bec333](https://github.com/openai/openai-node/commit/9bec3332133c115b0e728010ab614daf5516e35b))
+* refresh more ecosystem test dependencies ([#2003](https://github.com/openai/openai-node/issues/2003)) ([3cafa55](https://github.com/openai/openai-node/commit/3cafa553aeb7f10e9afb432ae5d4aaa1c6d42663))
+
## 6.48.0 (2026-07-17)
Full Changelog: [v6.47.0...v6.48.0](https://github.com/openai/openai-node/compare/v6.47.0...v6.48.0)
diff --git a/api.md b/api.md
index 0f2d45aae..43f9bba8c 100644
--- a/api.md
+++ b/api.md
@@ -956,6 +956,19 @@ Methods:
- client.admin.organization.dataRetention.retrieve() -> OrganizationDataRetention
- client.admin.organization.dataRetention.update({ ...params }) -> OrganizationDataRetention
+### SpendLimit
+
+Types:
+
+- OrganizationSpendLimit
+- OrganizationSpendLimitDeleted
+
+Methods:
+
+- client.admin.organization.spendLimit.retrieve() -> OrganizationSpendLimit
+- client.admin.organization.spendLimit.update({ ...params }) -> OrganizationSpendLimit
+- client.admin.organization.spendLimit.delete() -> OrganizationSpendLimitDeleted
+
### SpendAlerts
Types:
@@ -1165,6 +1178,19 @@ Methods:
- client.admin.organization.projects.dataRetention.retrieve(projectID) -> ProjectDataRetention
- client.admin.organization.projects.dataRetention.update(projectID, { ...params }) -> ProjectDataRetention
+#### SpendLimit
+
+Types:
+
+- ProjectSpendLimit
+- ProjectSpendLimitDeleted
+
+Methods:
+
+- client.admin.organization.projects.spendLimit.retrieve(projectID) -> ProjectSpendLimit
+- client.admin.organization.projects.spendLimit.update(projectID, { ...params }) -> ProjectSpendLimit
+- client.admin.organization.projects.spendLimit.delete(projectID) -> ProjectSpendLimitDeleted
+
#### SpendAlerts
Types:
diff --git a/jsr.json b/jsr.json
index 947c933dd..ebc053eff 100644
--- a/jsr.json
+++ b/jsr.json
@@ -1,6 +1,6 @@
{
"name": "@openai/openai",
- "version": "6.48.0",
+ "version": "6.49.0",
"exports": {
".": "./index.ts",
"./providers/bedrock": "./providers/bedrock.ts",
diff --git a/package.json b/package.json
index 9383ad69f..24a023d5e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "openai",
- "version": "6.48.0",
+ "version": "6.49.0",
"description": "The official TypeScript library for the OpenAI API",
"author": "OpenAI ",
"types": "dist/index.d.ts",
diff --git a/scripts/detect-breaking-changes b/scripts/detect-breaking-changes
index 990a14b39..9a21c01e4 100755
--- a/scripts/detect-breaking-changes
+++ b/scripts/detect-breaking-changes
@@ -58,6 +58,7 @@ TEST_PATHS=(
tests/api-resources/admin/organization/groups/roles.test.ts
tests/api-resources/admin/organization/roles.test.ts
tests/api-resources/admin/organization/data-retention.test.ts
+ tests/api-resources/admin/organization/spend-limit.test.ts
tests/api-resources/admin/organization/spend-alerts.test.ts
tests/api-resources/admin/organization/certificates.test.ts
tests/api-resources/admin/organization/projects/projects.test.ts
@@ -73,6 +74,7 @@ TEST_PATHS=(
tests/api-resources/admin/organization/projects/groups/roles.test.ts
tests/api-resources/admin/organization/projects/roles.test.ts
tests/api-resources/admin/organization/projects/data-retention.test.ts
+ tests/api-resources/admin/organization/projects/spend-limit.test.ts
tests/api-resources/admin/organization/projects/spend-alerts.test.ts
tests/api-resources/admin/organization/projects/certificates.test.ts
tests/api-resources/responses/responses.test.ts
diff --git a/src/helpers/zod.ts b/src/helpers/zod.ts
index 07036d127..55ab0e3ff 100644
--- a/src/helpers/zod.ts
+++ b/src/helpers/zod.ts
@@ -58,10 +58,10 @@ function validateSchemaDefinitions(schemaDefinitions: ZodSchemaDefinitions | und
}
}
-function escapeSchemaDefinitionRefs(
- schema: Record,
+function escapeSchemaDefinitionRefs(
+ schema: T,
schemaDefinitions: ZodSchemaDefinitions | undefined,
-): Record {
+): T {
const refReplacements = new Map(
Object.keys(schemaDefinitions ?? {}).map((name) => [
`#/definitions/${name}`,
@@ -126,30 +126,30 @@ function zodV4ToJsonSchema(
metadata?.add(definition as unknown as z4.ZodType, { id: name });
}
- const jsonSchema = toStrictJsonSchema(
- z4.toJSONSchema(schema, {
- target: 'draft-7',
- ...(metadata ? { metadata } : undefined),
- override: ({ zodSchema, jsonSchema }) => {
- const def = zodSchema._zod.def;
-
- if (def.type === 'union' && 'discriminator' in def && Array.isArray(jsonSchema.oneOf)) {
- if (jsonSchema.anyOf !== undefined) {
- throw new Error(
- 'Zod discriminated union generated both `anyOf` and `oneOf`, which cannot be represented in an OpenAI strict schema',
- );
- }
-
- // Discriminator values are mutually exclusive, so anyOf preserves the
- // union while staying inside the API's supported JSON Schema subset.
- jsonSchema.anyOf = jsonSchema.oneOf;
- delete jsonSchema.oneOf;
+ const jsonSchema = z4.toJSONSchema(schema, {
+ target: 'draft-7',
+ ...(metadata ? { metadata } : undefined),
+ override: ({ zodSchema, jsonSchema }) => {
+ const def = zodSchema._zod.def;
+
+ if (def.type === 'union' && 'discriminator' in def && Array.isArray(jsonSchema.oneOf)) {
+ if (jsonSchema.anyOf !== undefined) {
+ throw new Error(
+ 'Zod discriminated union generated both `anyOf` and `oneOf`, which cannot be represented in an OpenAI strict schema',
+ );
}
- },
- }) as JSONSchema,
- ) as Record;
- return escapeSchemaDefinitionRefs(jsonSchema, options.schemaDefinitions);
+ // Discriminator values are mutually exclusive, so anyOf preserves the
+ // union while staying inside the API's supported JSON Schema subset.
+ jsonSchema.anyOf = jsonSchema.oneOf;
+ delete jsonSchema.oneOf;
+ }
+ },
+ }) as JSONSchema;
+
+ const escapedSchema = escapeSchemaDefinitionRefs(jsonSchema, options.schemaDefinitions);
+
+ return toStrictJsonSchema(escapedSchema) as Record;
}
function zodV3ToNonStrictJsonSchema(schema: z3.ZodType, options: { name: string }): Record {
diff --git a/src/resources/admin/organization/index.ts b/src/resources/admin/organization/index.ts
index 8450870f2..b113beb48 100644
--- a/src/resources/admin/organization/index.ts
+++ b/src/resources/admin/organization/index.ts
@@ -82,6 +82,12 @@ export {
type SpendAlertListParams,
type OrganizationSpendAlertsPage,
} from './spend-alerts';
+export {
+ SpendLimit,
+ type OrganizationSpendLimit,
+ type OrganizationSpendLimitDeleted,
+ type SpendLimitUpdateParams,
+} from './spend-limit';
export {
Usage,
type UsageAudioSpeechesResponse,
diff --git a/src/resources/admin/organization/organization.ts b/src/resources/admin/organization/organization.ts
index 1ffb53507..1cde6a13d 100644
--- a/src/resources/admin/organization/organization.ts
+++ b/src/resources/admin/organization/organization.ts
@@ -62,6 +62,13 @@ import {
SpendAlertUpdateParams,
SpendAlerts,
} from './spend-alerts';
+import * as SpendLimitAPI from './spend-limit';
+import {
+ OrganizationSpendLimit,
+ OrganizationSpendLimitDeleted,
+ SpendLimit,
+ SpendLimitUpdateParams,
+} from './spend-limit';
import * as UsageAPI from './usage';
import {
Usage,
@@ -127,6 +134,7 @@ export class Organization extends APIResource {
groups: GroupsAPI.Groups = new GroupsAPI.Groups(this._client);
roles: RolesAPI.Roles = new RolesAPI.Roles(this._client);
dataRetention: DataRetentionAPI.DataRetention = new DataRetentionAPI.DataRetention(this._client);
+ spendLimit: SpendLimitAPI.SpendLimit = new SpendLimitAPI.SpendLimit(this._client);
spendAlerts: SpendAlertsAPI.SpendAlerts = new SpendAlertsAPI.SpendAlerts(this._client);
certificates: CertificatesAPI.Certificates = new CertificatesAPI.Certificates(this._client);
projects: ProjectsAPI.Projects = new ProjectsAPI.Projects(this._client);
@@ -140,6 +148,7 @@ Organization.Users = Users;
Organization.Groups = Groups;
Organization.Roles = Roles;
Organization.DataRetention = DataRetention;
+Organization.SpendLimit = SpendLimit;
Organization.SpendAlerts = SpendAlerts;
Organization.Certificates = Certificates;
Organization.Projects = Projects;
@@ -233,6 +242,13 @@ export declare namespace Organization {
type DataRetentionUpdateParams as DataRetentionUpdateParams,
};
+ export {
+ SpendLimit as SpendLimit,
+ type OrganizationSpendLimit as OrganizationSpendLimit,
+ type OrganizationSpendLimitDeleted as OrganizationSpendLimitDeleted,
+ type SpendLimitUpdateParams as SpendLimitUpdateParams,
+ };
+
export {
SpendAlerts as SpendAlerts,
type OrganizationSpendAlert as OrganizationSpendAlert,
diff --git a/src/resources/admin/organization/projects/index.ts b/src/resources/admin/organization/projects/index.ts
index fe5e3fc79..35c59bd75 100644
--- a/src/resources/admin/organization/projects/index.ts
+++ b/src/resources/admin/organization/projects/index.ts
@@ -90,6 +90,12 @@ export {
type SpendAlertDeleteParams,
type ProjectSpendAlertsPage,
} from './spend-alerts';
+export {
+ SpendLimit,
+ type ProjectSpendLimit,
+ type ProjectSpendLimitDeleted,
+ type SpendLimitUpdateParams,
+} from './spend-limit';
export {
Users,
type ProjectUser,
diff --git a/src/resources/admin/organization/projects/projects.ts b/src/resources/admin/organization/projects/projects.ts
index bea6aafdf..b1e68b51f 100644
--- a/src/resources/admin/organization/projects/projects.ts
+++ b/src/resources/admin/organization/projects/projects.ts
@@ -69,6 +69,13 @@ import {
SpendAlertUpdateParams,
SpendAlerts,
} from './spend-alerts';
+import * as SpendLimitAPI from './spend-limit';
+import {
+ ProjectSpendLimit,
+ ProjectSpendLimitDeleted,
+ SpendLimit,
+ SpendLimitUpdateParams,
+} from './spend-limit';
import * as GroupsAPI from './groups/groups';
import {
GroupCreateParams,
@@ -127,6 +134,7 @@ export class Projects extends APIResource {
groups: GroupsAPI.Groups = new GroupsAPI.Groups(this._client);
roles: RolesAPI.Roles = new RolesAPI.Roles(this._client);
dataRetention: DataRetentionAPI.DataRetention = new DataRetentionAPI.DataRetention(this._client);
+ spendLimit: SpendLimitAPI.SpendLimit = new SpendLimitAPI.SpendLimit(this._client);
spendAlerts: SpendAlertsAPI.SpendAlerts = new SpendAlertsAPI.SpendAlerts(this._client);
certificates: CertificatesAPI.Certificates = new CertificatesAPI.Certificates(this._client);
@@ -325,6 +333,7 @@ Projects.HostedToolPermissions = HostedToolPermissions;
Projects.Groups = Groups;
Projects.Roles = Roles;
Projects.DataRetention = DataRetention;
+Projects.SpendLimit = SpendLimit;
Projects.SpendAlerts = SpendAlerts;
Projects.Certificates = Certificates;
@@ -420,6 +429,13 @@ export declare namespace Projects {
type DataRetentionUpdateParams as DataRetentionUpdateParams,
};
+ export {
+ SpendLimit as SpendLimit,
+ type ProjectSpendLimit as ProjectSpendLimit,
+ type ProjectSpendLimitDeleted as ProjectSpendLimitDeleted,
+ type SpendLimitUpdateParams as SpendLimitUpdateParams,
+ };
+
export {
SpendAlerts as SpendAlerts,
type ProjectSpendAlert as ProjectSpendAlert,
diff --git a/src/resources/admin/organization/projects/spend-limit.ts b/src/resources/admin/organization/projects/spend-limit.ts
new file mode 100644
index 000000000..895793e8e
--- /dev/null
+++ b/src/resources/admin/organization/projects/spend-limit.ts
@@ -0,0 +1,156 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../../../../core/resource';
+import { APIPromise } from '../../../../core/api-promise';
+import { RequestOptions } from '../../../../internal/request-options';
+import { path } from '../../../../internal/utils/path';
+
+export class SpendLimit extends APIResource {
+ /**
+ * Get a project's hard spend limit.
+ *
+ * @example
+ * ```ts
+ * const projectSpendLimit =
+ * await client.admin.organization.projects.spendLimit.retrieve(
+ * 'proj_123',
+ * );
+ * ```
+ */
+ retrieve(projectID: string, options?: RequestOptions): APIPromise {
+ return this._client.get(path`/organization/projects/${projectID}/spend_limit`, {
+ ...options,
+ __security: { adminAPIKeyAuth: true },
+ });
+ }
+
+ /**
+ * Create or replace a project's hard spend limit.
+ *
+ * @example
+ * ```ts
+ * const projectSpendLimit =
+ * await client.admin.organization.projects.spendLimit.update(
+ * 'proj_123',
+ * {
+ * currency: 'USD',
+ * interval: 'month',
+ * threshold_amount: 1,
+ * },
+ * );
+ * ```
+ */
+ update(
+ projectID: string,
+ body: SpendLimitUpdateParams,
+ options?: RequestOptions,
+ ): APIPromise {
+ return this._client.post(path`/organization/projects/${projectID}/spend_limit`, {
+ body,
+ ...options,
+ __security: { adminAPIKeyAuth: true },
+ });
+ }
+
+ /**
+ * Delete a project's hard spend limit.
+ *
+ * @example
+ * ```ts
+ * const projectSpendLimitDeleted =
+ * await client.admin.organization.projects.spendLimit.delete(
+ * 'proj_123',
+ * );
+ * ```
+ */
+ delete(projectID: string, options?: RequestOptions): APIPromise {
+ return this._client.delete(path`/organization/projects/${projectID}/spend_limit`, {
+ ...options,
+ __security: { adminAPIKeyAuth: true },
+ });
+ }
+}
+
+/**
+ * Represents a hard spend limit configured at the project level.
+ */
+export interface ProjectSpendLimit {
+ /**
+ * The currency for the threshold amount. Currently, only `USD` is supported.
+ */
+ currency: (string & {}) | 'USD';
+
+ /**
+ * The current enforcement state of the hard spend limit.
+ */
+ enforcement: ProjectSpendLimit.Enforcement;
+
+ /**
+ * The time interval for evaluating spend against the threshold. Currently, only
+ * `month` is supported.
+ */
+ interval: (string & {}) | 'month';
+
+ /**
+ * The object type, which is always `project.spend_limit`.
+ */
+ object: 'project.spend_limit';
+
+ /**
+ * The hard spend limit amount, in cents.
+ */
+ threshold_amount: number;
+}
+
+export namespace ProjectSpendLimit {
+ /**
+ * The current enforcement state of the hard spend limit.
+ */
+ export interface Enforcement {
+ /**
+ * Whether the hard spend limit is currently enforcing.
+ */
+ status: (string & {}) | 'inactive' | 'enforcing';
+ }
+}
+
+/**
+ * Confirmation payload returned after deleting a project hard spend limit.
+ */
+export interface ProjectSpendLimitDeleted {
+ /**
+ * Whether the hard spend limit was deleted.
+ */
+ deleted: boolean;
+
+ /**
+ * The object type, which is always `project.spend_limit.deleted`.
+ */
+ object: 'project.spend_limit.deleted';
+}
+
+export interface SpendLimitUpdateParams {
+ /**
+ * The currency for the threshold amount. Currently, only `USD` is supported.
+ */
+ currency: 'USD';
+
+ /**
+ * The time interval for evaluating spend against the threshold. Currently, only
+ * `month` is supported.
+ */
+ interval: 'month';
+
+ /**
+ * The hard spend limit amount, in cents.
+ */
+ threshold_amount: number;
+}
+
+export declare namespace SpendLimit {
+ export {
+ type ProjectSpendLimit as ProjectSpendLimit,
+ type ProjectSpendLimitDeleted as ProjectSpendLimitDeleted,
+ type SpendLimitUpdateParams as SpendLimitUpdateParams,
+ };
+}
diff --git a/src/resources/admin/organization/spend-limit.ts b/src/resources/admin/organization/spend-limit.ts
new file mode 100644
index 000000000..422420bbc
--- /dev/null
+++ b/src/resources/admin/organization/spend-limit.ts
@@ -0,0 +1,144 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../../../core/resource';
+import { APIPromise } from '../../../core/api-promise';
+import { RequestOptions } from '../../../internal/request-options';
+
+export class SpendLimit extends APIResource {
+ /**
+ * Get the organization's hard spend limit.
+ *
+ * @example
+ * ```ts
+ * const organizationSpendLimit =
+ * await client.admin.organization.spendLimit.retrieve();
+ * ```
+ */
+ retrieve(options?: RequestOptions): APIPromise {
+ return this._client.get('/organization/spend_limit', {
+ ...options,
+ __security: { adminAPIKeyAuth: true },
+ });
+ }
+
+ /**
+ * Create or replace the organization's hard spend limit.
+ *
+ * @example
+ * ```ts
+ * const organizationSpendLimit =
+ * await client.admin.organization.spendLimit.update({
+ * currency: 'USD',
+ * interval: 'month',
+ * threshold_amount: 1,
+ * });
+ * ```
+ */
+ update(body: SpendLimitUpdateParams, options?: RequestOptions): APIPromise {
+ return this._client.post('/organization/spend_limit', {
+ body,
+ ...options,
+ __security: { adminAPIKeyAuth: true },
+ });
+ }
+
+ /**
+ * Delete the organization's hard spend limit.
+ *
+ * @example
+ * ```ts
+ * const organizationSpendLimitDeleted =
+ * await client.admin.organization.spendLimit.delete();
+ * ```
+ */
+ delete(options?: RequestOptions): APIPromise {
+ return this._client.delete('/organization/spend_limit', {
+ ...options,
+ __security: { adminAPIKeyAuth: true },
+ });
+ }
+}
+
+/**
+ * Represents a hard spend limit configured at the organization level.
+ */
+export interface OrganizationSpendLimit {
+ /**
+ * The currency for the threshold amount. Currently, only `USD` is supported.
+ */
+ currency: (string & {}) | 'USD';
+
+ /**
+ * The current enforcement state of the hard spend limit.
+ */
+ enforcement: OrganizationSpendLimit.Enforcement;
+
+ /**
+ * The time interval for evaluating spend against the threshold. Currently, only
+ * `month` is supported.
+ */
+ interval: (string & {}) | 'month';
+
+ /**
+ * The object type, which is always `organization.spend_limit`.
+ */
+ object: 'organization.spend_limit';
+
+ /**
+ * The hard spend limit amount, in cents.
+ */
+ threshold_amount: number;
+}
+
+export namespace OrganizationSpendLimit {
+ /**
+ * The current enforcement state of the hard spend limit.
+ */
+ export interface Enforcement {
+ /**
+ * Whether the hard spend limit is currently enforcing.
+ */
+ status: (string & {}) | 'inactive' | 'enforcing';
+ }
+}
+
+/**
+ * Confirmation payload returned after deleting an organization hard spend limit.
+ */
+export interface OrganizationSpendLimitDeleted {
+ /**
+ * Whether the hard spend limit was deleted.
+ */
+ deleted: boolean;
+
+ /**
+ * The object type, which is always `organization.spend_limit.deleted`.
+ */
+ object: 'organization.spend_limit.deleted';
+}
+
+export interface SpendLimitUpdateParams {
+ /**
+ * The currency for the threshold amount. Currently, only `USD` is supported.
+ */
+ currency: 'USD';
+
+ /**
+ * The time interval for evaluating spend against the threshold. Currently, only
+ * `month` is supported.
+ */
+ interval: 'month';
+
+ /**
+ * The hard spend limit amount, in cents.
+ */
+ threshold_amount: number;
+}
+
+export declare namespace SpendLimit {
+ export {
+ type OrganizationSpendLimit as OrganizationSpendLimit,
+ type OrganizationSpendLimitDeleted as OrganizationSpendLimitDeleted,
+ type SpendLimitUpdateParams as SpendLimitUpdateParams,
+ };
+}
diff --git a/src/resources/beta/responses/input-tokens.ts b/src/resources/beta/responses/input-tokens.ts
index 3c971c0a6..3e73fea7d 100644
--- a/src/resources/beta/responses/input-tokens.ts
+++ b/src/resources/beta/responses/input-tokens.ts
@@ -153,7 +153,10 @@ export namespace InputTokenCountParams {
*/
export interface Reasoning {
/**
- * Controls which reasoning items are rendered back to the model on later turns.
+ * Controls which reasoning items are rendered back to the model on later turns. If
+ * omitted or set to `auto`, the model determines the context mode. The `gpt-5.6`
+ * model family defaults to `all_turns`; earlier models default to `current_turn`.
+ *
* When returned on a response, this is the effective reasoning context mode used
* for the response.
*/
@@ -224,7 +227,8 @@ export namespace InputTokenCountParams {
/**
* Constrains the verbosity of the model's response. Lower values will result in
* more concise responses, while higher values will result in more verbose
- * responses. Currently supported values are `low`, `medium`, and `high`.
+ * responses. Currently supported values are `low`, `medium`, and `high`. The
+ * default is `medium`.
*/
verbosity?: 'low' | 'medium' | 'high' | null;
}
diff --git a/src/resources/beta/responses/responses.ts b/src/resources/beta/responses/responses.ts
index 54e15a7c8..44e8f7a7e 100644
--- a/src/resources/beta/responses/responses.ts
+++ b/src/resources/beta/responses/responses.ts
@@ -1330,7 +1330,7 @@ export interface BetaResponse {
* hit rates. Replaces the `user` field.
* [Learn more](https://platform.openai.com/docs/guides/prompt-caching).
*/
- prompt_cache_key?: string;
+ prompt_cache_key?: string | null;
/**
* The prompt-caching options that were applied to the response. Supported for
@@ -1375,7 +1375,7 @@ export interface BetaResponse {
* identifying information.
* [Learn more](https://platform.openai.com/docs/guides/safety-best-practices#safety-identifiers).
*/
- safety_identifier?: string;
+ safety_identifier?: string | null;
/**
* Specifies the processing type used for serving the request.
@@ -1632,7 +1632,10 @@ export namespace BetaResponse {
*/
export interface Reasoning {
/**
- * Controls which reasoning items are rendered back to the model on later turns.
+ * Controls which reasoning items are rendered back to the model on later turns. If
+ * omitted or set to `auto`, the model determines the context mode. The `gpt-5.6`
+ * model family defaults to `all_turns`; earlier models default to `current_turn`.
+ *
* When returned on a response, this is the effective reasoning context mode used
* for the response.
*/
@@ -3124,6 +3127,7 @@ export interface BetaResponseError {
| 'server_error'
| 'rate_limit_exceeded'
| 'invalid_prompt'
+ | 'data_residency_mismatch'
| 'bio_policy'
| 'vector_store_timeout'
| 'invalid_image'
@@ -9611,7 +9615,8 @@ export interface BetaResponseTextConfig {
/**
* Constrains the verbosity of the model's response. Lower values will result in
* more concise responses, while higher values will result in more verbose
- * responses. Currently supported values are `low`, `medium`, and `high`.
+ * responses. Currently supported values are `low`, `medium`, and `high`. The
+ * default is `medium`.
*/
verbosity?: 'low' | 'medium' | 'high' | null;
}
@@ -10392,7 +10397,7 @@ export namespace BetaResponsesClientEvent {
* hit rates. Replaces the `user` field.
* [Learn more](https://platform.openai.com/docs/guides/prompt-caching).
*/
- prompt_cache_key?: string;
+ prompt_cache_key?: string | null;
/**
* Options for prompt caching. Supported for `gpt-5.6` and later models. By
@@ -10444,7 +10449,7 @@ export namespace BetaResponsesClientEvent {
* identifying information.
* [Learn more](https://platform.openai.com/docs/guides/safety-best-practices#safety-identifiers).
*/
- safety_identifier?: string;
+ safety_identifier?: string | null;
/**
* Specifies the processing type used for serving the request.
@@ -10700,7 +10705,10 @@ export namespace BetaResponsesClientEvent {
*/
export interface Reasoning {
/**
- * Controls which reasoning items are rendered back to the model on later turns.
+ * Controls which reasoning items are rendered back to the model on later turns. If
+ * omitted or set to `auto`, the model determines the context mode. The `gpt-5.6`
+ * model family defaults to `all_turns`; earlier models default to `current_turn`.
+ *
* When returned on a response, this is the effective reasoning context mode used
* for the response.
*/
@@ -11761,7 +11769,7 @@ export interface ResponseCreateParamsBase {
* your cache hit rates. Replaces the `user` field.
* [Learn more](https://platform.openai.com/docs/guides/prompt-caching).
*/
- prompt_cache_key?: string;
+ prompt_cache_key?: string | null;
/**
* Body param: Options for prompt caching. Supported for `gpt-5.6` and later
@@ -11814,7 +11822,7 @@ export interface ResponseCreateParamsBase {
* any identifying information.
* [Learn more](https://platform.openai.com/docs/guides/safety-best-practices#safety-identifiers).
*/
- safety_identifier?: string;
+ safety_identifier?: string | null;
/**
* Body param: Specifies the processing type used for serving the request.
@@ -12079,7 +12087,10 @@ export namespace ResponseCreateParams {
*/
export interface Reasoning {
/**
- * Controls which reasoning items are rendered back to the model on later turns.
+ * Controls which reasoning items are rendered back to the model on later turns. If
+ * omitted or set to `auto`, the model determines the context mode. The `gpt-5.6`
+ * model family defaults to `all_turns`; earlier models default to `current_turn`.
+ *
* When returned on a response, this is the effective reasoning context mode used
* for the response.
*/
diff --git a/src/resources/chat/completions/completions.ts b/src/resources/chat/completions/completions.ts
index 648570638..1ad2f7286 100644
--- a/src/resources/chat/completions/completions.ts
+++ b/src/resources/chat/completions/completions.ts
@@ -2178,7 +2178,7 @@ export interface ChatCompletionCreateParamsBase {
* hit rates. Replaces the `user` field.
* [Learn more](https://platform.openai.com/docs/guides/prompt-caching).
*/
- prompt_cache_key?: string;
+ prompt_cache_key?: string | null;
/**
* Options for prompt caching. Supported for `gpt-5.6` and later models. By
@@ -2249,7 +2249,7 @@ export interface ChatCompletionCreateParamsBase {
* identifying information.
* [Learn more](https://platform.openai.com/docs/guides/safety-best-practices#safety-identifiers).
*/
- safety_identifier?: string;
+ safety_identifier?: string | null;
/**
* @deprecated This feature is in Beta. If specified, our system will make a best
@@ -2372,7 +2372,8 @@ export interface ChatCompletionCreateParamsBase {
/**
* Constrains the verbosity of the model's response. Lower values will result in
* more concise responses, while higher values will result in more verbose
- * responses. Currently supported values are `low`, `medium`, and `high`.
+ * responses. Currently supported values are `low`, `medium`, and `high`. The
+ * default is `medium`.
*/
verbosity?: 'low' | 'medium' | 'high' | null;
diff --git a/src/resources/responses/input-tokens.ts b/src/resources/responses/input-tokens.ts
index 38fff3772..b50244f50 100644
--- a/src/resources/responses/input-tokens.ts
+++ b/src/resources/responses/input-tokens.ts
@@ -163,7 +163,8 @@ export namespace InputTokenCountParams {
/**
* Constrains the verbosity of the model's response. Lower values will result in
* more concise responses, while higher values will result in more verbose
- * responses. Currently supported values are `low`, `medium`, and `high`.
+ * responses. Currently supported values are `low`, `medium`, and `high`. The
+ * default is `medium`.
*/
verbosity?: 'low' | 'medium' | 'high' | null;
}
diff --git a/src/resources/responses/responses.ts b/src/resources/responses/responses.ts
index f598cf9da..32bd8e248 100644
--- a/src/resources/responses/responses.ts
+++ b/src/resources/responses/responses.ts
@@ -1172,7 +1172,7 @@ export interface Response {
* hit rates. Replaces the `user` field.
* [Learn more](https://platform.openai.com/docs/guides/prompt-caching).
*/
- prompt_cache_key?: string;
+ prompt_cache_key?: string | null;
/**
* The prompt-caching options that were applied to the response. Supported for
@@ -1217,7 +1217,7 @@ export interface Response {
* identifying information.
* [Learn more](https://platform.openai.com/docs/guides/safety-best-practices#safety-identifiers).
*/
- safety_identifier?: string;
+ safety_identifier?: string | null;
/**
* Specifies the latency tier to use for processing the request. This parameter is
@@ -2753,6 +2753,7 @@ export interface ResponseError {
| 'server_error'
| 'rate_limit_exceeded'
| 'invalid_prompt'
+ | 'data_residency_mismatch'
| 'bio_policy'
| 'vector_store_timeout'
| 'invalid_image'
@@ -6955,7 +6956,8 @@ export interface ResponseTextConfig {
/**
* Constrains the verbosity of the model's response. Lower values will result in
* more concise responses, while higher values will result in more verbose
- * responses. Currently supported values are `low`, `medium`, and `high`.
+ * responses. Currently supported values are `low`, `medium`, and `high`. The
+ * default is `medium`.
*/
verbosity?: 'low' | 'medium' | 'high' | null;
}
@@ -7488,7 +7490,7 @@ export interface ResponsesClientEvent {
* hit rates. Replaces the `user` field.
* [Learn more](https://platform.openai.com/docs/guides/prompt-caching).
*/
- prompt_cache_key?: string;
+ prompt_cache_key?: string | null;
/**
* Options for prompt caching. Supported for `gpt-5.6` and later models. By
@@ -7540,7 +7542,7 @@ export interface ResponsesClientEvent {
* identifying information.
* [Learn more](https://platform.openai.com/docs/guides/safety-best-practices#safety-identifiers).
*/
- safety_identifier?: string;
+ safety_identifier?: string | null;
/**
* Specifies the processing type used for serving the request.
@@ -8677,7 +8679,7 @@ export interface ResponseCreateParamsBase {
* hit rates. Replaces the `user` field.
* [Learn more](https://platform.openai.com/docs/guides/prompt-caching).
*/
- prompt_cache_key?: string;
+ prompt_cache_key?: string | null;
/**
* Options for prompt caching. Supported for `gpt-5.6` and later models. By
@@ -8729,7 +8731,7 @@ export interface ResponseCreateParamsBase {
* identifying information.
* [Learn more](https://platform.openai.com/docs/guides/safety-best-practices#safety-identifiers).
*/
- safety_identifier?: string;
+ safety_identifier?: string | null;
/**
* Specifies the latency tier to use for processing the request. This parameter is
diff --git a/src/resources/shared.ts b/src/resources/shared.ts
index 8628b7f5a..7a0c88cc3 100644
--- a/src/resources/shared.ts
+++ b/src/resources/shared.ts
@@ -261,7 +261,10 @@ export type OAuthErrorCode = 'invalid_grant' | 'invalid_subject_token' | (string
*/
export interface Reasoning {
/**
- * Controls which reasoning items are rendered back to the model on later turns.
+ * Controls which reasoning items are rendered back to the model on later turns. If
+ * omitted or set to `auto`, the model determines the context mode. The `gpt-5.6`
+ * model family defaults to `all_turns`; earlier models default to `current_turn`.
+ *
* When returned on a response, this is the effective reasoning context mode used
* for the response.
*/
diff --git a/src/version.ts b/src/version.ts
index b0bceb2f9..c9f525192 100644
--- a/src/version.ts
+++ b/src/version.ts
@@ -1 +1 @@
-export const VERSION = '6.48.0'; // x-release-please-version
+export const VERSION = '6.49.0'; // x-release-please-version
diff --git a/tests/api-resources/admin/organization/projects/spend-limit.test.ts b/tests/api-resources/admin/organization/projects/spend-limit.test.ts
new file mode 100644
index 000000000..a332a5a12
--- /dev/null
+++ b/tests/api-resources/admin/organization/projects/spend-limit.test.ts
@@ -0,0 +1,56 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import OpenAI from 'openai';
+
+const client = new OpenAI({
+ apiKey: 'My API Key',
+ adminAPIKey: 'My Admin API Key',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+describe('resource spendLimit', () => {
+ test('retrieve', async () => {
+ const responsePromise = client.admin.organization.projects.spendLimit.retrieve('proj_123');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('update: only required params', async () => {
+ const responsePromise = client.admin.organization.projects.spendLimit.update('proj_123', {
+ currency: 'USD',
+ interval: 'month',
+ threshold_amount: 1,
+ });
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('update: required and optional params', async () => {
+ const response = await client.admin.organization.projects.spendLimit.update('proj_123', {
+ currency: 'USD',
+ interval: 'month',
+ threshold_amount: 1,
+ });
+ });
+
+ test('delete', async () => {
+ const responsePromise = client.admin.organization.projects.spendLimit.delete('proj_123');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+});
diff --git a/tests/api-resources/admin/organization/spend-limit.test.ts b/tests/api-resources/admin/organization/spend-limit.test.ts
new file mode 100644
index 000000000..3c0192bc2
--- /dev/null
+++ b/tests/api-resources/admin/organization/spend-limit.test.ts
@@ -0,0 +1,56 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import OpenAI from 'openai';
+
+const client = new OpenAI({
+ apiKey: 'My API Key',
+ adminAPIKey: 'My Admin API Key',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+describe('resource spendLimit', () => {
+ test('retrieve', async () => {
+ const responsePromise = client.admin.organization.spendLimit.retrieve();
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('update: only required params', async () => {
+ const responsePromise = client.admin.organization.spendLimit.update({
+ currency: 'USD',
+ interval: 'month',
+ threshold_amount: 1,
+ });
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('update: required and optional params', async () => {
+ const response = await client.admin.organization.spendLimit.update({
+ currency: 'USD',
+ interval: 'month',
+ threshold_amount: 1,
+ });
+ });
+
+ test('delete', async () => {
+ const responsePromise = client.admin.organization.spendLimit.delete();
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+});