SpyBara
Go Premium

Documentation 2026-10-01 22:59 UTC to 2026-10-02 16:57 UTC

12 files changed +292 −22. View all changes and history on the product overview
2026
Sun 18 23:00 Sat 17 22:57 Fri 16 23:02 Thu 15 23:00 Wed 14 23:59 Tue 13 23:00 Sun 11 23:59 Sat 10 23:58 Fri 9 22:57 Thu 8 23:01 Wed 7 23:57 Tue 6 22:58 Mon 5 22:59 Sun 4 22:58 Fri 2 23:58 Thu 1 22:59

deprecations.md +21 −0

Details

34 34 

35Upcoming deprecations are listed below, with the most recent announcements at the top.35Upcoming deprecations are listed below, with the most recent announcements at the top.

36 36 

37### 2026-10-01: GPT-5.3-Codex, GPT-5.1, GPT-5.4-Nano

38 

39The following models are deprecated and will be removed from the API on April 1, 2027, with six months' notice. Migrate to the recommended replacements before the shutdown date.

40 

41| Shutdown date | Model / system | Recommended replacement |

42| ------------- | --------------- | ----------------------- |

43| Apr 1, 2027 | `gpt-5.3-codex` | `gpt-6-sol` |

44| Apr 1, 2027 | `gpt-5.4-nano` | `gpt-6-luna` |

45| Apr 1, 2027 | `gpt-5.1` | `gpt-6-sol` |

46 

47### 2026-10-01: Text-to-speech models

48 

49The following text-to-speech models are deprecated and will be removed from the API on January 6, 2027, with at least three months' notice. Migrate to `gpt-realtime-2.1-mini` before the shutdown date. See the [Realtime API guide](https://developers.openai.com/api/docs/guides/realtime) to plan your migration.

50 

51| Shutdown date | Model / system | Recommended replacement |

52| ------------- | ---------------------------- | ----------------------- |

53| Jan 6, 2027 | `tts-1` | `gpt-realtime-2.1-mini` |

54| Jan 6, 2027 | `tts-1-hd` | `gpt-realtime-2.1-mini` |

55| Jan 6, 2027 | `gpt-4o-mini-tts-2025-03-20` | `gpt-realtime-2.1-mini` |

56| Jan 6, 2027 | `gpt-4o-mini-tts-2025-12-15` | `gpt-realtime-2.1-mini` |

57 

37### 2026-09-11: GPT-5.4-Cyber58### 2026-09-11: GPT-5.4-Cyber

38 59 

39The `gpt-5.4-cyber` model is deprecated and will be removed from the API on October 1, 2026. Migrate to the most capable cyber model available to you before the shutdown date.60The `gpt-5.4-cyber` model is deprecated and will be removed from the API on October 1, 2026. Migrate to the most capable cyber model available to you before the shutdown date.

Details

113 113 

114```javascript114```javascript

115import OpenAI from "openai";115import OpenAI from "openai";

116import { agentFileDestination } from "openai/helpers/beta/agents/filesystem";

116 117 

117const client = new OpenAI();118const client = new OpenAI();

118const stream = await client.beta.agents.sessions.create({119const stream = await client.beta.agents.sessions.create({


133 stream: true,134 stream: true,

134});135});

135 136 

136for await (const event of stream) {137stream.withResultCollection();

138try {

139 for await (const event of stream) {

137 console.log(event);140 console.log(event);

141 }

142 const result = await stream.finalResult();

143 await client.beta.agents.sessions.artifacts.forResult(result).download({

144 path: "/workspace/outputs/summary.json",

145 to: agentFileDestination("summary.json"),

146 });

147} finally {

148 stream.controller.abort();

138}149}

139```150```

140 151 


159 stream=True,170 stream=True,

160)171)

161 172 

162with stream:173with stream.with_result_collection():

163 for event in stream:174 for event in stream:

164 print(event.model_dump_json())175 print(event.model_dump_json())

176 result = stream.get_final_result()

177 

178client.beta.agents.sessions.artifacts.for_result(result).download(

179 "/workspace/outputs/summary.json", to="summary.json"

180)

165```181```

166 182 

167```go183```go


170import (186import (

171 "context"187 "context"

172 "fmt"188 "fmt"

189 "os"

173 190 

174 "github.com/openai/openai-go/v3"191 "github.com/openai/openai-go/v3"

175)192)


189 Input: openai.BetaAgentSessionNewParamsInputUnion{OfString: openai.String("Use Python to sum the amount column in /workspace/amounts.csv. Write a JSON object with the total to /workspace/outputs/summary.json, then read it back to verify it.")},206 Input: openai.BetaAgentSessionNewParamsInputUnion{OfString: openai.String("Use Python to sum the amount column in /workspace/amounts.csv. Write a JSON object with the total to /workspace/outputs/summary.json, then read it back to verify it.")},

190 })207 })

191 defer stream.Close()208 defer stream.Close()

192 209 openai.BetaAgentSessionWithResultCollection(stream)

193 for stream.Next() {210 for stream.Next() {

194 fmt.Println(stream.Current().RawJSON())211 fmt.Println(stream.Current().RawJSON())

195 }212 }

