Provider Connectors
OpenAI
See what you spend on OpenAI and who uses it. Connect the API bill, ChatGPT Enterprise, and the usage Codex and your own apps report.
What each plan can show
OpenAI publishes a bill for the API and per-person analytics for ChatGPT Enterprise and Edu. Codex reports its own usage to LevelFour on any plan, and so do your own apps through OpenTelemetry. Chat in ChatGPT is measured on Enterprise and Edu alone: on Business, Plus and Pro, OpenAI publishes nothing about it, and it does not run on your machine.
| Your plan | What you pay | Connect | What you see |
|---|---|---|---|
| OpenAI API (platform.openai.com) | Per token | OpenAI Platform | Your bill by project, model, token type and API key |
| OpenAI API, called from your own apps | Per token | App usage, beside OpenAI Platform | The same calls by app and model, valued at list price |
| ChatGPT Enterprise or Edu | Seats, plus credits | ChatGPT Enterprise | What each person used of ChatGPT, Codex and Work, in dollars or in credits |
| ChatGPT Business, Plus or Pro | Seats or a flat fee | Codex usage | Who uses Codex and ChatGPT Work, with which model, and how much. Not chat |
Connect any mix, in any order. Billing data holds no activity, so add Codex usage beside a bill to see sessions, prompts and tools next to what you pay.
A source can hold more than one account: a second OpenAI organization, a second ChatGPT workspace, or a settings block per team. Add another at any time from the same page. Name is optional free text, and LevelFour uses it only to tell accounts apart.
A ChatGPT workspace billed in credits shows credits. LevelFour does not turn credits into dollars, because the price of a credit is set in your agreement.
History and what is left out
| Source | History on connect | First data | Not included |
|---|---|---|---|
| OpenAI Platform | 180 days, by day | About an hour | Tax |
| ChatGPT Enterprise | 90 days, by day | About an hour | Seat fees, prompts and responses |
| Codex usage | From the day you add the settings. Codex reports nothing earlier | A few minutes after you verify | Your bill, chat in ChatGPT, Codex and Work tasks that run in OpenAI's cloud, developers who have not added the settings, and what LevelFour never reads |
| App usage | From the day you set the variables | A few minutes after you verify | Calls a trace sampler dropped, and calls your app made to another vendor |
Prerequisites
- An organization on the OpenAI Platform.
- Organization owner access, to create the Admin key.
- A ChatGPT Enterprise or Edu workspace. ChatGPT Business has no analytics API.
- A workspace Owner or Admin, to create the workspace Admin key.
- Codex on each developer's machine: the CLI, the IDE extension or the ChatGPT app, on any plan.
- For a whole organization: an admin who manages your developers' machines, through MDM or a managed configuration file.
- An app that calls the OpenAI API through an official SDK.
- The OpenTelemetry SDK of the app's language, or an OpenTelemetry Collector the app already exports to.
Connect
Open Connect Providers and select OpenAI. The first time an admin opens it, Connect OpenAI starts by itself; after that, click Add account. Pick each plan your company pays for and click Continue:
| Plan you pick | Steps it adds |
|---|---|
| OpenAI API | OpenAI Platform: an Admin key, with Codex and Your apps as optional steps |
| ChatGPT Enterprise or Edu | ChatGPT Enterprise: a workspace Admin key, with Codex as an optional step |
| ChatGPT Business, or ChatGPT Plus or Pro | Codex: a settings block |
Two plans with the same source share one step. You can skip a step or hand it to a colleague, and a review at the end lists what you connected and what is still open. Run it again at any time: it only adds accounts. Only admins connect, rotate and disconnect; a member or viewer sees each account and its status.
Create a read-only Admin key
Sign in to the OpenAI Platform as an organization owner. Open Admin keys, click Create new admin key, and name it for LevelFour.
Under Permissions, give the key Read access and no Write, and set an expiration before you click Create admin key. If you change the permission later, OpenAI may not apply it. Copy the key (it starts with sk-admin-). OpenAI shows it once.
Add it to LevelFour
In Connect OpenAI, pick OpenAI API. On the OpenAI Platform step, click Add Admin API key, paste the key and click Connect account.
LevelFour reads the costs report grouped by project, API key and line item, and the completions usage report for the tokens behind each charge. A charge that no API key made, such as a fine-tuning job, shows as (no key). The account is the OpenAI organization the key belongs to, so a second key of an organization you already connected adds no account.
Create a workspace Admin key
Sign in to the ChatGPT Admin Console as a workspace Owner or Admin. Go to Credentials > Admin keys and create a key for LevelFour with Read on Enterprise analytics API and Codex analytics API. Copy it (it starts with sk-admin-). It is shown once.
Copy the Workspace ID from the workspace details page too.
Add it to LevelFour
In Connect OpenAI, pick ChatGPT Enterprise or Edu. On the ChatGPT Enterprise step, click Add workspace Admin key, paste the key and the Workspace ID, and click Connect account.
LevelFour reads what each person used per day from the Enterprise analytics API, and the tokens of each Codex model from the Codex analytics API. A key with only one of the two permissions connects, and the account says which one it reads.
Seat fees are not in either API, so your ChatGPT Enterprise total is lower than your invoice. A workspace billed in credits shows credits and no dollars.
Generate the settings
In Connect OpenAI, pick the plan that uses Codex. On the Codex step, click Generate settings. LevelFour shows a settings block that holds a new ingest key.
[otel]
log_user_prompt = false
exporter = { otlp-http = { endpoint = "https://api.levelfour.ai/api/v1/otlp/v1/logs", protocol = "json", headers = { "Authorization" = "Bearer l4i_..." } } }Copy the block before you leave the page. LevelFour keeps only a hash of the key and shows it this one time.
Add it to Codex
- One developer: add the block at the end of
~/.codex/config.toml, below every other setting. TOML puts each key under the table above it, so a block pasted at the top would capture the settings after it. Then quit Codex and the ChatGPT app and open them again: Codex reads the file when it starts. Codex reads it in the CLI, the IDE extension and the ChatGPT app. - Every developer in your organization: encode the block in base64 with no line wrapping, and push it to Macs through MDM (preference domain
com.openai.codex, keyconfig_toml_base64). Without MDM, write the block to/etc/codex/managed_config.tomlon macOS and Linux, or~/.codex/managed_config.tomlon Windows. Codex applies it the next time it starts, so ask developers to quit and reopen Codex and the ChatGPT app.
A developer can still change a managed default during a session. LevelFour does not enforce collection.
A configuration file holds one [otel] table, so Codex on a machine reports to one key. If the file already has an [otel] table, replace it. A machine that also runs Codex against DeepSeek sends those sessions here too, and LevelFour leaves out each request for a model OpenAI does not serve.
The ChatGPT app runs Work tasks through the same Codex, so the block measures them too. They show as ChatGPT Work, apart from Codex. Chat in the app is not measured, and neither is a task that runs in OpenAI's cloud.
Verify
Run one prompt in Codex, then click Verify connection in the step. If your rollout takes days, close the dialog: the block waits for its first event on the OpenAI page, and you verify it there later.
Instrument the OpenAI SDK
Add the OpenTelemetry instrumentation of the OpenAI SDK to your app. In Python:
pip install opentelemetry-distro opentelemetry-exporter-otlp-proto-http opentelemetry-instrumentation-genai-openaiRun the app under opentelemetry-instrument, for example opentelemetry-instrument python app.py, and set OTEL_SERVICE_NAME to the name LevelFour should show for the app. Other languages have their own OpenAI instrumentation, and OpenLLMetry covers several.
opentelemetry-instrumentation-genai-openai traces chat completions, the Responses API and embeddings, and reports cached input, which LevelFour prices at the cache rate. It replaces opentelemetry-instrumentation-openai-v2, which traces no Responses API call and reports no cached input, so an app on it reads high.
A streamed chat completion carries token counts only when the app asks for them with stream_options={"include_usage": True}. Without it, the call reaches LevelFour with no tokens and is left out. A streamed Responses API call always carries them.
Generate the variables
In Connect OpenAI, pick OpenAI API, then the optional Your apps step, and click Generate settings. LevelFour shows the environment variables with a new ingest key, once.
OTEL_TRACES_EXPORTER=otlp
OTEL_EXPORTER_OTLP_TRACES_PROTOCOL=http/protobuf
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://api.levelfour.ai/api/v1/otlp/v1/traces
OTEL_EXPORTER_OTLP_TRACES_HEADERS=Authorization=Bearer%20l4i_...
OTEL_TRACES_SAMPLER=always_on
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=falseSet them where the app runs
Add the variables to the app's environment: its container, its deployment or its .env file. An app that already exports traces elsewhere keeps doing so through an OpenTelemetry Collector, with a second exporter for LevelFour. See Sending through a Collector.
Verify
Make one model call from the app, then click Verify connection in the step.
LevelFour reads only the spans of model calls. It reads a span of a chat, completion or embedding call and skips agent and workflow spans, which repeat the tokens of the calls under them. A call the sampler dropped never reaches LevelFour, which is why the variables keep every trace.
What LevelFour keeps from Codex
Codex reports each thing a developer does as an event. LevelFour adds it to a daily total and stores the total, never one row per event.
| Kept | As a daily total of |
|---|---|
| Usage | Requests, tokens by type and usage value, per person and model |
| Sessions | Conversations started |
| Prompts | How many, and their length in characters |
| Tools | Calls per tool, how many succeeded, and how long they took. A tool an MCP server serves counts as one row, MCP tools |
| Tool approvals | Calls approved or denied, and what decided: configuration or a person |
| Failed requests | Model requests that did not go through, by status code where Codex sends one |
| Speed | Time to first token by model, and requests per reasoning effort |
LevelFour keeps usage, sessions, prompt counts and failed requests per person. Every other total covers all developers together and carries no name. Each person has one profile: the Codex version and terminal they last reported, and the first and last day they reported.
Codex reports no cost, so LevelFour values its tokens at OpenAI's API list price.
What LevelFour never reads
Codex sends a tool's arguments and output with every tool result. LevelFour discards them unread. It never reads or stores:
- the text of a prompt or a response
- a tool's arguments or output
- a command
- file content
The settings block keeps log_user_prompt off, so Codex sends no prompt text.
Who a request belongs to
A developer signed in to Codex with ChatGPT shows under their email, in the CLI and in the ChatGPT app. Codex signed in with an API key names no person, so LevelFour shows the account, or the machine when there is none. A developer who runs the CLI on an API key can name themselves by setting OTEL_RESOURCE_ATTRIBUTES=levelfour.person=<their email> in the shell Codex runs in. The ChatGPT app does not read your shell's variables, which it does not need: it is always signed in with ChatGPT.
Sending through an OpenTelemetry Collector
You can put an OpenTelemetry Collector between Codex or your apps and LevelFour. Have it export OTLP over HTTP, as JSON or protobuf, to the route of each signal: /api/v1/otlp/v1/logs for Codex and /api/v1/otlp/v1/traces for apps. LevelFour refuses gRPC, a batch over 2 MB, and a batch that holds more than 1,024 model calls.
exporters:
otlphttp/levelfour:
traces_endpoint: https://api.levelfour.ai/api/v1/otlp/v1/traces
headers:
Authorization: Bearer l4i_...
processors:
filter/genai:
error_mode: ignore
traces:
span:
- >-
attributes["gen_ai.usage.input_tokens"] == nil and attributes["gen_ai.usage.prompt_tokens"] == nil
and attributes["gen_ai.usage.output_tokens"] == nil and attributes["gen_ai.usage.completion_tokens"] == nil
service:
pipelines:
traces/levelfour:
receivers: [otlp]
processors: [filter/genai]
exporters: [otlphttp/levelfour]The filter keeps only the spans that carry token counts, so the rest of your traces stay with your own backend. It reads the counts rather than gen_ai.operation.name, which older instrumentations leave out. An app that calls both OpenAI and DeepSeek sends through a Collector with one exporter per vendor, each with its own key: LevelFour leaves out a call that a key of the other vendor sent.
What you see
OpenAI spend appears under Costs and Usage and on its own OpenAI board under Boards, which appears once you connect a source.
| Group by | OpenAI Platform | ChatGPT Enterprise | Codex and app usage |
|---|---|---|---|
| Model | The model | The product: ChatGPT, Codex or Work | The model |
| Project or tool | Project | Client | Codex, ChatGPT Work or Apps |
| Token type | Input, Cache read, Output | Not reported | On the board's tokens card |
| Key, person or app | API key, or (no key) | Person | Person, or app for app usage |
Billed and usage value
LevelFour keeps two figures apart, and a switch on the chart and the table chooses between them.
- Billed is what OpenAI charges you through the API, and what a ChatGPT workspace billed in dollars reports.
- Usage value is Codex and app usage priced at OpenAI's API list price. It estimates what that usage would cost per token. LevelFour never adds it to a billed total.
The OpenAI board
The board sorts its cards into groups under headings. A card appears once it has data, and a heading appears once its group has a card. Bill reads OpenAI Platform and ChatGPT Enterprise. Every other group reads what Codex and your apps report, with the current day included.
| Group | Cards |
|---|---|
| Bill | Spend summary, cost by model, by project or tool, by token type, and by key, person or app, the cost chart and table, active anomalies |
| Usage | Usage value, active people, requests and tokens; usage value and tokens per day; usage by person and by model; Codex versus apps; usage bands and concentration; cache efficiency; inactive people; people and apps, one row each, with a CSV download |
| Activity | Sessions per day, prompts, new and returning people |
| How Codex is used | Tools used most, tool success rate, tool approvals |
| Speed and reliability | Response time by model, rate limits and API errors, slowest tools, effort and fast mode |
| Fleet | Codex versions, terminals and IDEs |
Cards that compare people need two or more people who reported usage.
Confirming it worked
Each account you connect moves to Connected on the OpenAI page. OpenAI Platform and ChatGPT Enterprise data appears in about an hour. Codex and app usage turn Connected after the first prompt or model call and Verify connection, and their figures appear on the board within minutes.
Rotating or removing access
Rotating a credential
Create a new key in OpenAI. On the OpenAI page under Connect Providers, click Rotate credential on the account, paste the new key, then revoke the old one where you created it.
You cannot rotate an ingest key. Disconnect the Codex or app usage source, keeping its data, generate the settings again, and replace the block or the variables wherever you put them.
Removing access
Click Disconnect on the account under Connect Providers, then revoke the key: an Admin key on the OpenAI Platform's Admin keys page, a workspace Admin key under Credentials > Admin keys in the ChatGPT Admin Console. Disconnecting a usage source stops its ingest key working at once. Remove the block or the variables so Codex or your app stops sending.
Troubleshooting
| Symptom | What to do |
|---|---|
| LevelFour rejects the OpenAI Platform key | OpenAI's organization reports refuse a project API key. Create an Admin key under Admin keys: it starts with sk-admin- |
| Key creation fails or the Admin keys page is not visible | You need organization owner access on the OpenAI Platform account |
| LevelFour rejects the ChatGPT Enterprise key | Check the key has Read on Enterprise analytics API or Codex analytics API, and that you copied the Workspace ID of the workspace you created it in |
| ChatGPT Enterprise shows credits and no dollars | Expected for a workspace billed in credits |
| A charge shows (no key) | No API key made it, as with fine-tuning and some batch jobs |
| Verify connection says no usage has arrived | Check the block sits at the end of the config.toml Codex reads, quit and reopen Codex, then run one prompt. For an app, check the variables are in its environment, then make one model call. A chat in ChatGPT sends nothing |
| The account shows a warning that a model has no list price | A request used a model LevelFour cannot price yet. Its tokens count, at no cost, until LevelFour adds the price |
| Codex usage stopped after you set up Codex for DeepSeek | The machine's [otel] table now names the DeepSeek key. A machine reports Codex to one key |
| A Codex developer shows as an account id or a machine name | They use Codex with an API key. Have them set levelfour.person, as in Who a request belongs to |
| App calls are missing | Check you started the app under the instrumentation, that no sampler drops traces, and that the app calls OpenAI itself. A streamed chat completion needs stream_options={"include_usage": True} |
| Azure OpenAI spend is missing | This page covers OpenAI itself. Azure bills Azure OpenAI, so connect Azure to see it |
Next
- Connect Providers lists every provider you can connect
- Anthropic and DeepSeek connect the same way
- Virtual tags group your OpenAI spend by team, product, or any other dimension, alongside your other providers
Troubleshooting
What each answer in the LevelFour agent's logs means, and how to fix a cluster that does not install, does not report, reports no usage, shows no price or gets no recommendations.
Anthropic
See what you spend on Claude, who uses it and how, whatever plan you are on. Connect the Claude API, Claude Enterprise, and the usage of Claude Code and Cowork.