driftwatch

OpenAI

21 spec versions tracked, back to 2026-09-28. 47 published breaking changes. Provider docs.

OpenAI2026-09-29 · c25ff3f01 breaking11 additive
  • Breakingdirection flipresponse.enum.value-added

    value can now return "gpt-6.1-sol"

    Producer-side tools call this additive. It breaks exhaustive switches, strict parsers and generated client enums.

    can now return "gpt-6.1-sol"

    2 places: BetaModelIdsShared, ModelIdsShared
    switch (response) {
      // existing branches …
      // no branch for "gpt-6.1-sol"
      default:
        throw new Error("unexpected value");
    }

Additive3 new response fieldsEnvironmentResourceOpenaiHosted.container_size, EnvironmentResourceOpenaiHosted.desktop, EnvironmentTemplateResource.desktop

Additive8 new request propertiesNetworkPolicyParam.blocked_domains, CreateEnvironmentTemplateParams.network.blocked_domains, CreateEnvironmentTemplateParams.desktop, EnvironmentParamOpenaiHosted.network.blocked_domains, EnvironmentParamOpenaiHosted.container_size, EnvironmentParamOpenaiHosted.desktop, UpdateEnvironmentTemplateParams.network.blocked_domains, UpdateEnvironmentTemplateParams.desktop

OpenAI2026-09-28 · b6059fc73 additive
  • Additiveresponse.property.type-narrowed

    Response type narrowed

    A tighter guarantee, not a break. Every value you can receive now was already possible, so existing handling still covers it; a null check here may now be dead code.

    ChatCompletionResponseMessage.function_call · reachable from 4 operations
  • Additiveresponse.property.type-narrowed

    Response type narrowed

    A tighter guarantee, not a break. Every value you can receive now was already possible, so existing handling still covers it; a null check here may now be dead code.

    ChatCompletionList.first_id · reachable from 1 operation
  • Additiveresponse.property.type-narrowed

    Response type narrowed

    A tighter guarantee, not a break. Every value you can receive now was already possible, so existing handling still covers it; a null check here may now be dead code.

    ChatCompletionList.last_id · reachable from 1 operation
OpenAI2026-09-28 · 14b6495c4 breaking
  • Breakingdirection flipresponse.property.became-optional

    Response field noise_reduction is no longer guaranteed

    Producer-side tools call this non-breaking. For a consumer it is a null dereference on an unknown future date.

    can now be null

    3 places: RealtimeSessionCreateResponse.audio.input.noise_reduction, RealtimeSessionCreateResponseGA.audio.input.noise_reduction, RealtimeTranscriptionSessionCreateResponseGA.audio.input.noise_reduction
    // response.audio.input.noise_reduction may now be absent or null
    const noise_reduction = response.audio.input.noise_reduction ?? fallback;
  • Breakingdirection flipresponse.property.became-optional

    Response field turn_detection is no longer guaranteed

    Producer-side tools call this non-breaking. For a consumer it is a null dereference on an unknown future date.

    can now be null

    2 places: RealtimeSessionCreateResponse.audio.input.turn_detection, RealtimeSessionCreateResponse.turn_detection
    // response.audio.input.turn_detection may now be absent or null
    const turn_detection = response.audio.input.turn_detection ?? fallback;
  • Breakingdirection flipresponse.property.became-optional

    Response field include is no longer guaranteed

    Producer-side tools call this non-breaking. For a consumer it is a null dereference on an unknown future date.

    can now be null

    2 places: RealtimeSessionCreateResponseGA.include, RealtimeTranscriptionSessionCreateResponseGA.include
    // response.include may now be absent or null
    const include = response.include ?? fallback;
  • Breakingdirection flipresponse.property.became-optional

    Response field language is no longer guaranteed

    Producer-side tools call this non-breaking. For a consumer it is a null dereference on an unknown future date.

    AudioTranscriptionResponse.language · reachable from 3 operations
    // response.language may now be absent or null
    const language = response.language ?? fallback;