196 if err := stream.Err(); err != nil {213 

214 result, err := openai.BetaAgentSessionFinalResult(stream)

215 if err != nil {

216 panic(err)

217 }

218 destination, err := os.Create("summary.json")

219 if err != nil {

220 panic(err)

221 }

222 defer destination.Close()

223 _, err = client.Beta.Agents.Sessions.Artifacts.ForResult(result).Download(ctx, "/workspace/outputs/summary.json", destination)

224 if err != nil {

225 panic(err)

226 }

227 if err := destination.Close(); err != nil {

197 panic(err)228 panic(err)

198 }229 }

199}230}


201 232 

202```java233```java

203import com.openai.client.okhttp.OpenAIOkHttpClient;234import com.openai.client.okhttp.OpenAIOkHttpClient;

235import com.openai.helpers.beta.agents.AgentArtifactDownloads;

204import com.openai.models.beta.agents.EnvironmentParam;236import com.openai.models.beta.agents.EnvironmentParam;

205import com.openai.models.beta.agents.HostedEnvironmentFileParam;237import com.openai.models.beta.agents.HostedEnvironmentFileParam;

206import com.openai.models.beta.agents.sessions.SessionCreateParams;238import com.openai.models.beta.agents.sessions.SessionCreateParams;

239import com.openai.services.beta.agents.AgentTurnResults;

240import java.nio.file.Path;

207 241 

208public class HostedReport {242public class HostedReport {

209 public static void main(String[] args) throws Exception {243 public static void main(String[] args) throws Exception {


230 .build();264 .build();

231 265 

232 try (var stream = client.beta().agents().sessions().createStreaming(params)) {266 try (var stream = client.beta().agents().sessions().createStreaming(params)) {

267 AgentTurnResults.withResultCollection(stream);

233 stream.stream().forEach(System.out::println);268 stream.stream().forEach(System.out::println);

269 var result = AgentTurnResults.getFinalResult(stream);

270 AgentArtifactDownloads.forResult(client.beta().agents().sessions().artifacts(), result)

271 .download("/workspace/outputs/summary.json", Path.of("summary.json"));

234 }272 }

235 }273 }

236}274}


239```ruby277```ruby

240require "openai"278require "openai"

241require "json"279require "json"

280require "pathname"

242 281 

243client = OpenAI::Client.new282client = OpenAI::Client.new

244stream = client.beta.agents.sessions.create_streaming(283stream = client.beta.agents.sessions.create_streaming(


258)297)

259 298 

260begin299begin

300 stream.with_result_collection

261 stream.each { |event| puts event.to_json }301 stream.each { |event| puts event.to_json }

302 result = stream.get_final_result

303 puts result.output_text

304 client.beta.agents.sessions.artifacts.for_result(result).download(

305 path: "/workspace/outputs/summary.json",

306 to: Pathname("summary.json")

307 )

262ensure308ensure

263 stream.close309 stream.close

264end310end

Details

41 "Release A: Search now supports filtering by date. Existing queries continue to work. Release B: The export endpoint now returns a download URL instead of file bytes. Update clients to fetch that URL.",41 "Release A: Search now supports filtering by date. Existing queries continue to work. Release B: The export endpoint now returns a download URL instead of file bytes. Update clients to fetch that URL.",

42 stream: true,42 stream: true,

43});43});

44for await (const event of events) {44events.withResultCollection();

45try {

46 for await (const event of events) {

45 console.log(JSON.stringify(event));47 console.log(JSON.stringify(event));

48 }

49 console.log((await events.finalResult()).output_text);

50} finally {

51 events.controller.abort();

46}52}

47```53```

48 54 


60 environment={"type": "none"},66 environment={"type": "none"},

61 input="Release A: Search now supports filtering by date. Existing queries continue to work. Release B: The export endpoint now returns a download URL instead of file bytes. Update clients to fetch that URL.",67 input="Release A: Search now supports filtering by date. Existing queries continue to work. Release B: The export endpoint now returns a download URL instead of file bytes. Update clients to fetch that URL.",

62 stream=True,68 stream=True,

63) as events:69).with_result_collection() as stream:

64 for event in events:70 for event in stream:

65 print(event.model_dump_json())71 print(event.model_dump_json())

72 result = stream.get_final_result()

73print(result.output_text)

66```74```

67 75 

68```go76```go


81 Environment: openai.EnvironmentParamUnion{OfParamNone: &openai.EnvironmentParamNone{}},89 Environment: openai.EnvironmentParamUnion{OfParamNone: &openai.EnvironmentParamNone{}},

82 Input: openai.BetaAgentSessionNewParamsInputUnion{OfString: openai.String("Release A: Search now supports filtering by date. Existing queries continue to work. Release B: The export endpoint now returns a download URL instead of file bytes. Update clients to fetch that URL.")}})90 Input: openai.BetaAgentSessionNewParamsInputUnion{OfString: openai.String("Release A: Search now supports filtering by date. Existing queries continue to work. Release B: The export endpoint now returns a download URL instead of file bytes. Update clients to fetch that URL.")}})

83defer events.Close()91defer events.Close()

92openai.BetaAgentSessionWithResultCollection(events)

84for events.Next() {93for events.Next() {

85 fmt.Println(events.Current().RawJSON())94 fmt.Println(events.Current().RawJSON())

86}95}

