> ## Documentation Index
> Fetch the complete documentation index at: https://docs.opal.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# OpenAI and ChatGPT

> Connect OpenAI to Opal to bring OpenAI agents, service accounts, and ChatGPT user agents into Agent Inventory.

> [!NOTE]
>
> OpenAI and ChatGPT agent sync is part of [Agent Inventory](/docs/agent-inventory), which is currently in limited beta. Contact Opal support to enable it for your organization.

One OpenAI connection in Opal can bring agents into [Agent Inventory](/docs/agent-inventory) from three places. Each place uses its own credential, and you add only the ones you need.

| Part | What Opal reads | Credential |
| - | - | - |
| OpenAI API Platform | Service accounts, their API keys, and the people in your OpenAI organization | Organization Admin API key (`sk-admin-...`) |
| OpenAI Agents API | Agent definitions, the tools they declare including MCP servers, and the vault credentials they hold. Opal also reads sessions where your key is allowed to. | Project API key or service account key (`sk-proj-...` or `sk-svcacct-...`) with the `api.agents.read` and `api.vaults.read` scopes |
| ChatGPT Enterprise | The people who have a ChatGPT seat, which Opal turns into ChatGPT user agents, and the custom GPTs that people have published | Workspace Admin key from the ChatGPT Admin Console |

The Admin API key is required to create the connection. The Agents API key and the ChatGPT credential are optional. If you have no ChatGPT Enterprise workspace, leave the ChatGPT fields empty.

## Requirements

Before you begin, you must:

* Be an Opal Admin
* Have agent governance enabled for your organization by Opal
* Be able to create an Admin API key in your OpenAI organization

To read agents from the OpenAI Agents API, you must also be able to create a key in the OpenAI project that holds those agents.

To create ChatGPT user agents, you must have a ChatGPT Enterprise, Edu, or Healthcare workspace. OpenAI states that only a workspace owner can grant broad compliance access, so ask a workspace owner to create the ChatGPT key.

## What Opal reads

The parts on this page only read from OpenAI. Opal calls OpenAI's list endpoints and does not create, change, or delete anything in OpenAI through them.

**OpenAI API Platform.** Opal reads your projects and the service accounts in them. For each API key, it reads the name, ID, creation date, last used date, expiry, and the service account or person that owns the key. For each member of your OpenAI organization, it reads the name, email address, and role.

**OpenAI Agents API.** For each agent, Opal reads the name, model, and instructions. It shows the model and a shortened version of the instructions, up to 280 characters, as the agent's purpose.

Opal also reads each tool an agent declares. For an MCP server, it reads the label, the server URL or command, the transport, whether the server is required, the credential the server names, and the `allowed_tools` list. A missing `allowed_tools` list means the agent can call every tool on that server, and Opal records it that way.

For each vault credential, Opal reads the name, vault, authentication method, the MCP server URL the credential applies to, the expiry, and whether the credential can refresh itself.

Where your key is allowed to read sessions, Opal reads each session's status, start and last activity times, the vault credentials attached to it, the environment and its network policy, the turn count, token usage, and model.

**ChatGPT Enterprise.** For each person with a seat, Opal reads the user ID, name, email address, workspace role, status, and creation date. If the key also has the Users read permission, Opal reads the seat type and whether SCIM manages the seat. For each custom GPT that people have published in the workspace, Opal reads the ID, name, description, and author.

**What Opal does not read.** Opal does not read the secret value of an API key or a vault credential. It does not read ChatGPT conversations, messages, uploaded files, or memories, and it does not call the endpoints that return them. It does not show when a person last used ChatGPT, because the user endpoints OpenAI provides do not return a last-active time. It does not read a custom GPT's instructions, files, or tool settings.

## 1. Create the Admin API key

The Admin API key is an organization-level key (`sk-admin-...`). Opal uses it to read service accounts, API keys, and the people in your organization.

If you already created an Admin API key for the [OpenAI Platform](/integrations/openai) integration, you can use that key. Otherwise, create one as described on that page and in OpenAI's [Admin API keys reference](https://platform.openai.com/docs/api-reference/admin-api-keys).

A project key (`sk-proj-...`) or a service account key (`sk-svcacct-...`) is refused here. The Admin API key also cannot list agents, whatever permissions you give it. Agents come from the Agents API key in the next step.