OpenAI2026-09-28 · 87b2daae8 breaking6 additive
  • Breakingresponse.property.removed

    Response field annotations removed

    Reads of this field return undefined, and the failure surfaces wherever that value is used rather than at the call.

    ChatCompletionMessageList.data[].annotations · reachable from 1 operation
    // response.data[0].annotations is now undefined
    const annotations = response.data[0].annotations;
  • Breakingresponse.property.removed

    Response field audio removed

    Reads of this field return undefined, and the failure surfaces wherever that value is used rather than at the call.

    ChatCompletionMessageList.data[].audio · reachable from 1 operation
    // response.data[0].audio is now undefined
    const audio = response.data[0].audio;
  • Breakingresponse.property.removed

    Response field function_call removed

    Reads of this field return undefined, and the failure surfaces wherever that value is used rather than at the call.

    ChatCompletionMessageList.data[].function_call · reachable from 1 operation
    // response.data[0].function_call is now undefined
    const function_call = response.data[0].function_call;
  • Breakingresponse.property.removed

    Response field refusal removed

    Reads of this field return undefined, and the failure surfaces wherever that value is used rather than at the call.

    ChatCompletionMessageList.data[].refusal · reachable from 1 operation
    // response.data[0].refusal is now undefined
    const refusal = response.data[0].refusal;
  • Breakingdirection flipresponse.enum.value-added

    role can now return "developer", "function", "system", "tool", "user"

    Producer-side tools call this additive. It breaks exhaustive switches, strict parsers and generated client enums.

    ChatCompletionMessageList.data[].role · reachable from 1 operation
    switch (response.data[0].role) {
      // existing branches …
      // no branch for "developer"
      // no branch for "function"
      // no branch for "system"
      // no branch for "tool"
      // no branch for "user"
      default:
        throw new Error("unexpected role");
    }
  • Breakingresponse.property.removed

    Response field tool_calls removed

    Reads of this field return undefined, and the failure surfaces wherever that value is used rather than at the call.

    ChatCompletionMessageList.data[].tool_calls · reachable from 1 operation
    // response.data[0].tool_calls is now undefined
    const tool_calls = response.data[0].tool_calls;
  • Breakingdirection flipresponse.property.became-optional

    Response field first_id is no longer guaranteed

    Producer-side tools call this non-breaking. For a consumer it is a null dereference on an unknown future date.

    ChatCompletionMessageList.first_id · reachable from 1 operation
    // response.first_id may now be absent or null
    const first_id = response.first_id ?? fallback;
  • Breakingdirection flipresponse.property.became-optional

    Response field last_id is no longer guaranteed

    Producer-side tools call this non-breaking. For a consumer it is a null dereference on an unknown future date.

    ChatCompletionMessageList.last_id · reachable from 1 operation
    // response.last_id may now be absent or null
    const last_id = response.last_id ?? fallback;

Additive6 new response fieldsChatCompletionMessageList.data[].content_parts[].file, ChatCompletionMessageList.data[].content_parts[].image_url, ChatCompletionMessageList.data[].content_parts[].input_audio, ChatCompletionMessageList.data[].content_parts[].text, ChatCompletionMessageList.data[].content_parts[].type, ChatCompletionMessageList.data[].name