87if err := events.Err(); err != nil {96result, err := openai.BetaAgentSessionFinalResult(events)

97if err != nil {

88 panic(err)98 panic(err)

89}99}

100fmt.Println(result.OutputText())

90```101```

91 102 

92```java103```java


94import com.openai.client.okhttp.OpenAIOkHttpClient;105import com.openai.client.okhttp.OpenAIOkHttpClient;

95import com.openai.models.beta.agents.MultiAgentConfigParam;106import com.openai.models.beta.agents.MultiAgentConfigParam;

96import com.openai.models.beta.agents.sessions.SessionCreateParams;107import com.openai.models.beta.agents.sessions.SessionCreateParams;

108import com.openai.services.beta.agents.AgentTurnResults;

97 109 

98OpenAIClient client = OpenAIOkHttpClient.fromEnv();110OpenAIClient client = OpenAIOkHttpClient.fromEnv();

99try (var events =111try (var events =


125 + " download URL instead of file bytes. Update clients to fetch that"137 + " download URL instead of file bytes. Update clients to fetch that"

126 + " URL.")138 + " URL.")

127 .build())) {139 .build())) {

140 AgentTurnResults.withResultCollection(events);

128 events.stream().forEach(System.out::println);141 events.stream().forEach(System.out::println);

142 System.out.println(AgentTurnResults.getFinalResult(events).outputText());

129}143}

130```144```

131 145 


148 input: "Release A: Search now supports filtering by date. Existing queries continue to work. Release B: The export endpoint now returns a download URL instead of file bytes. Update clients to fetch that URL."162 input: "Release A: Search now supports filtering by date. Existing queries continue to work. Release B: The export endpoint now returns a download URL instead of file bytes. Update clients to fetch that URL."

149)163)

150begin164begin

165 events.with_result_collection

151 events.each { |event| puts JSON.generate(event.to_h) }166 events.each { |event| puts JSON.generate(event.to_h) }

167 result = events.get_final_result

168 puts result.output_text

152ensure169ensure

153 events.close170 events.close

154end171end

Details

48 environment={"type": "openai_hosted"},48 environment={"type": "openai_hosted"},

49 input="Create tree.py, a Python script that prints a readable tree of the files in the current directory. Run it and show me the output.",49 input="Create tree.py, a Python script that prints a readable tree of the files in the current directory. Run it and show me the output.",

50 stream=True,50 stream=True,

51 ) as events:51 ).with_result_collection() as stream:

52 for event in events:52 for event in stream:

53 print(event.to_json(indent=None), flush=True)53 print(event.to_json(indent=None), flush=True)

54 result = stream.get_final_result()

55 print(result.output_text)

56 session_id = result.session_id

54```57```

55 58 

56 59 


93 "Create tree.py, a Python script that prints a readable tree of the files in the current directory. Run it and show me the output.",96 "Create tree.py, a Python script that prints a readable tree of the files in the current directory. Run it and show me the output.",

94 stream: true,97 stream: true,

95});98});

99events.withResultCollection();

96try {100try {

97 for await (const event of events) {101 for await (const event of events) {

98 console.log(JSON.stringify(event));102 console.log(JSON.stringify(event));

99 }103 }

104 const result = await events.finalResult();

105 console.log(result.output_text);

106 console.log("Session:", result.session_id);

100} finally {107} finally {

101 events.controller.abort();108 events.controller.abort();

102}109}


150 },157 },

151})158})

152defer events.Close()159defer events.Close()

160openai.BetaAgentSessionWithResultCollection(events)

153if events.Err() != nil {161if events.Err() != nil {

154 panic(events.Err())162 panic(events.Err())

155}163}


157 event := events.Current()165 event := events.Current()

158 fmt.Println(event.RawJSON())166 fmt.Println(event.RawJSON())

159}167}

160if err := events.Err(); err != nil {168result, err := openai.BetaAgentSessionFinalResult(events)

169if err != nil {

161 panic(err)170 panic(err)

162}171}

172fmt.Println(result.OutputText())

173sessionID := result.SessionID()

174fmt.Println("Session:", sessionID)

163```175```

164 176 

165 177 


201import com.openai.models.beta.agents.AgentSessionEvent;213import com.openai.models.beta.agents.AgentSessionEvent;

202import com.openai.models.beta.agents.EnvironmentParam;214import com.openai.models.beta.agents.EnvironmentParam;

203import com.openai.models.beta.agents.sessions.SessionCreateParams;215import com.openai.models.beta.agents.sessions.SessionCreateParams;

216import com.openai.services.beta.agents.AgentTurnResults;

204 217 

205OpenAIClient client = OpenAIOkHttpClient.fromEnv();218OpenAIClient client = OpenAIOkHttpClient.fromEnv();

206var json = new JsonMapper();219var json = new JsonMapper();


221 "Create tree.py, a Python script that prints a readable tree of the files"234 "Create tree.py, a Python script that prints a readable tree of the files"

222 + " in the current directory. Run it and show me the output.")235 + " in the current directory. Run it and show me the output.")