> [!WARNING]
>
> OpenAI shows the key once. Save it before you leave the page.

## 2. Create the Agents API key (optional)

Skip this step if you do not use the OpenAI Agents API.

In the OpenAI project that holds your agents, create a project API key or a service account. Give it these scopes:

| Scope | Used for |
| - | - |
| `api.agents.read` | Listing agents and their tools |
| `api.vaults.read` | Listing the vault credentials that agents hold |

You need one key that carries both scopes, not two keys. A project API key or a service account key can carry both. The scopes decide what Opal can read. OpenAI describes both scopes in its [vaults guide](https://developers.openai.com/api/docs/guides/agents-api/tools/vaults).

Agents belong to a project. A key created in a different project than the one that holds your agents returns an empty list instead of an error. Create the key in the project that holds the agents you want Opal to read.

Session reading needs a scope that OpenAI has not documented. Opal reads sessions only where the key is allowed to. The Sessions tab on an agent shows whether Opal could read them. If you want sessions and Opal cannot read them with the two scopes above, widen the key's permissions in OpenAI and sync again.

## 3. Create the ChatGPT Admin key (optional)

Skip this step if you do not use ChatGPT Enterprise, Edu, or Healthcare.

> [!NOTE]
>
> This setup follows OpenAI's published API reference. Opal has not verified it against a live ChatGPT Enterprise workspace, so your first sync is the first live check. If a call fails, the sync reports which part failed. See [Troubleshooting](#troubleshooting).

In the ChatGPT Admin Console, go to **Credentials** > **Admin keys** and create a key for the workspace you want Opal to read. Give it these permissions:

| Scope | Required | Used for |
| - | - | - |
| `chatgpt.enterprise.compliance_export` | Yes | Listing workspace users and custom GPTs |
| `chatgpt.enterprise.user.read` (Users read) | No | Listing current members, with seat type and SCIM status. OpenAI offers this permission only where it is available. |

When you create the key, choose when it expires: no expiry, 30, 60, or 90 days, or a custom number of days. Copy the key when the Admin Console shows it.

> [!WARNING]
>
> A key stops working if it expires, if it is revoked, if the person who created it loses the required workspace access, or if that person's account is deactivated. Create the key from an account that will keep its workspace access. Before you revoke a key that is still in use, create a replacement and update Opal.

An Admin key belongs to one workspace. It does not reach other workspaces or your OpenAI API Platform organization. If you run several ChatGPT workspaces, create one Opal connection for each workspace.

Next, copy the workspace ID. In ChatGPT, open your profile menu and go to **Workspace settings** > **General**. Copy the **Workspace identifier**.

For more detail, see OpenAI's article [Managing Admin keys in Admin Console](https://help.openai.com/en/articles/20001407).

## 4. Add the credentials in Opal

To create a new connection:

1. In Opal, go to **Inventory** > **+ App** and select **OpenAI Platform**.
2. Fill in the fields in the table below.
3. Save the app.

To add keys to a connection you already have, find the app in **Inventory**, open its **Setup** tab, and select **Edit**.

| Field | Value |
| - | - |
| App name | An identifiable name for the connection |
| App admin | The owner of this app in Opal |
| Description | A short description of the account |
| Admin API key | Required. The `sk-admin-...` key from [step 1](#1-create-the-admin-api-key). |
| Agents API key | Optional. The key from [step 2](#2-create-the-agents-api-key-optional), with both scopes on one key. |
| Sync agents daily | Selected by default. See [Turn off automatic agent creation](#turn-off-automatic-agent-creation). This checkbox appears when agent governance is enabled for your organization. |
| ChatGPT Compliance API key | Optional. Paste the workspace Admin key from [step 3](#3-create-the-chatgpt-admin-key-optional) here. |
| ChatGPT workspace identifier | The workspace ID from step 3. Required if you add the ChatGPT key. |
| Visibility | Global, or restricted to specific groups |

You need both ChatGPT fields or neither. If only one is filled in, Opal skips ChatGPT and tells you the credential is incomplete.

## First sync

Saving the app does not create agents. A sync creates them. To run the first sync now instead of waiting for the daily sync, go to **Inventory** > **Agents**, select **Sync from connectors**, and choose your OpenAI connection.

The first sync reads each part that has a credential on the connection:

* **Agents API:** Opal creates one agent for each OpenAI agent, with its declared tools and the vault credentials it holds.
* **API Platform:** Opal creates an agent for each service account, with its API keys. It also reads the people in your OpenAI organization, and you choose which of them to bring in as agents.
* **ChatGPT Enterprise:** Opal lists the people who have a seat in the workspace, and you choose which of them to bring in as ChatGPT user agents. It records the custom GPTs each person has published.
* **Sessions:** Opal reads the sessions of the Agents API agents it created, where the key allows it.

When the sync finishes, Opal shows a message with the number of agents it synced. If a part did not run or could not read everything, the message names that part and says what to change. See [Troubleshooting](#troubleshooting).

## Daily sync

When **Sync agents daily** is selected, Opal repeats the sync once a day for the connection. The daily sync covers Agents API agents, their vault credentials, ChatGPT user agents, and the people in your OpenAI organization, using the keys stored on the connection.

* Unlike a manual sync, the daily sync adds new people without a review step. It creates a ChatGPT user agent for every person with a seat in the workspace, and an agent for every member of your OpenAI organization, that the keys can read. A large workspace adds many agents at once. It refreshes the agents it already created, including their tools, credentials, workspace role, and seat status.
* Opal sets the owner and sponsor of each new person's agent from their email address. The Opal user with that email becomes the sponsor, and the agent goes to that person's owner. If the person has no owner, Opal creates one named after them. If no Opal user has that email, the agent goes to the connection's admin owner and has no sponsor. Opal sets these when it creates the agent, so a change you make later is kept.
* If you delete an agent that the daily sync created, the daily sync does not create it again. A manual sync can.
* A part is skipped without a message when its credential is not on the connection. A connection with no Agents API key skips agents and vault credentials. A connection with no ChatGPT credential skips ChatGPT user agents. The people in your OpenAI organization need only the Admin API key, so they sync on every connection.
* If one part fails, the others still run. The failed part tries again the next day.
* Opal sets an agent's tier when it creates the agent. A tier you change later is kept by later syncs.

## What shows up in Opal

Agents from OpenAI appear in **Inventory** > **Agents** with the source **OpenAI**.

| Where it comes from | Harness | Tier | Why |
| - | - | - | - |
| Agents API agent | OpenAI | Autonomous, or Orchestrator when the agent has subagents enabled | The agent runs through the API |
| API Platform service account | OpenAI | Autonomous | The service account authenticates with API keys |
| Person in your OpenAI organization | OpenAI | Supervised | A person is the one operating it |
| ChatGPT user agent | ChatGPT | Supervised | A person works in a chat window, so a human is in the loop |

Opal infers a ChatGPT user agent from each person's seat, and names it after the person, for example "Jane Doe's ChatGPT". Its purpose shows the person's workspace role. If the workspace export lists a person whose seat is inactive, the purpose says so.

Opal does not create an agent for each custom GPT. A GPT runs with the access of whoever uses it, so Opal records it as something its author published, as part of the author's ChatGPT user agent.

On an agent's page:

* The **MCP connectors** tab lists **Declared MCP servers** for Agents API agents. Each server shows its endpoint, transport, tool allow-list, and the credential that would authorize it. A server with no allow-list is marked **All tools**, because the agent can call every tool that server offers.
* The **Keys** tab has two sections. **Authenticate as this agent** lists the API keys that act as the agent. **Credentials this agent holds** lists vault credentials, with their method, destination, and expiry.
* The **Sessions** tab appears only for Agents API agents, because the other sources have no sessions. It shows each session's status, times, credentials, environment, network, turns, tokens, and model. A session whose sandbox has network access and no host allow-list is marked **Unrestricted**.

In the tab list, Sessions with no count means Opal did not read sessions. A count of zero means Opal read them and found none.

## Turn off automatic agent creation

The daily sync is the only part that creates agents without someone selecting Sync. To turn it off, clear **Sync agents daily**. You choose this when you add the connection. The same checkbox is on the app's **Setup** tab if you change your mind later.

With the checkbox cleared:

* Opal stops the daily sync for that connection. Agents are created and updated only when someone selects Sync.
* You can still sync manually from **Inventory** > **Agents** > **Sync from connectors**.

To keep ChatGPT user agents out of the inventory but still sync your API agents, leave the two ChatGPT fields empty.

## Troubleshooting

### OpenAI rejected the ChatGPT workspace Admin key

The sync reports that OpenAI rejected the key (HTTP 401) and that the people in your workspace were not read. The usual causes are:

* The key expired or was revoked.
* The person who created the key lost the required workspace access.
* The creator's account was deactivated.
* The key was not copied in full.

In the ChatGPT Admin Console, open **Credentials** > **Admin keys** to see the key's status, expiration, and creator. Create a replacement key with the same permissions, paste it into the app's **Setup** tab in Opal, and sync again. Create the replacement before you revoke the old key so anything else that uses the old key keeps working.

### The Agents API key is missing or was refused

If the sync says the connection has no Agents API key, add one in the app's **Setup** tab. A key in the **Admin API key** field does not count, because the Admin API key cannot list agents.

If the sync says the key was refused, the message names the scope to add:

* Refused by the agents endpoint: add `api.agents.read`.
* Refused by the vaults endpoint: add `api.vaults.read`.

These are separate scopes. A key that lists agents can still be refused for vault credentials. Add the missing scope to the same key and sync again.

### The sync finds no agents

The sync reports "No agents were found" and names the project Opal is reading. Agents belong to a project, and a key from a different project returns an empty list instead of an error.

After a sync, the app's **Setup** tab shows the project under the Agents API key as **Reading project**. If that is not the project that holds your agents, create a key in the right project, replace the key in Opal, and sync again.

When no agents are found, the sync also reports that no vault credentials were found. Many organizations have no vaults, so the vault message does not mean something is wrong by itself.

### Only part of the ChatGPT workspace was read

Opal reads people from two places, the compliance export and the current members list, and combines the results. If one of them cannot be read, the sync still completes and tells you which one failed.

* **The compliance export was refused (HTTP 403).** The key does not have `chatgpt.enterprise.compliance_export`. Opal reads people from the members list only. It adds and updates people, but it does not remove anyone until it can read the export in full, so someone who left the workspace may still appear. Opal also cannot read custom GPTs. Ask a workspace owner to create a key that has the permission.
* **The members list was refused (HTTP 403).** The key does not have Users read. Opal reads everyone in the export, but it does not collect seat type or SCIM status. This permission is optional. Add it to the key where the Admin Console offers it.
* **The key can read the export but not the GPT list.** Opal reads the people and leaves the custom GPT information as unknown.

### OpenAI says the workspace was not found

The sync reports HTTP 404. OpenAI documents this response for a workspace it cannot find and for a feature that is not available. Check the **ChatGPT workspace identifier** on the connection. If the identifier is correct, the Admin API may not be available for that workspace.

### The ChatGPT credential is incomplete

Opal needs both the ChatGPT key and the workspace identifier. Add the missing field in the app's **Setup** tab and sync again.

### Sessions are not read

The Sessions tab explains why Opal did not read sessions:

* The connection has no Agents API key. Add one.
* OpenAI refused the key on the sessions endpoint. OpenAI has not documented the scope that sessions need, so widen the key's permissions in OpenAI and sync again.
* Opal has not read sessions for the connection yet. Run a sync.

### No agents appeared after I saved the app

Saving the app does not create agents. Run a sync from **Inventory** > **Agents** > **Sync from connectors**, or wait for the daily sync. If you do not see the **Sync agents daily** checkbox on the app, agent governance is not enabled for your organization. Contact Opal support.

## Revoke access

Opal reads from OpenAI with the keys you created, so you control its access in OpenAI.

* **Admin API key:** Revoke it in your OpenAI organization's Admin API keys. See OpenAI's [Admin API keys reference](https://platform.openai.com/docs/api-reference/admin-api-keys).
* **Agents API key:** Delete the key, or the service account that owns it, in the OpenAI project.
* **ChatGPT Admin key:** In the ChatGPT Admin Console, open **Credentials** > **Admin keys** and revoke the key.

After you revoke a key, Opal can no longer read that part, and the next sync reports the problem. To keep syncing with a new key, create the new key first, paste it into the app's **Setup** tab in Opal, and then revoke the old key.

To stop the daily sync without revoking a key, clear **Sync agents daily**. To remove the connection from Opal, delete the app.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.