OpenAI2026-09-28 · f6be21c58 breaking
  • Breakingdirection flipresponse.property.became-optional

    Response field action is no longer guaranteed

    Producer-side tools call this non-breaking. For a consumer it is a null dereference on an unknown future date.

    no longer guaranteed present

    2 places: BetaWebSearchToolCall.action, WebSearchToolCall.action
    // response.action may now be absent or null
    const action = response.action ?? fallback;
  • Breakingdirection flipresponse.property.became-optional

    Response field completed_at is no longer guaranteed

    Producer-side tools call this non-breaking. For a consumer it is a null dereference on an unknown future date.

    Batch.completed_at · reachable from 4 operations
    // response.completed_at may now be absent or null
    const completed_at = response.completed_at ?? fallback;
  • Breakingdirection flipresponse.property.became-optional

    Response field error_file_id is no longer guaranteed

    Producer-side tools call this non-breaking. For a consumer it is a null dereference on an unknown future date.

    Batch.error_file_id · reachable from 4 operations
    // response.error_file_id may now be absent or null
    const error_file_id = response.error_file_id ?? fallback;
  • Breakingdirection flipresponse.property.became-optional

    Response field expires_at is no longer guaranteed

    Producer-side tools call this non-breaking. For a consumer it is a null dereference on an unknown future date.

    Batch.expires_at · reachable from 4 operations
    // response.expires_at may now be absent or null
    const expires_at = response.expires_at ?? fallback;
  • Breakingdirection flipresponse.property.became-optional

    Response field finalizing_at is no longer guaranteed

    Producer-side tools call this non-breaking. For a consumer it is a null dereference on an unknown future date.

    Batch.finalizing_at · reachable from 4 operations
    // response.finalizing_at may now be absent or null
    const finalizing_at = response.finalizing_at ?? fallback;
  • Breakingdirection flipresponse.property.became-optional

    Response field in_progress_at is no longer guaranteed

    Producer-side tools call this non-breaking. For a consumer it is a null dereference on an unknown future date.

    Batch.in_progress_at · reachable from 4 operations
    // response.in_progress_at may now be absent or null
    const in_progress_at = response.in_progress_at ?? fallback;
  • Breakingdirection flipresponse.property.became-optional

    Response field output_file_id is no longer guaranteed

    Producer-side tools call this non-breaking. For a consumer it is a null dereference on an unknown future date.

    Batch.output_file_id · reachable from 4 operations
    // response.output_file_id may now be absent or null
    const output_file_id = response.output_file_id ?? fallback;
  • Breakingdirection flipresponse.enum.value-added

    object can now return "vector_store.file_batch"

    Producer-side tools call this additive. It breaks exhaustive switches, strict parsers and generated client enums.

    VectorStoreFileBatchObject.object · reachable from 3 operations
    switch (response.object) {
      // existing branches …
      // no branch for "vector_store.file_batch"
      default:
        throw new Error("unexpected object");
    }
OpenAI2026-09-28 · 883357cf7 breaking
  • Breakingdirection flipresponse.property.became-optional

    Response field refusal is no longer guaranteed

    Producer-side tools call this non-breaking. For a consumer it is a null dereference on an unknown future date.

    no longer guaranteed present

    2 places: ChatCompletionMessageList.data[].refusal, ChatCompletionResponseMessage.refusal
    // response.data[0].refusal may now be absent or null
    const refusal = response.data[0].refusal ?? fallback;
  • Breakingdirection flipresponse.property.became-optional

    Response field function_call is no longer guaranteed

    Producer-side tools call this non-breaking. For a consumer it is a null dereference on an unknown future date.

    can now be null

    2 places: ChatCompletionMessageList.data[].function_call, ChatCompletionResponseMessage.function_call
    // response.data[0].function_call may now be absent or null
    const function_call = response.data[0].function_call ?? fallback;
  • Breakingdirection flipresponse.property.became-optional

    Response field hyperparameters is no longer guaranteed

    Producer-side tools call this non-breaking. For a consumer it is a null dereference on an unknown future date.

    FineTuningJob.hyperparameters · reachable from 6 operations
    // response.hyperparameters may now be absent or null
    const hyperparameters = response.hyperparameters ?? fallback;
  • Breakingdirection flipresponse.property.became-optional

    Response field seed is no longer guaranteed

    Producer-side tools call this non-breaking. For a consumer it is a null dereference on an unknown future date.

    FineTuningJob.seed · reachable from 6 operations
    // response.seed may now be absent or null
    const seed = response.seed ?? fallback;
  • Breakingdirection flipresponse.enum.value-added

    status can now return "paused", "pausing"

    Producer-side tools call this additive. It breaks exhaustive switches, strict parsers and generated client enums.

    FineTuningJob.status · reachable from 6 operations
    switch (response.status) {
      // existing branches …
      // no branch for "paused"
      // no branch for "pausing"
      default:
        throw new Error("unexpected status");
    }
  • Breakingdirection flipresponse.property.became-optional

    Response field first_id is no longer guaranteed

    Producer-side tools call this non-breaking. For a consumer it is a null dereference on an unknown future date.

    ChatCompletionList.first_id · reachable from 1 operation
    // response.first_id may now be absent or null
    const first_id = response.first_id ?? fallback;
  • Breakingdirection flipresponse.property.became-optional

    Response field last_id is no longer guaranteed

    Producer-side tools call this non-breaking. For a consumer it is a null dereference on an unknown future date.

    ChatCompletionList.last_id · reachable from 1 operation
    // response.last_id may now be absent or null
    const last_id = response.last_id ?? fallback;