223 .build())) {236 .build())) {

237 AgentTurnResults.withResultCollection(events);

224 var iterator = events.stream().iterator();238 var iterator = events.stream().iterator();

225 while (iterator.hasNext()) {239 while (iterator.hasNext()) {

226 var event = iterator.next();240 var event = iterator.next();

227 System.out.println(json.writeValueAsString(event));241 System.out.println(json.writeValueAsString(event));

228 }242 }

243 var result = AgentTurnResults.getFinalResult(events);

244 System.out.println(result.outputText());

245 String sessionId = result.sessionId();

246 System.out.println(sessionId);

229}247}

230```248```

231 249 


269 input: "Create tree.py, a Python script that prints a readable tree of the files in the current directory. Run it and show me the output."287 input: "Create tree.py, a Python script that prints a readable tree of the files in the current directory. Run it and show me the output."

270)288)

271begin289begin

290 events.with_result_collection

272 events.each do |event|291 events.each do |event|

273 puts JSON.generate(event.to_h)292 puts JSON.generate(event.to_h)

274 end293 end

294 result = events.get_final_result

295 puts result.output_text

296 session_id = result.session_id

297 puts "Session: #{session_id}"

275ensure298ensure

276 events.close299 events.close

277end300end

Details

38 "Create tree.py, a Python script that prints a readable tree of the files in the current directory. Run it and show me the output.",38 "Create tree.py, a Python script that prints a readable tree of the files in the current directory. Run it and show me the output.",

39 stream: true,39 stream: true,

40});40});

41events.withResultCollection();

41try {42try {

42 for await (const event of events) {43 for await (const event of events) {

43 console.log(JSON.stringify(event));44 console.log(JSON.stringify(event));

44 }45 }

46 const result = await events.finalResult();

47 console.log(result.output_text);

48 console.log("Session:", result.session_id);

45} finally {49} finally {

46 events.controller.abort();50 events.controller.abort();

47}51}


59 environment={"type": "openai_hosted"},63 environment={"type": "openai_hosted"},

60 input="Create tree.py, a Python script that prints a readable tree of the files in the current directory. Run it and show me the output.",64 input="Create tree.py, a Python script that prints a readable tree of the files in the current directory. Run it and show me the output.",

61 stream=True,65 stream=True,

62 ) as events:66 ).with_result_collection() as stream:

63 for event in events:67 for event in stream:

64 print(event.to_json(indent=None), flush=True)68 print(event.to_json(indent=None), flush=True)

69 result = stream.get_final_result()

70 print(result.output_text)

71 session_id = result.session_id

65```72```

66 73 

67```go74```go


85 },92 },

86})93})

87defer events.Close()94defer events.Close()

95openai.BetaAgentSessionWithResultCollection(events)

88if events.Err() != nil {96if events.Err() != nil {

89 panic(events.Err())97 panic(events.Err())

90}98}


92 event := events.Current()100 event := events.Current()

93 fmt.Println(event.RawJSON())101 fmt.Println(event.RawJSON())

94}102}

95if err := events.Err(); err != nil {103result, err := openai.BetaAgentSessionFinalResult(events)

104if err != nil {

96 panic(err)105 panic(err)

97}106}

107fmt.Println(result.OutputText())

108sessionID := result.SessionID()

109fmt.Println("Session:", sessionID)

98```110```

99 111 

100```java112```java


105import com.openai.models.beta.agents.AgentSessionEvent;117import com.openai.models.beta.agents.AgentSessionEvent;

106import com.openai.models.beta.agents.EnvironmentParam;118import com.openai.models.beta.agents.EnvironmentParam;

107import com.openai.models.beta.agents.sessions.SessionCreateParams;119import com.openai.models.beta.agents.sessions.SessionCreateParams;

120import com.openai.services.beta.agents.AgentTurnResults;

108 121 

109OpenAIClient client = OpenAIOkHttpClient.fromEnv();122OpenAIClient client = OpenAIOkHttpClient.fromEnv();

110var json = new JsonMapper();123var json = new JsonMapper();


125 "Create tree.py, a Python script that prints a readable tree of the files"138 "Create tree.py, a Python script that prints a readable tree of the files"

126 + " in the current directory. Run it and show me the output.")139 + " in the current directory. Run it and show me the output.")

127 .build())) {140 .build())) {

141 AgentTurnResults.withResultCollection(events);

128 var iterator = events.stream().iterator();142 var iterator = events.stream().iterator();

129 while (iterator.hasNext()) {143 while (iterator.hasNext()) {

130 var event = iterator.next();144 var event = iterator.next();

131 System.out.println(json.writeValueAsString(event));145 System.out.println(json.writeValueAsString(event));

132 }146 }

147 var result = AgentTurnResults.getFinalResult(events);

148 System.out.println(result.outputText());

149 String sessionId = result.sessionId();

150 System.out.println(sessionId);

133}151}

134```152```

135 153 


147 input: "Create tree.py, a Python script that prints a readable tree of the files in the current directory. Run it and show me the output."165 input: "Create tree.py, a Python script that prints a readable tree of the files in the current directory. Run it and show me the output."

148)166)

149begin167begin

168 events.with_result_collection

150 events.each do |event|169 events.each do |event|

151 puts JSON.generate(event.to_h)170 puts JSON.generate(event.to_h)

152 end171 end

172 result = events.get_final_result

