SpyBara
Go Premium

Documentation 2026-09-17 10:04 UTC to 2026-09-18 22:59 UTC

27 files changed +315 −660. View all changes and history on the product overview
2026
Tue 29 22:57 Mon 28 22:57 Sat 26 23:59 Fri 25 23:58 Thu 24 23:58 Wed 23 23:58 Tue 22 23:57 Mon 21 23:00 Sat 19 23:00 Fri 18 22:59 Thu 17 10:04 Wed 16 20:58 Tue 15 22:59 Mon 14 22:58 Sun 13 15:02 Fri 11 20:00 Thu 10 18:01 Wed 9 23:59 Sat 5 17:01 Fri 4 23:59 Thu 3 23:00 Wed 2 22:59
Details

15 15 

16Search for a session by ID to inspect its turns, tool calls, and subagents.16Search for a session by ID to inspect its turns, tool calls, and subagents.

17 17 

18Use the [Tracing guide](https://developers.openai.com/api/docs/guides/agents-api/tracing) to inspect recorded model responses, tool calls, and subagent activity in the dashboard. Trace retrieval and external trace exporters are not part of the public beta API.18Use the [Tracing guide](https://developers.openai.com/api/docs/guides/agents-api/tracing) to inspect recorded model responses, tool calls, and subagent activity in the dashboard, or [export session traces](https://developers.openai.com/api/docs/guides/agents-api/tracing#export-session-traces) as OTLP JSON through the public API.

19 19 

20## Follow events and inspect session history20## Follow events and inspect session history

21 21 


397## Inspect a turn trace397## Inspect a turn trace

398 398 

399Use the Platform dashboard to inspect a completed turn and its agent activity.399Use the Platform dashboard to inspect a completed turn and its agent activity.

400Detailed trace retrieval is not available through an ordinary project API key. Dashboard trace endpoints require separate access and are not a400To retrieve recorded traces through the public API, use the [session trace export endpoint](https://developers.openai.com/api/docs/guides/agents-api/tracing#export-session-traces) with a project API key. Dashboard trace endpoints remain separate from the supported customer API.

401supported customer API.

402 401 

403Turn resources include best-effort `usage` and a `subagent_id` that identifies delegated work. Usage can be `null` when unknown and may change. See [Inspect subagent token usage](#inspect-subagent-token-usage).402Turn resources include best-effort `usage` and a `subagent_id` that identifies delegated work. Usage can be `null` when unknown and may change. See [Inspect subagent token usage](#inspect-subagent-token-usage).

404 403 

Details

21 21 

22Explore complete applications:22Explore complete applications:

23 23 

24- [Incident response agent](https://developers.openai.com/showcase/agents-api-sev-bot): investigate alerts and request approval for recovery actions.24- [Incident response agent](https://developers.openai.com/cookbook/examples/agents_api/apps/sev_bot/readme): investigate alerts and request approval for recovery actions.

25- [Slack bot](https://developers.openai.com/showcase/agents-api-slack-bot): investigate requests using connected workplace tools.25- [Slack bot](https://developers.openai.com/cookbook/examples/agents_api/apps/slack_bot/readme): investigate requests using connected workplace tools.

26- [Data analyst](https://developers.openai.com/showcase/agents-api-data-analyst): answer warehouse questions with read-only SQL.26- [Data analyst](https://developers.openai.com/cookbook/examples/agents_api/apps/data_analyst/readme): answer warehouse questions with read-only SQL.

27- [GitHub issue investigator](https://developers.openai.com/showcase/agents-api-github-issues): reproduce reported bugs and share findings on GitHub.27- Use the [GitHub issue investigator](https://github.com/openai/openai-cookbook/tree/main/examples/agents_api/apps/github_issues) to reproduce reported bugs and share findings on GitHub.

28- [Document reviewer](https://developers.openai.com/showcase/agents-api-document-review): review documents with policy skills and specialist agents.28- Use the [document reviewer](https://github.com/openai/openai-cookbook/tree/main/examples/agents_api/apps/document_review) to review documents with policy skills and specialist agents.

29 29 

30## Core concepts30## Core concepts

31 31 

Details

8 8 

9For session status, live events, saved output, and usage through the API, start with [Observability](https://developers.openai.com/api/docs/guides/agents-api/observability).9For session status, live events, saved output, and usage through the API, start with [Observability](https://developers.openai.com/api/docs/guides/agents-api/observability).

10 10 

11Tracing is enabled by default for new sessions. The public beta API does not expose tracing configuration or external trace exporters.11Tracing is enabled by default for new sessions. You can inspect traces in the dashboard or export them through the API.

12 12 

13## Open a trace13## Open a trace

14 14 


88 88 

89[Live session events](https://developers.openai.com/api/docs/guides/agents-api/sessions/events) show progress while the agent is still working.89[Live session events](https://developers.openai.com/api/docs/guides/agents-api/sessions/events) show progress while the agent is still working.

90 90 

91## Export session traces

92 

93Download session traces to inspect them in another tracing tool. The endpoint `GET /v1/agents/sessions/{session_id}/traces` returns a page of traces containing OpenTelemetry Protocol (OTLP) JSON.

94 

95Trace export must be enabled for your organization. Use an API key for the

96 session's project with either traces read permission (`api.traces.read`) or

97 the broader agents read permission (`api.agents.read`).

98 

99Set `OPENAI_API_KEY` and replace `sess_123` with your session ID. This example uses cURL and `jq` to save one page as `traces.otlp.json`:

100 

101Download a page of session traces

102 

103```bash

104curl --fail-with-body \

105 "https://api.openai.com/v1/agents/sessions/sess_123/traces?limit=20&order=asc" \

106 -H "Authorization: Bearer $OPENAI_API_KEY" \

107 -H "OpenAI-Beta: agents=v1" \

108 --output trace-page.json && \

109jq '{resourceSpans: [.data[].otlp.resourceSpans[]]}' trace-page.json > traces.otlp.json

110```

111 

112 

113The command combines the traces from that page into one OTLP payload. Send it to your tracing provider's OTLP/HTTP endpoint using the provider's authentication.

114 

115To export the whole session, check `trace-page.json`. When `has_more` is `true`, request the next page with `last_id` as `after`, keeping the same `order`. Save or upload each page before fetching the next, and repeat until `has_more` is `false`.

116 

117Exports include only traces available when you make each request. For a historical export, wait for the session's turns to finish and allow time for traces to appear. Exporting does not set up automatic delivery of future traces.

118 

119### Export traces for an agent

120 

121To export traces across an agent's sessions, first [list sessions](https://developers.openai.com/api/docs/guides/agents-api/sessions/manage#find-sessions) with the `agent_id` filter. Replace `agent_123` with your agent's ID:

122 

123Find sessions for an agent

124 

125```bash

126curl --fail-with-body \

127 "https://api.openai.com/v1/agents/sessions?agent_id=agent_123&limit=100&order=asc" \

128 -H "Authorization: Bearer $OPENAI_API_KEY" \

129 -H "OpenAI-Beta: agents=v1"

130```

131 

132 

1331. For each session in `data`, use its `id` to export every page of session traces as described above.

1342. When the session list has `has_more: true`, pass that list's `last_id` as `after` to fetch the next page. Keep the same `agent_id` and `order`.

1353. Repeat until the session list has `has_more: false`.

136 

137The filter matches the session's root agent. Keep the session-list cursor separate from each session's trace cursor.

138 

91## Example: One turn with two subagents139## Example: One turn with two subagents

92 140 

93This example is based on a recorded session. The root agent calls an MCP tool while two subagents run a command and fetch documents. The subagent names are simplified below; the counts and durations come from the recorded trace.141This example is based on a recorded session. The root agent calls an MCP tool while two subagents run a command and fetch documents. The subagent names are simplified below; the counts and durations come from the recorded trace.

Details

122- Use **hosted MCP** for public remote servers that fit the platform trust model.122- Use **hosted MCP** for public remote servers that fit the platform trust model.

123- Use **local or private MCP** when your runtime should own connectivity, filtering, or approvals.123- Use **local or private MCP** when your runtime should own connectivity, filtering, or approvals.

124 124 

125For the platform-wide concept, trust model, and product support story, keep [MCP and Connectors](https://developers.openai.com/api/docs/guides/tools-connectors-mcp) as the canonical reference.125For the platform-wide concept, trust model, and product support story, keep [MCP servers](https://developers.openai.com/api/docs/guides/tools-connectors-mcp) as the canonical reference.

126 126 

127## Tracing127## Tracing

128 128 

Details

2 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.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 4 

5{/* This guide necessarily discusses sexual abuse, so these profanity heuristics don't apply. */}5{"OpenAI developed this resource with expert input from the "}

6{/* vale alex.ProfanityMaybe = NO */}

7{/* vale alex.ProfanityUnlikely = NO */}

8{/* "Potentially" preserves uncertainty in classifier and policy language. */}

9{/* vale Microsoft.Adverbs = NO */}

10 

11 

12 

13 {"OpenAI developed this resource with expert input from the "}

14 {", "}6 {", "}

15 {", the "}7 {", the "}

16 {", and the "}8 {", and the "}

Details

2 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.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 4 

5OpenAI models can accept files as `input_file` items. In the Responses API, you can send a file as Base64-encoded data, a file ID returned by the Files API (`/v1/files`), or an external URL.5File input support depends on the API endpoint. The Responses API accepts the file types listed below as `input_file` items. Chat Completions accepts only PDF files as `file` content parts.

6 

7| Input method | Responses API | Chat Completions |

8| -------------------------------------- | --------------------------------- | ---------------- |

9| Base64-encoded file data (`file_data`) | Supported file types listed below | PDF only |

10| Uploaded file ID (`file_id`) | Supported file types listed below | PDF only |

11| External file URL (`file_url`) | Supported file types listed below | Not supported |

12 

13Use the Responses API for non-PDF file inputs. To use text from a file in Chat Completions, read the file in your application and send its contents as a `text` content part.

6 14 

7## How it works15## How it works

8 16 

9`input_file` processing depends on the file type:17In the Responses API, `input_file` processing depends on the file type:

10 18 

11- **PDF files**: On models with vision capabilities, such as `gpt-4o` and later models, the API extracts both text and page images and sends both to the model.19- **PDF files**: On models with vision capabilities, such as `gpt-4o` and later models, the API extracts both text and page images and sends both to the model.

12- **Non-PDF document and text files** (for example, `.docx`, `.pptx`, `.txt`, and code files): the API extracts text only.20- **Non-PDF document and text files** (for example, `.docx`, `.pptx`, `.txt`, and code files): the API extracts text only.


19 27 

20## Non-PDF image and chart limitations28## Non-PDF image and chart limitations

21 29 

22For non-PDF files, the API doesn't extract embedded images or charts into the30For non-PDF files, the Responses API doesn't extract embedded images or charts

23model context.31into the model context.

24 32 

25To preserve chart and diagram fidelity, convert the file to PDF first, then33To preserve chart and diagram fidelity, convert the file to PDF first, then

26send the PDF as `input_file`.34send the PDF as `input_file`.


28## How spreadsheet augmentation works36## How spreadsheet augmentation works

29 37 

30For spreadsheet-like files (such as `.xlsx`, `.xls`, `.csv`, `.tsv`, and38For spreadsheet-like files (such as `.xlsx`, `.xls`, `.csv`, `.tsv`, and

31`.iif`), `input_file` uses a spreadsheet-specific augmentation process.39`.iif`), the Responses API uses a spreadsheet-specific augmentation process.

32 40 

33Instead of passing entire sheets to the model, the API parses up to the first41Instead of passing entire sheets to the model, the API parses up to the first

341,000 rows per sheet and adds model-generated summary and header metadata so the421,000 rows per sheet and adds model-generated summary and header metadata so the


73 81 

74## Accepted file types82## Accepted file types

75 83 

76The following table lists common file types accepted in `input_file`. The full84The following table lists common file types accepted by the Responses API as

77list of extensions and MIME types appears later on this page.85`input_file` items. The full list of extensions and MIME types appears later on

86this page. Chat Completions supports only `.pdf` (`application/pdf`) for both

87`file_data` and `file_id`.

78 88 

79| Category | Common extensions |89| Category | Common extensions |

80| -------------- | --------------------------------------------------- |90| -------------- | --------------------------------------------------- |


836 846 

837## Full list of accepted file types847## Full list of accepted file types

838 848 

849This list applies to the Responses API. Chat Completions supports only `.pdf`

850(`application/pdf`) for both `file_data` and `file_id`.

851 

839| Category | Extensions | MIME types |852| Category | Extensions | MIME types |

840| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |853| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |

841| PDF files | PDF files (`.pdf`) | `application/pdf` |854| PDF files | PDF files (`.pdf`) | `application/pdf` |

Details

40 40 

41Choose the mode when you create the session; to change modes, start a new session.41Choose the mode when you create the session; to change modes, start a new session.

42 42 

43{/* prettier-ignore */}

44 

45 

46## Configure Responses delegation43## Configure Responses delegation

47 44 

48Add this delegation configuration when [creating your Live session](https://developers.openai.com/api/docs/guides/live). Choose the Responses model independently of the voice model:45Add this delegation configuration when [creating your Live session](https://developers.openai.com/api/docs/guides/live). Choose the Responses model independently of the voice model:


439 439 

440If a caller types an exact value, such as an order number, pass it to the backend that handles the task. A voice-only application does not need this path. Keep the typed value as user data rather than a live-model instruction.440If a caller types an exact value, such as an order number, pass it to the backend that handles the task. A voice-only application does not need this path. Keep the typed value as user data rather than a live-model instruction.

441 441 

442{/* prettier-ignore */}442 

443 

444

443 445 

444 446 

445With Responses delegation, queue a user message for the backend:447With Responses delegation, queue a user message for the backend:


499 504 

500To help a caller discuss a photo or screen, send the image and relevant context from your application to a vision-capable backend. The backend interprets the image and returns relevant text for GPT-Live to use in conversation. The Live audio frontend does not accept images directly.505To help a caller discuss a photo or screen, send the image and relevant context from your application to a vision-capable backend. The backend interprets the image and returns relevant text for GPT-Live to use in conversation. The Live audio frontend does not accept images directly.

501 506 

502{/* prettier-ignore */}507 

508 

509

503 510 

504 511 

505With Responses delegation, configure a vision-capable backend model. Queue a supported Responses image input item with `response.item.create`, then send `response.create` to run or resume backend work. Return all required pending function results before continuing. See [Handle Responses delegation](https://developers.openai.com/api/docs/guides/live-delegation?delegation-mode=responses#handle-responses-delegation).512With Responses delegation, configure a vision-capable backend model. Queue a supported Responses image input item with `response.item.create`, then send `response.create` to run or resume backend work. Return all required pending function results before continuing. See [Handle Responses delegation](https://developers.openai.com/api/docs/guides/live-delegation?delegation-mode=responses#handle-responses-delegation).


519 529 

520Reduce the time between a request for backend work and a useful result for the conversation. Measure [latency at each stage](https://developers.openai.com/api/docs/guides/voice-agents#measure-latency) to locate delays. Compare useful spoken response time and task success on the same scenarios, and see the [voice agent evaluation Cookbook](https://developers.openai.com/cookbook/examples/audio/voice_agent_evaluation) for evaluation guidance.530Reduce the time between a request for backend work and a useful result for the conversation. Measure [latency at each stage](https://developers.openai.com/api/docs/guides/voice-agents#measure-latency) to locate delays. Compare useful spoken response time and task success on the same scenarios, and see the [voice agent evaluation Cookbook](https://developers.openai.com/cookbook/examples/audio/voice_agent_evaluation) for evaluation guidance.

521 531 

522{/* prettier-ignore */}532 

533 

534

523 535 

524 536 

525### Responses delegation537### Responses delegation

Details

65 65 

66Call third-party tools and services. Connect with OpenAI connectors or third-party servers, or add your own server. MCP connections are helpful in a workflow that needs to read or search data in another application, like Gmail or Zapier.66Call third-party tools and services. Connect with OpenAI connectors or third-party servers, or add your own server. MCP connections are helpful in a workflow that needs to read or search data in another application, like Gmail or Zapier.

67 67 

68Browse options in the Agent Builder. To learn more about MCP, see the [connectors and MCP documentation](https://developers.openai.com/api/docs/guides/tools-connectors-mcp).68Browse options in the Agent Builder. To learn more about MCP, see the [MCP documentation](https://developers.openai.com/api/docs/guides/tools-connectors-mcp).

69 69 

70### Logic nodes70### Logic nodes

71 71 


97 97 

98#### Transform98#### Transform

99 99 

100Reshape outputs (e.g., object → array). Useful for enforcing types to adhere to your schema or reshaping outputs for agents to read and understand as inputs.100Reshape outputs (for example, object → array). Useful for enforcing types to adhere to your schema or reshaping outputs for agents to read and understand as inputs.

101 101 

102#### Set state102#### Set state

103 103 

Details

4 4 

5You can attach tools to a Realtime session so the model can look up data, take actions, or call services during a live conversation. Tool configuration uses the same event surface whether your client is using a [WebRTC data channel](https://developers.openai.com/api/docs/guides/voice-webrtc?api=realtime) or a [WebSocket](https://developers.openai.com/api/docs/guides/voice-websockets?api=realtime).5You can attach tools to a Realtime session so the model can look up data, take actions, or call services during a live conversation. Tool configuration uses the same event surface whether your client is using a [WebRTC data channel](https://developers.openai.com/api/docs/guides/voice-webrtc?api=realtime) or a [WebSocket](https://developers.openai.com/api/docs/guides/voice-websockets?api=realtime).

6 6 

7Use function tools when your application should execute the tool and return the result. Use MCP tools or built-in connectors when the Realtime API should connect to a remote tool server for you.7Use function tools when your application should execute the tool and return the result. Use MCP tools when the Realtime API should connect to a remote tool server for you.

8 8 

9## Choose a tool type9## Choose a tool type

10 10 


12| ------------------------- | ------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------- |12| ------------------------- | ------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------- |

13| `function` | Your application owns the business logic, approval checks, or private system access. | Your client or server receives a function call and returns `function_call_output`. |13| `function` | Your application owns the business logic, approval checks, or private system access. | Your client or server receives a function call and returns `function_call_output`. |

14| `mcp` with `server_url` | You want the model to call tools exposed by a remote MCP server. | The Realtime API calls the remote MCP server. |14| `mcp` with `server_url` | You want the model to call tools exposed by a remote MCP server. | The Realtime API calls the remote MCP server. |

15| `mcp` with `connector_id` | You want to use a built-in connector such as Google Calendar. | The Realtime API calls the connector with the authorization you provide. |15| `mcp` with `connector_id` | You use a legacy built-in connector with an existing model. | The Realtime API calls the connector with the authorization you provide. |

16 16 

17Add tools in **one of two places**:17Add tools in **one of two places**:

18 18 


165 165 

166## Configure an MCP tool166## Configure an MCP tool

167 167 

168MCP tools are useful when the tool already exists behind a remote MCP server, or when you want to use an OpenAI-managed connector. Unlike function tools, MCP tools are executed by the Realtime API itself.168MCP tools are useful when the tool already exists behind a remote MCP server, or when an existing model uses a legacy built-in connector. Unlike function tools, MCP tools are executed by the Realtime API itself.

169 169 

170In Realtime, the MCP tool shape is:170In Realtime, the MCP tool shape is:

171 171 


243```243```

244 244 

245 245 

246### Legacy connectors

247 

248`connector_id` is deprecated for models released after September 1,

249 2026. Use `server_url` to connect to a remote MCP server, or

250 `tunnel_id` to connect to a local MCP server through

251 [Secure MCP Tunnel](https://developers.openai.com/api/docs/guides/secure-mcp-tunnels). Existing

252 models retain connector support. The example below uses

253 `gpt-realtime-1.5`, which predates the cutoff.

254 

246Built-in connectors use the same MCP tool shape, but pass `connector_id`255Built-in connectors use the same MCP tool shape, but pass `connector_id`

247instead of `server_url`. For example, Google Calendar uses256instead of `server_url`. For example, Google Calendar uses

248`connector_googlecalendar`. In Realtime, use these built-in connectors for read257`connector_googlecalendar`. In Realtime, use these built-in connectors for read


257 type: "session.update",266 type: "session.update",

258 session: {267 session: {

259 type: "realtime",268 type: "realtime",

260 model: "gpt-realtime-2.1",269 model: "gpt-realtime-1.5",

261 output_modalities: ["text"],270 output_modalities: ["text"],

262 tools: [271 tools: [

263 {272 {


284 "type": "session.update",293 "type": "session.update",

285 "session": {294 "session": {

286 "type": "realtime",295 "type": "realtime",

287 "model": "gpt-realtime-2.1",296 "model": "gpt-realtime-1.5",

288 "output_modalities": ["text"],297 "output_modalities": ["text"],

289 "tools": [298 "tools": [

290 {299 {


307 316 

308connection.session.update(317connection.session.update(

309 type: :realtime,318 type: :realtime,

310 model: "gpt-realtime-2.1",319 model: "gpt-realtime-1.5",

311 output_modalities: [:text],320 output_modalities: [:text],

312 tools: [321 tools: [

313 {322 {

Details

1908 1908 

1909_For `text/` MIME types, the encoding must be one of `utf-8`, `utf-16`, or `ascii`._1909_For `text/` MIME types, the encoding must be one of `utf-8`, `utf-16`, or `ascii`._

1910 1910 

1911{/* Keep this table in sync with RETRIEVAL_SUPPORTED_EXTENSIONS in the agentapi service */}

1912 

1913| File format | MIME type |1911| File format | MIME type |

1914| ----------- | --------------------------------------------------------------------------- |1912| ----------- | --------------------------------------------------------------------------- |

1915| `.c` | `text/x-c` |1913| `.c` | `text/x-c` |

Details

22- Your MCP server runs on a private network, on-premises, on a developer machine, or behind existing access controls.22- Your MCP server runs on a private network, on-premises, on a developer machine, or behind existing access controls.

23- You want ChatGPT, Codex, the Responses API, or another supported OpenAI surface to use that server without making the MCP server public.23- You want ChatGPT, Codex, the Responses API, or another supported OpenAI surface to use that server without making the MCP server public.

24- Your network allows the host running `tunnel-client` to make outbound HTTPS requests to `api.openai.com:443` by default, or `mtls.api.openai.com:443` when control-plane mTLS is configured, and reach the private MCP server.24- Your network allows the host running `tunnel-client` to make outbound HTTPS requests to `api.openai.com:443` by default, or `mtls.api.openai.com:443` when control-plane mTLS is configured, and reach the private MCP server.

25- Start with the [MCP and Connectors guide](https://developers.openai.com/api/docs/guides/tools-connectors-mcp) for general MCP concepts.25- Start with the [MCP servers guide](https://developers.openai.com/api/docs/guides/tools-connectors-mcp) for general MCP concepts.

26 26 

27## How it works27## How it works

28 28 


191- Tunnel metadata changes are exposed through the API Platform [Audit logs](https://developers.openai.com/api/reference/resources/admin/subresources/organization/subresources/audit_logs) surface as `tunnel.created`, `tunnel.updated`, and `tunnel.deleted`.191- Tunnel metadata changes are exposed through the API Platform [Audit logs](https://developers.openai.com/api/reference/resources/admin/subresources/organization/subresources/audit_logs) surface as `tunnel.created`, `tunnel.updated`, and `tunnel.deleted`.

192- When ChatGPT reaches a custom app through Secure MCP Tunnel, the tunnel remains only the transport path. Normal app-level compliance logging still applies on the app path, including app invocation logs and app auth lifecycle logs such as `APP_AUTH_LOG` when the app is linked or unlinked.192- When ChatGPT reaches a custom app through Secure MCP Tunnel, the tunnel remains only the transport path. Normal app-level compliance logging still applies on the app path, including app invocation logs and app auth lifecycle logs such as `APP_AUTH_LOG` when the app is linked or unlinked.

193 193 

194## Advanced: allowlisted HTTP callouts194## Advanced: Allowlisted HTTP callouts

195 195 

196Secure MCP Tunnel can also support narrowly scoped HTTP callouts from supported agent or API flows into a customer network. `tunnel-client` includes an embedded MCP server, Harpoon, that exposes configured HTTP targets by label and lets callers invoke them through the tunnel with bounded request/response limits.196Secure MCP Tunnel can also support narrowly scoped HTTP callouts from supported agent or API flows into a customer network. `tunnel-client` includes an embedded MCP server, Harpoon, that exposes configured HTTP targets by label and lets callers invoke them through the tunnel with bounded request/response limits.

197 197 

Details

1# MCP and Connectors1# MCP servers

2 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.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 4 

5In addition to tools you make available to the model with [function calling](https://developers.openai.com/api/docs/guides/function-calling), you can give models new capabilities using **connectors** and **remote MCP servers**. These tools give the model the ability to connect to and control external services when needed to respond to a user's prompt. These tool calls can either be allowed automatically, or restricted with explicit approval required by you as the developer.5In addition to tools you make available to the model with [function calling](https://developers.openai.com/api/docs/guides/function-calling), you can give models new capabilities using **remote MCP servers** or **Secure MCP Tunnel**. These tools give the model the ability to connect to and control external services when needed to respond to a user's prompt. These tool calls can either be allowed automatically, or restricted with explicit approval required by you as the developer.

6 6 

7- **Connectors** are OpenAI-maintained MCP wrappers for popular services like Google Workspace or Dropbox, like the connectors available in [ChatGPT](https://chatgpt.com).

8- **Remote MCP servers** can be any server on the public Internet that implements a remote [Model Context Protocol](https://modelcontextprotocol.io/introduction) (MCP) server.7- **Remote MCP servers** can be any server on the public Internet that implements a remote [Model Context Protocol](https://modelcontextprotocol.io/introduction) (MCP) server.

9 8 

10This guide will show how to use both remote MCP servers and connectors with the Responses API. For Agents API sessions, see [MCP connections](https://developers.openai.com/api/docs/guides/agents-api/tools/mcp), which covers connections from the managed service or from your sandbox.9- **Secure MCP Tunnel** connects a local or private MCP server without exposing it to the public internet.

10 

11This guide shows how to use MCP tools with the Responses API. Built-in connectors remain supported for existing models; see [Legacy connectors](#connectors) for the deprecation policy and compatibility examples. For Agents API sessions, see [MCP connections](https://developers.openai.com/api/docs/guides/agents-api/tools/mcp), which covers connections from the managed service or from your sandbox.

11 12 

12## Secure MCP Tunnel13## Secure MCP Tunnel

13 14 


15 16 

16## Quickstart17## Quickstart

17 18 

18Check out the examples below to see how remote MCP servers and connectors work through the [Responses API](https://developers.openai.com/api/reference/resources/responses/methods/create). Both connectors and remote MCP servers can be used with the `mcp` built-in tool type.19Use the `mcp` tool type in the [Responses API](https://developers.openai.com/api/reference/resources/responses/methods/create). Set `server_url` for a remote MCP server, or use `tunnel_id` for a local MCP server through [Secure MCP Tunnel](https://developers.openai.com/api/docs/guides/secure-mcp-tunnels). Depending on the server, you may also need an OAuth access token in the `authorization` parameter.

19 

20 

21 

22Using remote MCP servers

23 

24

25 20 

26 Remote MCP servers require a `server_url`. Depending on the server,21Using a remote MCP server in the Responses API

27 you may also need an OAuth `authorization` parameter containing an

28 access token.

29

30 

31 

32 Using a remote MCP server in the Responses API

33 22 

34```bash23```bash

35curl https://api.openai.com/v1/responses \ 24curl https://api.openai.com/v1/responses \


196```185```

197 186 

198 187 

199 It is very important that developers trust any remote MCP server they use with188It is very important that developers trust any remote MCP server they use with

200 the Responses API. A malicious server can exfiltrate sensitive data from189 the Responses API. A malicious server can exfiltrate sensitive data from

201 anything that enters the model's context. Carefully review the 190 anything that enters the model's context. Carefully review the

202 **Risks and Safety** section below before using this tool.191 **Risks and Safety** section below before using this tool.

203 192 

204 193The API will return new items in the `output` array of the model response. If the model decides to use an MCP server, it will first make a request to list available tools from the server, which will create a `mcp_list_tools` output item. From the remote MCP server example above, it contains only one tool definition:

205 

206

207 

208

209Using connectors

210 

211

212 

213 Connectors require a `connector_id` parameter, and an OAuth access

214 token provided by your application in the `authorization` parameter.

215

216 

217 

218 Using connectors in the Responses API

219 

220```bash

221curl https://api.openai.com/v1/responses \

222-H "Content-Type: application/json" \

223-H "Authorization: Bearer $OPENAI_API_KEY" \

224-d '{

225 "model": "gpt-6-astra",

226 "tools": [

227 {

228 "type": "mcp",

229 "server_label": "Dropbox",

230 "connector_id": "connector_dropbox",

231 "authorization": "<oauth access token>",

232 "require_approval": "never"

233 }

234 ],

235 "input": "Summarize the Q2 earnings report."

236 }'

237```

238 

239```javascript

240import OpenAI from "openai";

241const client = new OpenAI();

242 

243const resp = await client.responses.create({

244 model: "gpt-6-astra",

245 tools: [

246 {

247 type: "mcp",

248 server_label: "Dropbox",

249 connector_id: "connector_dropbox",

250 authorization: "<oauth access token>",

251 require_approval: "never",

252 },

253 ],

254 input: "Summarize the Q2 earnings report.",

255});

256 

257console.log(resp.output_text);

258```

259 

260```python

261import os

262 

263from openai import OpenAI

264 

265client = OpenAI()

266connector_authorization = os.environ["OPENAI_CONNECTOR_AUTHORIZATION"]

267 

268resp = client.responses.create(

269 model="gpt-6-astra",

270 tools=[

271 {

272 "type": "mcp",

273 "server_label": "Dropbox",

274 "connector_id": "connector_dropbox",

275 "authorization": connector_authorization,

276 "require_approval": "never",

277 },

278 ],

279 input="Summarize the Q2 earnings report.",

280)

281 

282print(resp.output_text)

283```

284 

285```go

286package main

287 

288import (

289 "context"

290 "fmt"

291 

292 "github.com/openai/openai-go/v3"

293 "github.com/openai/openai-go/v3/responses"

294)

295 

296func main() {

297 client := openai.NewClient()

298 tool := responses.ToolParamOfMcp("Dropbox")

299 tool.OfMcp.ConnectorID = "connector_dropbox"

300 tool.OfMcp.Authorization = openai.String("<oauth access token>")

301 tool.OfMcp.RequireApproval = responses.ToolMcpRequireApprovalUnionParam{OfMcpToolApprovalSetting: openai.String("never")}

302 

303 response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{

304 Model: "gpt-6-astra",

305 Tools: []responses.ToolUnionParam{tool},

306 Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("Summarize the Q2 earnings report.")},

307 })

308 if err != nil {

309 panic(err)

310 }

311 fmt.Println(response.OutputText())

312}

313```

314 

315```java

316import com.openai.client.OpenAIClient;

317import com.openai.client.okhttp.OpenAIOkHttpClient;

318import com.openai.models.responses.ResponseCreateParams;

319import com.openai.models.responses.Tool;

320 

321String oauthAccessToken = "<oauth access token>";

322 

323ResponseCreateParams params =

324 ResponseCreateParams.builder()

325 .model("gpt-6-astra")

326 .input("Summarize the Q2 earnings report.")

327 .addTool(

328 Tool.Mcp.builder()

329 .serverLabel("Dropbox")

330 .connectorId(Tool.Mcp.ConnectorId.of("connector_dropbox"))

331 .authorization(oauthAccessToken)

332 .requireApproval(Tool.Mcp.RequireApproval.McpToolApprovalSetting.NEVER)

333 .build())

334 .build();

335 

336client.responses().create(params).output().stream()

337 .flatMap(item -> item.message().stream())

338 .flatMap(message -> message.content().stream())

339 .flatMap(content -> content.outputText().stream())

340 .forEach(text -> System.out.println(text.text()));

341```

342 

343```csharp

344using OpenAI.Responses;

345#pragma warning disable OPENAI001

346 

347string dropboxToken =

348 Environment.GetEnvironmentVariable("DROPBOX_OAUTH_ACCESS_TOKEN")!;

349string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;

350ResponsesClient client = new(key);

351 

352CreateResponseOptions options = new() { Model = "gpt-6-astra" };

353options.Tools.Add(

354 ResponseTool.CreateMcpTool(

355 serverLabel: "Dropbox",

356 connectorId: McpToolConnectorId.Dropbox,

357 authorizationToken: dropboxToken,

358 toolCallApprovalPolicy: DefaultMcpToolCallApprovalPolicy.NeverRequireApproval

359 )

360);

361options.InputItems.Add(

362 ResponseItem.CreateUserMessageItem("Summarize the Q2 earnings report.")

363);

364 

365ResponseResult response = await client.CreateResponseAsync(options);

366 

367Console.WriteLine(response.GetOutputText());

368```

369 

370```ruby

371require "openai"

372 

373client = OpenAI::Client.new

374response = client.responses.create(

375 model: "gpt-6-astra",

376 input: "Summarize the Q2 earnings report.",

377 tools: [

378 {

379 type: :mcp,

380 server_label: "Dropbox",

381 connector_id: "connector_dropbox",

382 authorization: "<oauth access token>",

383 require_approval: :never

384 }

385 ]

386)

387 

388puts(response.output_text)

389```

390 

391 

392 

393The API will return new items in the `output` array of the model response. If the model decides to use a Connector or MCP server, it will first make a request to list available tools from the server, which will create a `mcp_list_tools` output item. From the remote MCP server example above, it contains only one tool definition:

394 194 

395```json195```json

396{196{


437 237 

438## How it works238## How it works

439 239 

440The MCP tool (for both remote MCP servers and connectors) is available in the [Responses API](https://developers.openai.com/api/reference/resources/responses/methods/create) in most recent models. Check MCP tool compatibility for your model [here](https://developers.openai.com/api/docs/models). When you're using the MCP tool, you only pay for [tokens](https://developers.openai.com/api/docs/pricing) used when importing tool definitions or making tool calls. No additional fees apply per tool call.240The MCP tool is available in the [Responses API](https://developers.openai.com/api/reference/resources/responses/methods/create) in most recent models. Check MCP tool compatibility for your model [here](https://developers.openai.com/api/docs/models). When you're using the MCP tool, you only pay for [tokens](https://developers.openai.com/api/docs/pricing) used when importing tool definitions or making tool calls. No additional fees apply per tool call.

441 241 

442Below, we'll step through the process the API takes when calling an MCP tool.242Below, we'll step through the process the API takes when calling an MCP tool.

443 243 


1292 1092 

1293To prevent the leakage of sensitive tokens, the Responses API does not store the value you provide in the `authorization` field. This value will also not be visible in the Response object created. Because of this, you must send the `authorization` value in every Responses API creation request you make.1093To prevent the leakage of sensitive tokens, the Responses API does not store the value you provide in the `authorization` field. This value will also not be visible in the Response object created. Because of this, you must send the `authorization` value in every Responses API creation request you make.

1294 1094 

1295## Connectors1095<a id="connectors"></a>

1096 

1097## Legacy connectors

1098 

1099`connector_id` is deprecated for models released after September 1,

1100 2026. Use `server_url` to connect to a remote MCP server, or

1101 `tunnel_id` to connect to a local MCP server through

1102 [Secure MCP Tunnel](https://developers.openai.com/api/docs/guides/secure-mcp-tunnels). Existing

1103 models retain connector support. The examples in this section use

1104 `gpt-5.2`, which predates the cutoff.

1296 1105 

1297The Responses API has built-in support for a limited set of connectors to third-party services. These connectors let you pull in context from popular applications, like Dropbox and Gmail, to allow the model to interact with popular services.1106The Responses API has built-in support for a limited set of connectors to third-party services. These connectors let you pull in context from popular applications, like Dropbox and Gmail, to allow the model to interact with popular services.

1298 1107 

1299Connectors can be used in the same way as remote MCP servers. Both let an OpenAI model access additional third-party tools in an API request. However, instead of passing a `server_url` as you would to call a remote MCP server, you pass a `connector_id` which uniquely identifies a connector available in the API.1108Connectors can be used in the same way as remote MCP servers. Both let an OpenAI model access additional third-party tools in an API request. However, instead of passing a `server_url` as you would to call a remote MCP server, you pass a `connector_id` which uniquely identifies a connector available in the API.

1300 1109 

1110Connectors require an OAuth access token provided by your application in the `authorization` parameter.

1111 

1112Use a legacy connector with GPT-5.2

1113 

1114```bash

1115curl https://api.openai.com/v1/responses \

1116-H "Content-Type: application/json" \

1117-H "Authorization: Bearer $OPENAI_API_KEY" \

1118-d '{

1119 "model": "gpt-5.2",

1120 "tools": [

1121 {

1122 "type": "mcp",

1123 "server_label": "Dropbox",

1124 "connector_id": "connector_dropbox",

1125 "authorization": "<oauth access token>",

1126 "require_approval": "never"

1127 }

1128 ],

1129 "input": "Summarize the Q2 earnings report."

1130 }'

1131```

1132 

1133```javascript

1134import OpenAI from "openai";

1135const client = new OpenAI();

1136 

1137const resp = await client.responses.create({

1138 model: "gpt-5.2",

1139 tools: [

1140 {

1141 type: "mcp",

1142 server_label: "Dropbox",

1143 connector_id: "connector_dropbox",

1144 authorization: "<oauth access token>",

1145 require_approval: "never",

1146 },

1147 ],

1148 input: "Summarize the Q2 earnings report.",

1149});

1150 

1151console.log(resp.output_text);

1152```

1153 

1154```python

1155import os

1156 

1157from openai import OpenAI

1158 

1159client = OpenAI()

1160connector_authorization = os.environ["OPENAI_CONNECTOR_AUTHORIZATION"]

1161 

1162resp = client.responses.create(

1163 model="gpt-5.2",

1164 tools=[

1165 {

1166 "type": "mcp",

1167 "server_label": "Dropbox",

1168 "connector_id": "connector_dropbox",

1169 "authorization": connector_authorization,

1170 "require_approval": "never",

1171 },

1172 ],

1173 input="Summarize the Q2 earnings report.",

1174)

1175 

1176print(resp.output_text)

1177```

1178 

1179```go

1180package main

1181 

1182import (

1183 "context"

1184 "fmt"

1185 

1186 "github.com/openai/openai-go/v3"

1187 "github.com/openai/openai-go/v3/responses"

1188)

1189 

1190func main() {

1191 client := openai.NewClient()

1192 tool := responses.ToolParamOfMcp("Dropbox")

1193 tool.OfMcp.ConnectorID = "connector_dropbox"

1194 tool.OfMcp.Authorization = openai.String("<oauth access token>")

1195 tool.OfMcp.RequireApproval = responses.ToolMcpRequireApprovalUnionParam{OfMcpToolApprovalSetting: openai.String("never")}

1196 

1197 response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{

1198 Model: "gpt-5.2",

1199 Tools: []responses.ToolUnionParam{tool},

1200 Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("Summarize the Q2 earnings report.")},

1201 })

1202 if err != nil {

1203 panic(err)

1204 }

1205 fmt.Println(response.OutputText())

1206}

1207```

1208 

1209```java

1210import com.openai.client.OpenAIClient;

1211import com.openai.client.okhttp.OpenAIOkHttpClient;

1212import com.openai.models.responses.ResponseCreateParams;

1213import com.openai.models.responses.Tool;

1214 

1215String oauthAccessToken = "<oauth access token>";

1216 

1217ResponseCreateParams params =

1218 ResponseCreateParams.builder()

1219 .model("gpt-5.2")

1220 .input("Summarize the Q2 earnings report.")

1221 .addTool(

1222 Tool.Mcp.builder()

1223 .serverLabel("Dropbox")

1224 .connectorId(Tool.Mcp.ConnectorId.of("connector_dropbox"))

1225 .authorization(oauthAccessToken)

1226 .requireApproval(Tool.Mcp.RequireApproval.McpToolApprovalSetting.NEVER)

1227 .build())

1228 .build();

1229 

1230client.responses().create(params).output().stream()

1231 .flatMap(item -> item.message().stream())

1232 .flatMap(message -> message.content().stream())

1233 .flatMap(content -> content.outputText().stream())

1234 .forEach(text -> System.out.println(text.text()));

1235```

1236 

1237```csharp

1238using OpenAI.Responses;

1239#pragma warning disable OPENAI001

1240 

1241string dropboxToken =

1242 Environment.GetEnvironmentVariable("DROPBOX_OAUTH_ACCESS_TOKEN")!;

1243string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;

1244ResponsesClient client = new(key);

1245 

1246CreateResponseOptions options = new() { Model = "gpt-5.2" };

1247options.Tools.Add(

1248 ResponseTool.CreateMcpTool(

1249 serverLabel: "Dropbox",

1250 connectorId: McpToolConnectorId.Dropbox,

1251 authorizationToken: dropboxToken,

1252 toolCallApprovalPolicy: DefaultMcpToolCallApprovalPolicy.NeverRequireApproval

1253 )

1254);

1255options.InputItems.Add(

1256 ResponseItem.CreateUserMessageItem("Summarize the Q2 earnings report.")

1257);

1258 

1259ResponseResult response = await client.CreateResponseAsync(options);

1260 

1261Console.WriteLine(response.GetOutputText());

1262```

1263 

1264```ruby

1265require "openai"

1266 

1267client = OpenAI::Client.new

1268response = client.responses.create(

1269 model: "gpt-5.2",

1270 input: "Summarize the Q2 earnings report.",

1271 tools: [

1272 {

1273 type: :mcp,

1274 server_label: "Dropbox",

1275 connector_id: "connector_dropbox",

1276 authorization: "<oauth access token>",

1277 require_approval: :never

1278 }

1279 ]

1280)

1281 

1282puts(response.output_text)

1283```

1284 

1285 

1301### Available connectors1286### Available connectors

1302 1287 

1303- Dropbox: `connector_dropbox`1288- Dropbox: `connector_dropbox`


1334 -H "Content-Type: application/json" \1319 -H "Content-Type: application/json" \

1335 -H "Authorization: Bearer $OPENAI_API_KEY" \1320 -H "Authorization: Bearer $OPENAI_API_KEY" \

1336 -d '{1321 -d '{

1337 "model": "gpt-6-astra",1322 "model": "gpt-5.2",

1338 "tools": [1323 "tools": [

1339 {1324 {

1340 "type": "mcp",1325 "type": "mcp",


1353const client = new OpenAI();1338const client = new OpenAI();

1354 1339 

1355const resp = await client.responses.create({1340const resp = await client.responses.create({

1356 model: "gpt-6-astra",1341 model: "gpt-5.2",

1357 tools: [1342 tools: [

1358 {1343 {

1359 type: "mcp",1344 type: "mcp",


1377authorization = os.environ["GOOGLE_CALENDAR_OAUTH_ACCESS_TOKEN"]1362authorization = os.environ["GOOGLE_CALENDAR_OAUTH_ACCESS_TOKEN"]

1378 1363 

1379resp = client.responses.create(1364resp = client.responses.create(

1380 model="gpt-6-astra",1365 model="gpt-5.2",

1381 tools=[1366 tools=[

1382 {1367 {

1383 "type": "mcp",1368 "type": "mcp",


1412 tool.OfMcp.RequireApproval = responses.ToolMcpRequireApprovalUnionParam{OfMcpToolApprovalSetting: openai.String("never")}1397 tool.OfMcp.RequireApproval = responses.ToolMcpRequireApprovalUnionParam{OfMcpToolApprovalSetting: openai.String("never")}

1413 1398 

1414 response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{1399 response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{

1415 Model: "gpt-6-astra",1400 Model: "gpt-5.2",

1416 Tools: []responses.ToolUnionParam{tool},1401 Tools: []responses.ToolUnionParam{tool},

1417 Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("What's on my Google Calendar for today?")},1402 Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("What's on my Google Calendar for today?")},

1418 })1403 })


1433 1418 

1434ResponseCreateParams params =1419ResponseCreateParams params =

1435 ResponseCreateParams.builder()1420 ResponseCreateParams.builder()

1436 .model("gpt-6-astra")1421 .model("gpt-5.2")

1437 .input("What's on my Google Calendar for today?")1422 .input("What's on my Google Calendar for today?")

1438 .addTool(1423 .addTool(

1439 Tool.Mcp.builder()1424 Tool.Mcp.builder()


1460string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;1445string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;

1461ResponsesClient client = new(key);1446ResponsesClient client = new(key);

1462 1447 

1463CreateResponseOptions options = new() { Model = "gpt-6-astra" };1448CreateResponseOptions options = new() { Model = "gpt-5.2" };

1464options.Tools.Add(1449options.Tools.Add(

1465 ResponseTool.CreateMcpTool(1450 ResponseTool.CreateMcpTool(

1466 serverLabel: "google_calendar",1451 serverLabel: "google_calendar",


1483 1468 

1484client = OpenAI::Client.new1469client = OpenAI::Client.new

1485response = client.responses.create(1470response = client.responses.create(

1486 model: "gpt-6-astra",1471 model: "gpt-5.2",

1487 input: "What's on my Google Calendar for today?",1472 input: "What's on my Google Calendar for today?",

1488 tools: [1473 tools: [

1489 {1474 {

Details

783- Give tools specific names and descriptions so the model can compose them correctly.783- Give tools specific names and descriptions so the model can compose them correctly.

784- Require application-level approval before high-impact actions, regardless of the caller.784- Require application-level approval before high-impact actions, regardless of the caller.

785 785 

786{/* vale Vale.Terms = NO */}

787 

788## Evaluate Programmatic Tool Calling786## Evaluate Programmatic Tool Calling

789 787 

790Programmatic Tool Calling can reduce the amount of intermediate tool output added to model context, but the effect depends on the task and tool responses. Start with direct tool calling as a baseline, then compare both approaches on representative tasks.788Programmatic Tool Calling can reduce the amount of intermediate tool output added to model context, but the effect depends on the task and tool responses. Start with direct tool calling as a baseline, then compare both approaches on representative tasks.

791 789 

792Define the final-answer quality bar and required evidence before measuring efficiency. Evaluate token use and tool calls alongside correctness, completeness, and evidence coverage, and make any accepted quality tradeoff explicit.790Define the final-answer quality bar and required evidence before measuring efficiency. Evaluate token use and tool calls alongside correctness, completeness, and evidence coverage, and make any accepted quality tradeoff explicit.

793 791 

794{/* vale Vale.Terms = YES */}

795 

796Measure:792Measure:

797 793 

798- Final-answer correctness, completeness, and evidence coverage.794- Final-answer correctness, completeness, and evidence coverage.

Details

25 25 

26- **OpenAI API:** Continue to [Use workload identity with the OpenAI26- **OpenAI API:** Continue to [Use workload identity with the OpenAI

27 API](#use-workload-identity-with-the-openai-api).27 API](#use-workload-identity-with-the-openai-api).

28- **Codex:** Follow [Use workload identity with28- **Codex:** See [Use workload identity with Codex](#use-workload-identity-with-codex).

29 Codex](https://developers.openai.com/codex/enterprise/workload-identity) for the complete Admin Portal and

30 runtime setup.

31 29 

32Administrators can also [manage Codex providers and rules with the Admin30See the [Codex

33API](https://developers.openai.com/api/docs/guides/workload-identity-federation/admin-api). See the [Codex

34federation rule31federation rule

35reference](https://developers.openai.com/api/docs/guides/workload-identity-federation/federation-rules) for32reference](https://developers.openai.com/api/docs/guides/workload-identity-federation/federation-rules) for

36rule and lifecycle behavior.33rule and lifecycle behavior.


358 workspace. To request access, contact your OpenAI representative or [OpenAI355 workspace. To request access, contact your OpenAI representative or [OpenAI

359 Support](https://help.openai.com/en/articles/6614161-how-can-i-contact-support).356 Support](https://help.openai.com/en/articles/6614161-how-can-i-contact-support).

360 357 

361Follow [Use workload identity with358The [federation rule

362Codex](https://developers.openai.com/codex/enterprise/workload-identity) for the complete administrator and

363runtime procedure. It covers provider-specific token sources, federation rules,

364the required token-file configuration, credential precedence, supported Codex

365surfaces, rotation, and verification. For optional audit attribution, Codex

366accepts `OPENAI_WORKLOAD_IDENTITY_CONTEXT`; the Codex guide defines its schema,

367privacy limits, and audit behavior.

368 

369Use the [Admin

370API](https://developers.openai.com/api/docs/guides/workload-identity-federation/admin-api) to manage Codex

371providers and rules programmatically. The [federation rule

372reference](https://developers.openai.com/api/docs/guides/workload-identity-federation/federation-rules)359reference](https://developers.openai.com/api/docs/guides/workload-identity-federation/federation-rules)

373explains how one rule can accept more than one external subject while mapping to one360explains how one rule can accept more than one external subject while mapping to one

374ChatGPT principal.361ChatGPT principal.


416 403 

417## Related docs404## Related docs

418 405 

419- [Use workload identity with Codex](https://developers.openai.com/codex/enterprise/workload-identity)

420- [Codex federation rule reference](https://developers.openai.com/api/docs/guides/workload-identity-federation/federation-rules)406- [Codex federation rule reference](https://developers.openai.com/api/docs/guides/workload-identity-federation/federation-rules)

421- [Manage Codex workload identity with the Admin API](https://developers.openai.com/api/docs/guides/workload-identity-federation/admin-api)

422- [Workload identity token exchange reference](https://developers.openai.com/api/reference/workload-identity-federation)407- [Workload identity token exchange reference](https://developers.openai.com/api/reference/workload-identity-federation)

423- [Codex authentication](https://developers.openai.com/codex/auth)408- [Codex authentication](https://developers.openai.com/codex/auth)

424- [Codex environment variables](https://developers.openai.com/codex/config-file/environment-variables)409- [Codex environment variables](https://developers.openai.com/codex/config-file/environment-variables)

guides/workload-identity-federation/admin-api.md +0 −348 deleted

File Deleted View Diff

1# Manage Codex workload identity with the Admin API

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 the organization Admin API to manage Codex workload identity providers and

6federation rules from infrastructure tooling or CI. The API exposes the same

7provider and rule model as the OpenAI Admin Portal.

8 

9The API calls federation rules `mappings` in paths and response objects. This

10page uses **federation rule** for the product concept and `mapping` only when it

11refers to an API field or path.

12 

13These endpoints manage the Codex workload identity federation beta for managed

14 ChatGPT workspaces. To request access, contact your OpenAI representative or

15 [OpenAI

16 Support](https://help.openai.com/en/articles/6614161-how-can-i-contact-support).

17 These endpoints do not replace the existing OpenAI API workload identity

18 provider and service account mapping APIs.

19 

20## Prerequisites

21 

22You need:

23 

24- Workload identity federation enabled for your organization and managed

25 ChatGPT workspace.

26- An [Admin API key](https://platform.openai.com/settings/organization/admin-keys)

27 whose owner is an active administrator allowed to manage workload identity.

28- The ID of the managed ChatGPT workspace.

29- The OpenAI user ID of an existing active human or service account in that

30 workspace.

31- The issuer, audience, and claims for the workload's OIDC token or SPIFFE

32 JWT-SVID.

33 

34The WIF endpoints use resource IDs instead of names. They do not list or create

35ChatGPT workspaces or principals. Supply those IDs from your provisioning system.

36If you do not manage those resources programmatically, use the OpenAI Admin

37Portal to create or select the principal and connect that workload.

38 

39Set the Admin API key in your environment:

40 

41```bash

42export OPENAI_ADMIN_KEY="<admin-api-key>"

43```

44 

45Admin API keys are long-lived credentials. Store the key in a secrets manager,

46do not commit it, and do not use it for Codex runtime authentication.

47 

48## Endpoints

49 

50All requests use `https://api.openai.com` and an Admin API key in the bearer

51authorization header.

52 

53| Operation | Method and path |

54| ---------------------------- | ----------------------------------------------------------------------------------------- |

55| List providers | `GET /v1/organization/workload_identity/providers` |

56| Create a provider | `POST /v1/organization/workload_identity/providers` |

57| Get a provider | `GET /v1/organization/workload_identity/providers/{provider_id}` |

58| Update or disable a provider | `POST /v1/organization/workload_identity/providers/{provider_id}` |

59| Archive a provider | `DELETE /v1/organization/workload_identity/providers/{provider_id}` |

60| List rules | `GET /v1/organization/workload_identity/providers/{provider_id}/mappings` |

61| Create a rule | `POST /v1/organization/workload_identity/providers/{provider_id}/mappings` |

62| Get a rule | `GET /v1/organization/workload_identity/providers/{provider_id}/mappings/{mapping_id}` |

63| Update or disable a rule | `POST /v1/organization/workload_identity/providers/{provider_id}/mappings/{mapping_id}` |

64| Archive a rule | `DELETE /v1/organization/workload_identity/providers/{provider_id}/mappings/{mapping_id}` |

65 

66List responses use `{ "object": "list", "data": [...] }`. The endpoints do

67not use pagination.

68 

69## Create an OIDC provider

70 

71Create one provider for each issuer and trust boundary that you want to manage

72independently. Replace the example issuer and audience with exact values from a

73sample token. Inspect the token's `iat` and `exp` claims locally, then choose an

74accepted assertion lifetime that covers the issuer's expected `exp - iat`

75range. OpenAI checks that full duration, not the token's remaining validity.

76 

77For Microsoft Entra, do not assume a one-hour assertion. [Access-token lifetimes

78vary](https://learn.microsoft.com/en-us/entra/identity-platform/access-tokens#token-lifetime),

79and Microsoft does not support [configuring managed-identity token

80lifetimes](https://learn.microsoft.com/en-us/entra/identity-platform/configurable-token-lifetimes).

81Replace `MAX_ASSERTION_LIFETIME_SECONDS` with an approved integer from 1 through

82176,400. This provider limit is separate from the lifetime of the OpenAI access

83token that a federation rule issues.

84 

85```bash

86MAX_ASSERTION_LIFETIME_SECONDS="<accepted-issuer-lifetime-seconds>"

87 

88jq -n \

89 --argjson max_assertion_lifetime_seconds "$MAX_ASSERTION_LIFETIME_SECONDS" \

90 '{

91 name: "entra-production",

92 type: "oidc",

93 issuer: "https://login.microsoftonline.com/00000000-0000-0000-0000-000000000000/v2.0",

94 audience: "api://openai-codex-production",

95 description: "Production Codex workloads in Microsoft Azure",

96 max_assertion_lifetime_seconds: $max_assertion_lifetime_seconds,

97 check_jti: true

98 }' > provider.json

99 

100curl --fail-with-body --silent --show-error \

101 https://api.openai.com/v1/organization/workload_identity/providers \

102 -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \

103 -H "Content-Type: application/json" \

104 --data @provider.json \

105 --output provider-response.json

106 

107PROVIDER_ID="$(jq -r .id provider-response.json)"

108printf 'Created provider %s\n' "$PROVIDER_ID"

109```

110 

111Expected output begins with an identity-provider ID:

112 

113```text

114Created provider idp_...

115```

116 

117By default, an OIDC provider uses discovery at its issuer URL. Use `custom_url`

118when the public discovery document lives elsewhere, `jwks_uri` for an

119explicit public JWKS URL, or `jwks_local: true` with `jwks` to upload public

120keys. Do not include private key material.

121 

122## Create a SPIFFE JWT-SVID provider

123 

124Set `type` to `spiffe_jwt`, set `issuer` to the canonical trust domain, and

125provide either a public bundle URL or an uploaded SPIFFE bundle. A SPIFFE rule

126must also set `audiences`.

127 

128```json

129{

130 "name": "spiffe-production",

131 "type": "spiffe_jwt",

132 "issuer": "spiffe://example.com",

133 "jwks_uri": "https://spiffe.example.com/bundle.json",

134 "max_assertion_lifetime_seconds": 3600,

135 "check_jti": true

136}

137```

138 

139For an uploaded bundle, set `jwks_local` to `true`, replace `jwks_uri` with the

140`jwks` object, and include at least one public key whose `use` is `jwt-svid`.

141 

142## Create a federation rule

143 

144A rule targets one existing principal and can match one or many external

145workload identities. This example accepts one Azure managed identity subject:

146 

147```bash

148export WORKSPACE_ID="<managed-chatgpt-workspace-id>"

149export PRINCIPAL_ID="<existing-openai-user-id>"

150 

151jq -n \

152 --arg workspace_id "$WORKSPACE_ID" \

153 --arg principal_id "$PRINCIPAL_ID" \

154 '{

155 name: "entra-payments-production",

156 description: "Production payments workload",

157 workspace_id: $workspace_id,

158 principal_id: $principal_id,

159 external_subject: "11111111-2222-3333-4444-555555555555",

160 audiences: ["api://openai-codex-production"],

161 access_token_lifetime_seconds: 600,

162 enabled: true

163 }' > rule.json

164 

165curl --fail-with-body --silent --show-error \

166 "https://api.openai.com/v1/organization/workload_identity/providers/$PROVIDER_ID/mappings" \

167 -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \

168 -H "Content-Type: application/json" \

169 --data @rule.json \

170 --output rule-response.json

171 

172FEDERATION_RULE_ID="$(jq -r .id rule-response.json)"

173printf 'Created federation rule %s\n' "$FEDERATION_RULE_ID"

174```

175 

176Expected output begins with a mapping ID. This is the value Codex uses as

177`OPENAI_FEDERATION_RULE_ID`:

178 

179```text

180Created federation rule idpm_...

181```

182 

183For a set of allowed subjects in one rule, omit `external_subject` and use a CEL

184condition:

185 

186```json

187{

188 "condition": "assertion.sub in [\"workload-a\", \"workload-b\"]"

189}

190```

191 

192Set at least one of `external_subject`, `claims`, or `condition`. All configured

193identity checks must pass. See the [federation rule

194reference](https://developers.openai.com/api/docs/guides/workload-identity-federation/federation-rules) for

195cardinality, CEL, audience, scope, and lifetime behavior.

196 

197## List and reconcile resources

198 

199List providers before creating one so your automation can compare the intended

200configuration with the current state:

201 

202```bash

203curl --fail-with-body --silent --show-error \

204 https://api.openai.com/v1/organization/workload_identity/providers \

205 -H "Authorization: Bearer $OPENAI_ADMIN_KEY" | jq .

206```

207 

208Then list rules under a provider:

209 

210```bash

211curl --fail-with-body --silent --show-error \

212 "https://api.openai.com/v1/organization/workload_identity/providers/$PROVIDER_ID/mappings" \

213 -H "Authorization: Bearer $OPENAI_ADMIN_KEY" | jq .

214```

215 

216The API does not define an idempotency-key contract. Store returned IDs in your

217approved configuration state, read the current resource before changing it,

218and update by ID. Do not create a replacement on every run.

219 

220## Update or disable a resource

221 

222Updates use `POST` with only the fields you want to change. This example changes

223the rule lifetime:

224 

225```bash

226curl --fail-with-body --silent --show-error \

227 -X POST \

228 "https://api.openai.com/v1/organization/workload_identity/providers/$PROVIDER_ID/mappings/$FEDERATION_RULE_ID" \

229 -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \

230 -H "Content-Type: application/json" \

231 -d '{"access_token_lifetime_seconds": 300}' | jq .

232```

233 

234Disable a rule for an immediate stop:

235 

236```bash

237curl --fail-with-body --silent --show-error \

238 -X POST \

239 "https://api.openai.com/v1/organization/workload_identity/providers/$PROVIDER_ID/mappings/$FEDERATION_RULE_ID" \

240 -H "Authorization: Bearer $OPENAI_ADMIN_KEY" \

241 -H "Content-Type: application/json" \

242 -d '{"enabled": false}' | jq .

243```

244 

245Set `enabled` to `false` on the provider path to stop every rule under that

246provider. Disablement blocks new exchanges and revokes access tokens issued

247through the resource. You can turn it back on after its principal, workspace,

248binding, and provider are active.

249 

250Ordinary rule edits affect only new exchanges. Tokens issued before the edit can

251remain valid until their TTL ends. Provider trust edits revoke issued tokens

252before the new trust takes effect.

253 

254## Archive a resource

255 

256`DELETE` archives a provider or rule instead of erasing it. Archival blocks new

257exchanges, revokes issued tokens, hides the resource from normal list results,

258and cannot be undone.

259 

260Archive a rule:

261 

262```bash

263curl --fail-with-body --silent --show-error \

264 -X DELETE \

265 "https://api.openai.com/v1/organization/workload_identity/providers/$PROVIDER_ID/mappings/$FEDERATION_RULE_ID" \

266 -H "Authorization: Bearer $OPENAI_ADMIN_KEY"

267```

268 

269Archive a provider:

270 

271```bash

272curl --fail-with-body --silent --show-error \

273 -X DELETE \

274 "https://api.openai.com/v1/organization/workload_identity/providers/$PROVIDER_ID" \

275 -H "Authorization: Bearer $OPENAI_ADMIN_KEY"

276```

277 

278Archiving a provider revokes access for its Codex rules. You must remove any

279non-Codex product mapping before you can archive that provider. This protects

280existing OpenAI API workload identity configuration.

281 

282## Provider fields

283 

284Create requires `name` and `issuer`. Update accepts the mutable fields except

285`type`.

286 

287| Field | Type and behavior |

288| -------------------------------- | ---------------------------------------------------------------------------------------------------------------- |

289| `name` | Non-empty display name. |

290| `type` | `oidc` by default, or `spiffe_jwt`. You cannot change it after creation. |

291| `issuer` | Exact OIDC `iss` URL or canonical SPIFFE trust domain. |

292| `audience` | Optional provider-level audience. Set a rule audience when this is absent. |

293| `description` | Optional administrator description. |

294| `custom_url` | Optional public HTTPS OIDC discovery URL. OIDC only. |

295| `jwks_uri` | Optional public HTTPS JWKS or SPIFFE bundle URL. |

296| `jwks_local` | Set to `true` when supplying `jwks`. |

297| `jwks` | Uploaded public JWKS object, up to 100 keys and 1 MiB. |

298| `custom_ca_certificate` | Optional PEM CA bundle for JWKS HTTPS, up to 256 KiB. |

299| `attribute_conditions` | Optional bounded CEL condition applied before rule matching. Use `assertion` for the verified claims. |

300| `max_assertion_lifetime_seconds` | Accepted upstream assertion lifetime, 1 through 176,400 seconds. OIDC uses the full `exp - iat`. Default: 3,600. |

301| `check_jti` | When `true`, reject a repeated non-empty JWT `jti`. Default: `false`. |

302| `enabled` | Update-only switch that accepts or blocks exchanges. |

303 

304Discovery and explicit or uploaded keys are alternative verification modes.

305Issuer, discovery, and JWKS URLs have validation requirements described in the

306[workload identity overview](https://developers.openai.com/api/docs/guides/workload-identity-federation#manage-jwks-and-key-rotation).

307 

308## Federation rule fields

309 

310Create requires `workspace_id` and `principal_id`, plus at least one identity

311check. You cannot change the workspace or principal after creation.

312 

313| Field | Type and behavior |

314| ------------------------------- | ---------------------------------------------------------------------------------------------------- |

315| `workspace_id` | Existing managed ChatGPT workspace ID. Create-only. |

316| `principal_id` | Existing active OpenAI user or service-account ID in the workspace. Create-only. |

317| `external_subject` | Exact `sub` or one trailing-`*` prefix, up to 4,096 bytes. |

318| `claims` | Up to 32 exact top-level scalar claims. Do not include `sub`. |

319| `audiences` | One through 32 unique accepted audiences. Required for SPIFFE and when the provider has no audience. |

320| `condition` | Bounded CEL boolean condition over `assertion`, up to 16 KiB. |

321| `scopes` | Optional subset of the four supported Codex scopes. Omit to use the default set. |

322| `access_token_lifetime_seconds` | 60 through 3,600 seconds. Default: 3,600. |

323| `name` | Optional display name. |

324| `description` | Optional administrator description. |

325| `enabled` | Whether the rule accepts exchanges. Default: `true`. |

326 

327Provider responses use `workload_identity_provider`; rule responses use

328`workload_identity_mapping`. Both include `id`, `enabled`, `created_at`, and

329`updated_at`. Timestamps are Unix seconds.

330 

331## Limits and errors

332 

333An organization can have up to 50 non-archived providers. A provider can have up

334to 50 non-archived rules. The API returns:

335 

336- `400` for request field errors, provider trust settings, rule conditions, scopes, or

337 inactive principal membership.

338- `403` when the Admin API key owner cannot manage workload identity.

339- `404` when the organization has no tenant association or the requested

340 resource is outside the organization and tenant boundary.

341- `409` for provider or rule limits, subject conflicts, inactive bindings, or

342 lifecycle conflicts.

343 

344Treat `404` as non-disclosing: the service does not reveal a provider or rule

345owned by another organization or tenant. Retry transient `429` and `5xx`

346responses with bounded delays that increase after each attempt. Do not retry a

347validation or permission error without changing the request or administrator

348state.

Details

7- **AWS outbound identity federation:** Exchange an AWS STS-issued OIDC JWT from `GetWebIdentityToken` for a short-lived OpenAI access token.7- **AWS outbound identity federation:** Exchange an AWS STS-issued OIDC JWT from `GetWebIdentityToken` for a short-lived OpenAI access token.

8- **Amazon EKS:** Exchange a projected Amazon EKS service account token for a short-lived OpenAI access token.8- **Amazon EKS:** Exchange a projected Amazon EKS service account token for a short-lived OpenAI access token.

9 9 

10For Codex, use this page to get and inspect the AWS token. Then [configure Codex workload identity](https://developers.openai.com/codex/enterprise/workload-identity) to write that token to a file and point Codex to it. The service-account mapping and SDK examples on this page apply to the OpenAI API.

11 

12OpenAI supports AWS-issued OIDC JWTs from outbound identity federation and10OpenAI supports AWS-issued OIDC JWTs from outbound identity federation and

13 Kubernetes projected service account tokens issued by Amazon EKS. OpenAI does11 Kubernetes projected service account tokens issued by Amazon EKS. OpenAI does

14 not support SigV4-signed requests or AWS STS temporary access key credentials12 not support SigV4-signed requests or AWS STS temporary access key credentials

Details

11subject or a CEL condition. You can also create more than one rule for the same11subject or a CEL condition. You can also create more than one rule for the same

12principal.12principal.

13 13 

14For the setup procedure, see [Use workload identity with

15Codex](https://developers.openai.com/codex/enterprise/workload-identity). To manage rules with code, see the

16[workload identity Admin

17API](https://developers.openai.com/api/docs/guides/workload-identity-federation/admin-api).

18 

19## Rule model14## Rule model

20 15 

21| Part | Purpose |16| Part | Purpose |

Details

4 4 

5Use GitHub Actions as a Workload Identity Provider by exchanging a GitHub-issued OIDC token for a short-lived OpenAI access token. This lets workflows authenticate to the OpenAI API without storing a long-lived API key in GitHub secrets.5Use GitHub Actions as a Workload Identity Provider by exchanging a GitHub-issued OIDC token for a short-lived OpenAI access token. This lets workflows authenticate to the OpenAI API without storing a long-lived API key in GitHub secrets.

6 6 

7For Codex, use this page to get and inspect the GitHub token. Then [configure Codex workload identity](https://developers.openai.com/codex/enterprise/workload-identity) to write that token to a file and point Codex to it. The service-account mapping and SDK examples on this page apply to the OpenAI API.

8 

9GitHub can mint a signed OIDC JWT for a workflow job that has `id-token: write` permission and requests an identity token. OpenAI validates the token issuer, audience, signature, and mapping attributes before issuing an OpenAI access token.7GitHub can mint a signed OIDC JWT for a workflow job that has `id-token: write` permission and requests an identity token. OpenAI validates the token issuer, audience, signature, and mapping attributes before issuing an OpenAI access token.

10 8 

11## Setting up GitHub Actions9## Setting up GitHub Actions

Details

7- **Google workload identity:** Exchange a Google-signed OIDC token issued to an attached Google service account for a short-lived OpenAI access token.7- **Google workload identity:** Exchange a Google-signed OIDC token issued to an attached Google service account for a short-lived OpenAI access token.

8- **Google Kubernetes Engine:** Exchange a projected GKE service account token for a short-lived OpenAI access token.8- **Google Kubernetes Engine:** Exchange a projected GKE service account token for a short-lived OpenAI access token.

9 9 

10For Codex, use this page to get and inspect the Google token. Then [configure Codex workload identity](https://developers.openai.com/codex/enterprise/workload-identity) to write that token to a file and point Codex to it. The service-account mapping and SDK examples on this page apply to the OpenAI API.

11 

12 10 

13 11 

14## Google workload identity12## Google workload identity

Details

4 4 

5Use Kubernetes as a Workload Identity Provider by exchanging a projected Kubernetes service account token for a short-lived OpenAI access token.5Use Kubernetes as a Workload Identity Provider by exchanging a projected Kubernetes service account token for a short-lived OpenAI access token.

6 6 

7For Codex, use this page to get and inspect the projected token. Then [configure Codex workload identity](https://developers.openai.com/codex/enterprise/workload-identity) to point Codex to the mounted token file. The service-account mapping and SDK examples on this page apply to the OpenAI API.

8 

9## Setting up Kubernetes7## Setting up Kubernetes

10 8 

11This guide assumes Kubernetes service account token projection is enabled, which is available by default in modern Kubernetes releases. OpenAI workload identity federation requires OIDC-compatible projected service account tokens. Legacy Kubernetes service account tokens stored in Secrets are not supported.9This guide assumes Kubernetes service account token projection is enabled, which is available by default in modern Kubernetes releases. OpenAI workload identity federation requires OIDC-compatible projected service account tokens. Legacy Kubernetes service account tokens stored in Secrets are not supported.

Details

7- **Azure managed identity:** Exchange a Microsoft Entra ID access token issued for a managed identity for a short-lived OpenAI access token.7- **Azure managed identity:** Exchange a Microsoft Entra ID access token issued for a managed identity for a short-lived OpenAI access token.

8- **AKS:** Exchange a projected Azure Kubernetes Service (AKS) service account token for a short-lived OpenAI access token.8- **AKS:** Exchange a projected Azure Kubernetes Service (AKS) service account token for a short-lived OpenAI access token.

9 9 

10For Codex, use this page to get and inspect the Microsoft Entra token. Then [configure Codex workload identity](https://developers.openai.com/codex/enterprise/workload-identity) to write that token to a file and point Codex to it. The service-account mapping and SDK examples on this page apply to the OpenAI API.

11 

12 10 

13 11 

14## Azure managed identity12## Azure managed identity


373lifetimes](https://learn.microsoft.com/en-us/entra/identity-platform/access-tokens#token-lifetime)371lifetimes](https://learn.microsoft.com/en-us/entra/identity-platform/access-tokens#token-lifetime)

374and does not support [configuring managed-identity token372and does not support [configuring managed-identity token

375lifetimes](https://learn.microsoft.com/en-us/entra/identity-platform/configurable-token-lifetimes).373lifetimes](https://learn.microsoft.com/en-us/entra/identity-platform/configurable-token-lifetimes).

376See the [Admin API provider

377example](https://developers.openai.com/api/docs/guides/workload-identity-federation/admin-api#create-an-oidc-provider).

378 374 

379Managed identity tokens can also contain claims such as `azp`, `oid`, `sub`, or `xms_mirid`. Use the decoded token as the source of truth, and choose claims that identify the exact managed identity and resource boundary you trust.375Managed identity tokens can also contain claims such as `azp`, `oid`, `sub`, or `xms_mirid`. Use the decoded token as the source of truth, and choose claims that identify the exact managed identity and resource boundary you trust.

380 376 

Details

4 4 

5Use Oracle Cloud Infrastructure (OCI) as a Workload Identity Provider by exchanging an Oracle Identity Cloud Service (IDCS) access token for a short-lived OpenAI access token. An OCI instance principal signs a token exchange request to an identity domain in the same tenancy. OpenAI validates the resulting token and authorizes the OCI workload to act as a mapped OpenAI service account.5Use Oracle Cloud Infrastructure (OCI) as a Workload Identity Provider by exchanging an Oracle Identity Cloud Service (IDCS) access token for a short-lived OpenAI access token. An OCI instance principal signs a token exchange request to an identity domain in the same tenancy. OpenAI validates the resulting token and authorizes the OCI workload to act as a mapped OpenAI service account.

6 6 

7For Codex, use this page to get and inspect the Oracle token. Then [configure Codex workload identity](https://developers.openai.com/codex/enterprise/workload-identity) to write that token to a file and point Codex to it. The service-account mapping and SDK examples on this page apply to the OpenAI API.

8 

9This setup does not require an OpenAI API key, a custom Oracle OAuth resource application, or dynamic group grants to a custom application.7This setup does not require an OpenAI API key, a custom Oracle OAuth resource application, or dynamic group grants to a custom application.

10 8 

11## Set up the OCI workload9## Set up the OCI workload

Details

4 4 

5Use SPIFFE as a Workload Identity Provider by exchanging a SPIFFE JWT-SVID for a short-lived OpenAI access token. This lets workloads authenticated by SPIRE or another SPIFFE-compatible identity provider call the OpenAI API without storing long-lived API keys.5Use SPIFFE as a Workload Identity Provider by exchanging a SPIFFE JWT-SVID for a short-lived OpenAI access token. This lets workloads authenticated by SPIRE or another SPIFFE-compatible identity provider call the OpenAI API without storing long-lived API keys.

6 6 

7For Codex, use this page to get and inspect the JWT-SVID. Then [configure Codex workload identity](https://developers.openai.com/codex/enterprise/workload-identity) to write that token to a file and point Codex to it. The service-account mapping and SDK examples on this page apply to the OpenAI API.

8 

9OpenAI supports SPIFFE JWT-SVIDs that can be validated as JWT subject tokens with an issuer, audience, expiration, issued-at timestamp, and JWKS-backed signature. OpenAI doesn't support SPIFFE X.509-SVIDs as workload identity federation subject tokens.7OpenAI supports SPIFFE JWT-SVIDs that can be validated as JWT subject tokens with an issuer, audience, expiration, issued-at timestamp, and JWKS-backed signature. OpenAI doesn't support SPIFFE X.509-SVIDs as workload identity federation subject tokens.

10 8 

11The JWT-SVID specification requires the `sub`, `aud`, and `exp` claims. To use a JWT-SVID with OpenAI, the token must also include `iss` and `iat` claims and a `kid` header so OpenAI can validate the token against the Workload Identity Provider configuration.9The JWT-SVID specification requires the `sub`, `aud`, and `exp` claims. To use a JWT-SVID with OpenAI, the token must also include `iss` and `iat` claims and a `kid` header so OpenAI can validate the token against the Workload Identity Provider configuration.

Details

5X.509 workload identity federation lets a workload exchange an identity from a TLS client certificate for a short-lived OpenAI access token. The workload then calls the OpenAI API with both the access token and an accepted client certificate. This flow replaces the API key, not the client certificate.5X.509 workload identity federation lets a workload exchange an identity from a TLS client certificate for a short-lived OpenAI access token. The workload then calls the OpenAI API with both the access token and an accepted client certificate. This flow replaces the API key, not the client certificate.

6 6 

7X.509 workload identity federation is available for the OpenAI API. Codex does7X.509 workload identity federation is available for the OpenAI API. Codex does

8 not support it. For Codex, use an OIDC token or SPIFFE JWT-SVID and follow the8 not support it. For Codex, use an OIDC token or SPIFFE JWT-SVID.

9 [Codex workload identity guide](https://developers.openai.com/codex/enterprise/workload-identity).

10 9 

11For token exchange request and response details, see the [workload identity token exchange reference](https://developers.openai.com/api/reference/workload-identity-federation#exchange-an-x509-certificate). For Mutual TLS permissions, certificate requirements, activation, mTLS hosts, and rotation, see the [Mutual TLS guide](https://developers.openai.com/api/docs/guides/mutual-tls).10For token exchange request and response details, see the [workload identity token exchange reference](https://developers.openai.com/api/reference/workload-identity-federation#exchange-an-x509-certificate). For Mutual TLS permissions, certificate requirements, activation, mTLS hosts, and rotation, see the [Mutual TLS guide](https://developers.openai.com/api/docs/guides/mutual-tls).

12 11 

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.63.3</version>176 <version>4.65.0</version>

177</dependency>177</dependency>

178```178```

179 179 

quickstart.md +1 −2

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.63.3</version>193 <version>4.65.0</version>

194</dependency>194</dependency>

195```195```

196 196 


357 Go to billing357 Go to billing

358 358 

359 359 

360{/* prettier-ignore */}

361 360 

362Congrats on running a free test API request! Start building real applications with higher limits and use [our models](https://developers.openai.com/api/docs/models) to generate text, audio, images, videos and more.361Congrats on running a free test API request! Start building real applications with higher limits and use [our models](https://developers.openai.com/api/docs/models) to generate text, audio, images, videos and more.

363 362