OpenAI2026-09-28 · 78e0725d1 breaking7 additive
  • Breakingdirection flipresponse.property.became-optional

    Response field user is no longer guaranteed

    Producer-side tools call this non-breaking. For a consumer it is a null dereference on an unknown future date.

    can now be null

    4 places: BetaResponse.user, BetaModelResponseProperties.user, ModelResponseProperties.user, Response.user
    // response.user may now be absent or null
    const user = response.user ?? fallback;
  • Additiverequest.property.became-nullable

    Request field now accepts null

    A relaxation. Existing payloads are unaffected.

    ModelResponseProperties.user · reachable from 4 operations
  • Additiverequest.property.became-nullable

    Request field now accepts null

    A relaxation. Existing payloads are unaffected.

    BetaModelResponseProperties.user · reachable from 3 operations
  • Additiverequest.property.became-nullable

    Request field now accepts null

    A relaxation. Existing payloads are unaffected.

    CreateModelResponseProperties.user · reachable from 2 operations
  • Additiverequest.property.became-nullable

    Request field now accepts null

    A relaxation. Existing payloads are unaffected.

    BetaCreateModelResponseProperties.user · reachable from 1 operation
  • Additiverequest.property.became-nullable

    Request field now accepts null

    A relaxation. Existing payloads are unaffected.

    BetaCreateResponse.user · reachable from 1 operation
  • Additiverequest.property.became-nullable

    Request field now accepts null

    A relaxation. Existing payloads are unaffected.

    CreateChatCompletionRequest.user · reachable from 1 operation
  • Additiverequest.property.became-nullable

    Request field now accepts null

    A relaxation. Existing payloads are unaffected.

    CreateResponse.user · reachable from 1 operation
OpenAI2026-09-28 · 6faa7e5e1 breaking
  • Breakingdirection flipresponse.enum.value-added

    finish_reason gained response values

    Producer-side tools call this additive. It breaks exhaustive switches, strict parsers and generated client enums.

    CreateChatCompletionStreamResponse.choices[].finish_reason · reachable from 1 operation
    switch (response.choices[0].finish_reason) {
      // existing branches …
    
      default:
        throw new Error("unexpected finish_reason");
    }
OpenAI2026-09-28 · aae0ce2c5 breaking
  • Breakingdirection flipresponse.property.became-optional

    Response field cancelled_at is no longer guaranteed

    Producer-side tools call this non-breaking. For a consumer it is a null dereference on an unknown future date.

    Batch.cancelled_at · reachable from 4 operations
    // response.cancelled_at may now be absent or null
    const cancelled_at = response.cancelled_at ?? fallback;
  • Breakingdirection flipresponse.property.became-optional

    Response field cancelling_at is no longer guaranteed

    Producer-side tools call this non-breaking. For a consumer it is a null dereference on an unknown future date.

    Batch.cancelling_at · reachable from 4 operations
    // response.cancelling_at may now be absent or null
    const cancelling_at = response.cancelling_at ?? fallback;
  • Breakingdirection flipresponse.property.became-optional

    Response field errors is no longer guaranteed

    Producer-side tools call this non-breaking. For a consumer it is a null dereference on an unknown future date.

    Batch.errors · reachable from 4 operations
    // response.errors may now be absent or null
    const errors = response.errors ?? fallback;
  • Breakingdirection flipresponse.property.became-optional

    Response field expired_at is no longer guaranteed

    Producer-side tools call this non-breaking. For a consumer it is a null dereference on an unknown future date.

    Batch.expired_at · reachable from 4 operations
    // response.expired_at may now be absent or null
    const expired_at = response.expired_at ?? fallback;
  • Breakingdirection flipresponse.property.became-optional

    Response field failed_at is no longer guaranteed

    Producer-side tools call this non-breaking. For a consumer it is a null dereference on an unknown future date.

    Batch.failed_at · reachable from 4 operations
    // response.failed_at may now be absent or null
    const failed_at = response.failed_at ?? fallback;