173 puts result.output_text

174 session_id = result.session_id

175 puts "Session: #{session_id}"

153ensure176ensure

154 events.close177 events.close

155end178end

Details

19 19 

20## Implementing safety identifiers for individual users20## Implementing safety identifiers for individual users

21 21 

22To route warning and deactivation notices for a safety identifier to your investigation or support workflow, see [Safety enforcement notifications](https://developers.openai.com/api/docs/guides/safety-enforcement).

23 

22The `safety_identifier` parameter is available in both the [Responses API](https://developers.openai.com/api/reference/resources/responses/methods/create) and older [Chat Completions API](https://developers.openai.com/api/reference/resources/chat). The Realtime API supports the same concept through the `OpenAI-Safety-Identifier` header. To use safety identifiers, provide a stable ID for your end user on each request. Hash user email or internal user IDs to avoid passing any personal information.24The `safety_identifier` parameter is available in both the [Responses API](https://developers.openai.com/api/reference/resources/responses/methods/create) and older [Chat Completions API](https://developers.openai.com/api/reference/resources/chat). The Realtime API supports the same concept through the `OpenAI-Safety-Identifier` header. To use safety identifiers, provide a stable ID for your end user on each request. Hash user email or internal user IDs to avoid passing any personal information.

23 25 

24Safety identifiers do not carry over between APIs or sessions. If your application already sends `safety_identifier` with Responses API requests, pass the same stable value separately when you create or connect each Realtime session.26Safety identifiers do not carry over between APIs or sessions. If your application already sends `safety_identifier` with Responses API requests, pass the same stable value separately when you create or connect each Realtime session.

guides/safety-enforcement.md +124 −0 created

Details

1# Safety enforcement notifications

2 

3> For the complete documentation index, see [llms.txt](/llms.txt). Markdown versions of documentation pages are available by appending `.md` to the page URL.

4 

5Use safety webhooks and the Safety Case Read API to connect OpenAI enforcement notices to your team's workflows. For example, when a warning arrives, your application can retrieve its case details, identify the affected user, and create an internal review ticket.

6 

7## When to use this

8 

9Use this integration to:

10 

11- Route warning and deactivation notices to your trust and safety, security, or support team.

12- Add case details to an investigation or support ticket.

13- Associate a notice with a user through your application's safety-identifier mapping.

14 

15The steps in this guide use a warning to illustrate the workflow. You can use the same integration for deactivation notices.

16 

17## How it works

18 

19Safety webhooks notify your application that a notice was issued. The Safety Case Read API provides the details for that notice.

20 

21| Event | Notice |

22| ---------------------------- | ------------------------------------------------------------ |

23| `safety.warning_issued` | A warning for a safety identifier in your organization. |

24| `safety.deactivation_issued` | A deactivation for a safety identifier in your organization. |

25 

26Each event contains a case ID. Use it with `GET /v1/safety/cases/{id}` to retrieve the safety identifier, notice type, case creation timestamp, and available policy reason.

27 

28These organization-level notifications are separate from project-level [misalignment alerts](https://developers.openai.com/api/docs/guides/safety-checks/misalignment-monitoring#receive-project-safety-alerts). Retrieving a case does not change or reverse the enforcement. The API returns case metadata, not the underlying conversation or a full investigation report.

29 

30## Integrate with your application

31 

32Start by configuring an organization-level webhook and a key for case lookups. Then connect the notifications to your review workflow.

33 

34### 1. Configure your webhook and API key

35 

36Use a stable [safety identifier](https://developers.openai.com/api/docs/guides/safety-best-practices#implement-safety-identifiers) for each user, and keep your application's mapping from that identifier to the user. Avoid including personal information in the identifier.

37 

38Open your [organization webhook settings](https://platform.openai.com/settings/organization/webhooks) and select **Create**. Enter your receiver's HTTPS URL and subscribe to `safety.warning_issued` and `safety.deactivation_issued`. Save the signing secret securely so your receiver can verify incoming events. These events use an organization endpoint, not a project endpoint.

39 

40Your account needs `api.webhooks.read` and `organization.read` to view organization webhooks, plus `api.webhooks.write` and `organization.write` to create them. See [Permissions](https://developers.openai.com/api/docs/guides/rbac) for role configuration.

41 

42For case lookups, configure an API key for the same organization with **Restricted** permissions and set **Safety** to **Read** (`api.safety.read`). The API key authenticates case lookups; it is separate from the webhook signing secret.

43 

44### 2. Receive and verify the event

45 

46A warning notification has this structure. The IDs are illustrative:

47 

48```json

49{

50 "id": "evt_example",

51 "object": "event",

52 "created_at": 1787659200,

53 "type": "safety.warning_issued",

54 "data": {

55 "id": "C-example"

56 }

57}

58```

59 

60Verify the signature before processing the event. Save the verified event for processing, return a successful `2xx` response promptly, and retrieve the case in a background worker. See the Webhooks guide for [signature verification](https://developers.openai.com/api/docs/guides/webhooks#verifying-webhook-signatures) and [acknowledgments, retries, and duplicate deliveries](https://developers.openai.com/api/docs/guides/webhooks#handling-webhook-requests-on-a-server).

61 

62The event's `id` identifies the webhook event. Its `data.id` identifies the safety case to retrieve.

63 

64### 3. Retrieve the case

65 

66Set `OPENAI_API_KEY` to your API key. Replace `C-example` with `data.id` from the verified event:

67 

68```bash

69curl "https://api.openai.com/v1/safety/cases/C-example" \

70 -H "Authorization: Bearer ${OPENAI_API_KEY}"

71```

72 

73A successful lookup returns HTTP `200` and a case object. For example:

74 

75```json

76{

77 "id": "C-example",

78 "object": "safety.case",

79 "created_at": 1787659100,

80 "entity_identifier": "safety-id-example",

81 "reason": "cyber_abuse",

82 "notice": {

83 "type": "warning"

84 }

85}

86```

87 

88Use `entity_identifier` to find the affected user in your application. The `reason` can be `null`; continue processing the notice when no reason is available.

89 

90The case creation timestamp is not necessarily the event timestamp or the time of an individual request. See the [Safety Case API reference](https://developers.openai.com/api/reference/resources/safety/subresources/cases/methods/retrieve) for field definitions.

91 

92### 4. Create a review ticket

93 

94Add the case ID, notice type, safety identifier, case creation timestamp, and available policy reason to your internal ticket. Link the matching user record so your team can investigate using its own application records. If you cannot find a matching user, preserve the case details and flag the missing mapping for review.

95 

96Make ticket creation safe to retry. Follow the [webhook deduplication guidance](https://developers.openai.com/api/docs/guides/webhooks#handling-webhook-requests-on-a-server) so repeated deliveries do not create duplicate tickets. Retries of your own background processing should also reuse the existing ticket.

97 

98If an agent helps with triage, limit its access to the records it needs and keep customer-facing actions subject to your existing approval controls.

99 

100## Confirm it's working

101 

102For a real event and an accessible case in your organization, check that:

103 

1041. Your receiver verifies the signature and returns a successful acknowledgment.

1052. The lookup returns HTTP `200`, with a case `id` matching the event's `data.id`.

1063. Your application identifies the expected user or flags a missing mapping.

1074. One review ticket contains the available case details. Reprocessing the event does not create another ticket.

108 

109Before receiving a real notice, test your processing logic with local example events and mocked case responses. Include both notice types, a `null` reason, a missing user mapping, and duplicate deliveries. Test signature verification separately, including rejection of invalid signatures; keep it enabled on your production receiver.

110 

111The example IDs on this page are not retrievable cases. Mocked tests validate your processing logic, not live delivery or API permissions. Do not trigger an actual enforcement to test your integration. An absence of enforcement notifications alone does not indicate a broken integration.

112 

113## Troubleshoot

114 

115| Symptom | What to check |

116| ----------------------------------------- | -------------------------------------------------------------------------------------------------------- |

117| Signature verification fails | Check the signing secret and preserve the raw request body as described in the Webhooks guide. |

118| Lookup returns `401` | Check that the API key is present and valid. |

119| Lookup returns `403` | Check that the key has the `api.safety.read` permission. |

120| Lookup returns `404` | Use `data.id`, not the event ID. Check that the case belongs to the key's organization. |

121| Lookup returns `429` or a transient `5xx` | Retry with backoff and a bounded retry policy. Preserve the event for later processing or investigation. |

122| A ticket is created more than once | Check that ticket creation remains safe across repeated deliveries and worker retries. |

123 

124Do not silently discard a verified notification when its case lookup fails. Keep it available for retry or investigation.

Details

121 file: audio,121 file: audio,

122 model: "gpt-transcribe"122 model: "gpt-transcribe"

123)123)

124raise "Expected a JSON transcript response" if transcript.is_a?(StringIO)

125 

124puts(transcript.text)126puts(transcript.text)

125```127```

126 128 


273 model: "gpt-transcribe",275 model: "gpt-transcribe",

274 keywords: ["OpenAI", "Responses API", "Codex"]276 keywords: ["OpenAI", "Responses API", "Codex"]

275)277)

278raise "Expected a JSON transcript response" if transcript.is_a?(StringIO)

279 

276puts(transcript.text)280puts(transcript.text)

277```281```

278 282 


626client = OpenAI::Client.new630client = OpenAI::Client.new

627audio = Pathname("german.wav")631audio = Pathname("german.wav")

628translation = client.audio.translations.create(file: audio, model: "whisper-1")632translation = client.audio.translations.create(file: audio, model: "whisper-1")

633raise "Expected a JSON translation response" if translation.is_a?(StringIO)

634 

629puts(translation.text)635puts(translation.text)

630```636```

631 637 


796 response_format: :verbose_json,802 response_format: :verbose_json,

797 timestamp_granularities: [:word]803 timestamp_granularities: [:word]

798)804)

805raise "Expected a JSON transcript response" if transcript.is_a?(StringIO)

806 

799pp(transcript[:words])807pp(transcript[:words])

800```808```

801 809 


1126 model: "whisper-1",1134 model: "whisper-1",

1127 prompt: "The speaker says OpenAI and Responses API"1135 prompt: "The speaker says OpenAI and Responses API"

1128)1136)

1137raise "Expected a JSON transcript response" if transcript.is_a?(StringIO)

1138 

1129puts(transcript.text)1139puts(transcript.text)

1130```1140```

1131 1141 


1359 model: "gpt-4o-mini-transcribe"1369 model: "gpt-4o-mini-transcribe"

1360)1370)

1361 1371 

1372raise "Expected a JSON transcript response" if transcript.is_a?(StringIO)

1373 

1362response = client.responses.create(1374response = client.responses.create(

1363 model: "gpt-4.1",1375 model: "gpt-4.1",

1364 input: "Add punctuation and paragraph breaks without changing the words:\n#{transcript.text}"1376 input: "Add punctuation and paragraph breaks without changing the words:\n#{transcript.text}"

Details

6 6 

7To receive misalignment monitoring notifications for an API project, see [Receive project safety alerts](https://developers.openai.com/api/docs/guides/safety-checks/misalignment-monitoring#receive-project-safety-alerts).7To receive misalignment monitoring notifications for an API project, see [Receive project safety alerts](https://developers.openai.com/api/docs/guides/safety-checks/misalignment-monitoring#receive-project-safety-alerts).

8 8 

9To receive organization-level warning and deactivation notices for safety identifiers, see [Safety enforcement notifications](https://developers.openai.com/api/docs/guides/safety-enforcement).

10 

9For Agents API sessions, see [Session webhooks](https://developers.openai.com/api/docs/guides/agents-api/sessions/webhooks) for session events and recovery patterns. Use the endpoint setup, signature verification, and delivery guidance on this page for the webhook receiver.11For Agents API sessions, see [Session webhooks](https://developers.openai.com/api/docs/guides/agents-api/sessions/webhooks) for session events and recovery patterns. Use the endpoint setup, signature verification, and delivery guidance on this page for the webhook receiver.

10 12 

11[API reference for webhook events13[API reference for webhook events


273 275 

274## Creating webhook endpoints276## Creating webhook endpoints

275 277 

276To start receiving webhook requests on your server, log in to the dashboard and [open the webhook settings page](https://platform.openai.com/settings/project/webhooks). Webhooks are configured per-project.278To start receiving project webhook requests on your server, log in to the dashboard and [open the webhook settings page](https://platform.openai.com/settings/project/webhooks). The setup in this section is for project endpoints. For organization-level safety events, see [Safety enforcement notifications](https://developers.openai.com/api/docs/guides/safety-enforcement).

277 279 

278Click the "Create" button to create a new webhook endpoint. You will configure three things:280Click the "Create" button to create a new webhook endpoint. You will configure three things:

279 281 

libraries.md +1 −1

Details

173<dependency>173<dependency>

174 <groupId>com.openai</groupId>174 <groupId>com.openai</groupId>

175 <artifactId>openai-java</artifactId>175 <artifactId>openai-java</artifactId>

176 <version>4.74.0</version>176 <version>4.75.1</version>

177</dependency>177</dependency>

178```178```

179 179 

models/all.md +5 −5

Details

39- [GPT-4o Transcribe](/api/docs/models/gpt-4o-transcribe.md): Speech-to-text model powered by GPT-4o39- [GPT-4o Transcribe](/api/docs/models/gpt-4o-transcribe.md): Speech-to-text model powered by GPT-4o

40- [GPT-4o Mini Transcribe](/api/docs/models/gpt-4o-mini-transcribe.md): Speech-to-text model powered by GPT-4o Mini40- [GPT-4o Mini Transcribe](/api/docs/models/gpt-4o-mini-transcribe.md): Speech-to-text model powered by GPT-4o Mini

41- [GPT-4o Transcribe Diarize](/api/docs/models/gpt-4o-transcribe-diarize.md): Transcription model that identifies who's speaking when41- [GPT-4o Transcribe Diarize](/api/docs/models/gpt-4o-transcribe-diarize.md): Transcription model that identifies who's speaking when

42- [TTS-1](/api/docs/models/tts-1.md): Text-to-speech model optimized for speed

43- [TTS-1 HD](/api/docs/models/tts-1-hd.md): Text-to-speech model optimized for quality

44- [Whisper](/api/docs/models/whisper-1.md): General-purpose speech recognition model42- [Whisper](/api/docs/models/whisper-1.md): General-purpose speech recognition model

45- [GPT-4o Mini TTS](/api/docs/models/gpt-4o-mini-tts.md): Text-to-speech model powered by GPT-4o Mini43- [GPT-4o Mini TTS](/api/docs/models/gpt-4o-mini-tts.md): Text-to-speech model powered by GPT-4o Mini

46 44 


86- [GPT-5.4](/api/docs/models/gpt-5.4.md): A more affordable model for coding and professional work.84- [GPT-5.4](/api/docs/models/gpt-5.4.md): A more affordable model for coding and professional work.

87- [GPT-5.4 Pro](/api/docs/models/gpt-5.4-pro.md): Version of GPT-5.4 that produces smarter and more precise responses.85- [GPT-5.4 Pro](/api/docs/models/gpt-5.4-pro.md): Version of GPT-5.4 that produces smarter and more precise responses.

88- [GPT-5.4 Mini](/api/docs/models/gpt-5.4-mini.md): Our strongest mini model yet for coding, computer use, and subagents86- [GPT-5.4 Mini](/api/docs/models/gpt-5.4-mini.md): Our strongest mini model yet for coding, computer use, and subagents

89- [GPT-5.4 nano](/api/docs/models/gpt-5.4-nano.md): Our cheapest GPT-5.4-class model for simple high-volume tasks

90- [GPT-5.3-Codex](/api/docs/models/gpt-5.3-codex.md): The most capable agentic coding model to date.

91- [GPT-5.2](/api/docs/models/gpt-5.2.md): Previous flagship model for professional work with configurable reasoning effort87- [GPT-5.2](/api/docs/models/gpt-5.2.md): Previous flagship model for professional work with configurable reasoning effort

92- [GPT-5.2 Pro](/api/docs/models/gpt-5.2-pro.md): Previous pro model for professional work that produces smarter and more precise responses.88- [GPT-5.2 Pro](/api/docs/models/gpt-5.2-pro.md): Previous pro model for professional work that produces smarter and more precise responses.

93- [GPT-5.1](/api/docs/models/gpt-5.1.md): The best model for coding and agentic tasks with configurable reasoning effort

94- [GPT-5](/api/docs/models/gpt-5.md): Previous intelligent reasoning model for coding and agentic tasks with configurable reasoning effort89- [GPT-5](/api/docs/models/gpt-5.md): Previous intelligent reasoning model for coding and agentic tasks with configurable reasoning effort

95- [GPT-5 Mini](/api/docs/models/gpt-5-mini.md): Strong intelligence for cost sensitive, low latency, high volume workloads90- [GPT-5 Mini](/api/docs/models/gpt-5-mini.md): Strong intelligence for cost sensitive, low latency, high volume workloads

96- [GPT-5 nano](/api/docs/models/gpt-5-nano.md): Fastest, most cost-efficient version of GPT-591- [GPT-5 nano](/api/docs/models/gpt-5-nano.md): Fastest, most cost-efficient version of GPT-5


102- [omni-moderation](/api/docs/models/omni-moderation-latest.md): Identify potentially harmful content in text and images97- [omni-moderation](/api/docs/models/omni-moderation-latest.md): Identify potentially harmful content in text and images

103- [GPT-4o Mini](/api/docs/models/gpt-4o-mini.md): Fast, affordable small model for focused tasks98- [GPT-4o Mini](/api/docs/models/gpt-4o-mini.md): Fast, affordable small model for focused tasks

104- [GPT-4o](/api/docs/models/gpt-4o.md): Fast, intelligent, flexible GPT model99- [GPT-4o](/api/docs/models/gpt-4o.md): Fast, intelligent, flexible GPT model

100- [GPT-5.4 nano](/api/docs/models/gpt-5.4-nano.md): Deprecated. Our cheapest GPT-5.4-class model for simple high-volume tasks

101- [GPT-5.3-Codex](/api/docs/models/gpt-5.3-codex.md): Deprecated. The most capable agentic coding model to date.

102- [GPT-5.1](/api/docs/models/gpt-5.1.md): Deprecated. The best model for coding and agentic tasks with configurable reasoning effort

105- [GPT-Realtime](/api/docs/models/gpt-realtime.md): Deprecated. Model capable of realtime text and audio inputs and outputs103- [GPT-Realtime](/api/docs/models/gpt-realtime.md): Deprecated. Model capable of realtime text and audio inputs and outputs

106- [GPT-Audio](/api/docs/models/gpt-audio.md): Deprecated. For audio inputs and outputs with Chat Completions API104- [GPT-Audio](/api/docs/models/gpt-audio.md): Deprecated. For audio inputs and outputs with Chat Completions API

105- [TTS-1](/api/docs/models/tts-1.md): Deprecated. Text-to-speech model optimized for speed

106- [TTS-1 HD](/api/docs/models/tts-1-hd.md): Deprecated. Text-to-speech model optimized for quality

107- [GPT-5.3 Chat](/api/docs/models/gpt-5.3-chat-latest.md): Deprecated. GPT-5.3 Instant model used in ChatGPT107- [GPT-5.3 Chat](/api/docs/models/gpt-5.3-chat-latest.md): Deprecated. GPT-5.3 Instant model used in ChatGPT

108- [GPT-5.2 Chat](/api/docs/models/gpt-5.2-chat-latest.md): Deprecated. GPT-5.2 model used in ChatGPT108- [GPT-5.2 Chat](/api/docs/models/gpt-5.2-chat-latest.md): Deprecated. GPT-5.2 model used in ChatGPT

109- [GPT-5.2-Codex](/api/docs/models/gpt-5.2-codex.md): Deprecated. Our most intelligent coding model optimized for long-horizon, agentic coding tasks.109- [GPT-5.2-Codex](/api/docs/models/gpt-5.2-codex.md): Deprecated. Our most intelligent coding model optimized for long-horizon, agentic coding tasks.

quickstart.md +1 −1

Details

190<dependency>190<dependency>

191 <groupId>com.openai</groupId>191 <groupId>com.openai</groupId>

192 <artifactId>openai-java</artifactId>192 <artifactId>openai-java</artifactId>

193 <version>4.74.0</version>193 <version>4.75.1</version>

194</dependency>194</dependency>

195```195```

196 196