OpenAI usage tracking
How to track OpenAI API costs with the Usage and Costs APIs
You can track your OpenAI API spend programmatically by querying two dedicated endpoints: the Completions Usage API and the Costs API. Both endpoints require an Admin API key passed as a Bearer token and let you pull aggregated data in bucket widths like 1h or 1d.
While the default dashboard at https://platform.openai.com/usage works fine for checking numbers by hand, building automated alerts or internal chargeback requires pulling raw token counts and billed amounts via HTTP GET requests. Here is how both endpoints work, how to handle their grouping options, and how to query them from your terminal.
Creating an Admin API key for reporting
Standard OpenAI API keys (the ones starting with sk- that you pass to the completions endpoint) won't work here. The reporting routes belong to the organization management layer, so you have to authenticate using an Admin API key.
You create and manage these keys at https://platform.openai.com/settings/organization/admin-keys. Only Organization Owners can generate them. From a security standpoint, this separation is useful: Admin keys cannot call models, and a Read only Admin key cannot create new API keys. If a read-only key gets exposed in your data pipeline, nobody can use it to rack up inference charges.
When you make calls to either API, send the key as a Bearer token in the Authorization header, and pass Content-Type: application/json.
Pulling token metrics with the Completions Usage API
To pull token consumption and request volumes, send a GET request to https://api.openai.com/v1/organization/usage/completions.
This endpoint requires a start_time parameter formatted in Unix seconds. You can also pass an optional end_time in Unix seconds to bound your query window. If you leave end_time off, the query runs up to the most recent window.
You have several query parameters available to shape the data:
bucket_width: Accepts1m,1h, or1d. If omitted, it defaults to1d.limit: An integer specifying how many time buckets to return in the response.project_ids: An optional list of project IDs to filter results to specific workspaces.user_ids: An optional list of user IDs.api_key_ids: An optional list of API key IDs to isolate traffic from specific services.models: An optional list of model names, such aso1-2024-12-17,gpt-4o-2024-08-06, orgpt-4o-mini-2024-07-18.batch: A boolean flag whereTruereturns only batch jobs andFalselimits results to non-batch requests.
Beyond completions, OpenAI's organization schema also includes dedicated response models for other features, including usage_audio_speeches_response, usage_audio_transcriptions_response, usage_code_interpreter_sessions_response, usage_embeddings_response, usage_file_search_calls_response, usage_images_response, usage_moderations_response, usage_vector_stores_response, and usage_web_search_calls_response.
Grouping usage data and parsing the payload
The response body contains a data array where each element has an object type of bucket. Each bucket includes a start_time, an end_time, and a results list containing items of type organization.usage.completions.result.
Inside each result item, you'll find the core consumption metrics:
input_tokens: Total prompt tokens processed.output_tokens: Total completion tokens generated.num_model_requests: The total number of HTTP requests sent.- Specialized token fields:
input_cached_tokens,input_audio_tokens, andoutput_audio_tokens.
The result object also carries metadata attributes: project_id, user_id, api_key_id, model, and batch.
Here is the catch: if you don't supply a group_by parameter in your request, those metadata fields will simply return as null. To see which model or project generated the tokens, you must specify them in your request. The API supports grouping by multiple fields at once, such as group_by=["model", "project_id"] or group_by=["model", "user_id"].
Querying dollar amounts with the Costs API
Token counts tell you volume, but they don't give you exact billed amounts, especially when your workload spans different model tiers or storage fees. For dollar totals, use the Costs API at https://api.openai.com/v1/organization/costs.
Unlike the Completions Usage API, the Costs API does not support granular 1-minute or 1-hour intervals. The only supported value for the optional bucket_width parameter is 1d.
The Costs API returns bucket arrays with items of type organization.costs.result. Each result includes:
- An
amountobject containing a numericvalueand acurrencystring (likeusd). - An
organization_idstring identifying your account. - Optional dimensions:
project_idandline_item.
You can group cost records using the group_by parameter by supplying project_id or line_item. Grouping by line_item breaks out costs into specific categories, such as ft-gpt-4o-2024-08-06, input, assistants api | file search, or evals | gpt-4o-mini-2024-07-18, input.
Comparing the Usage and Costs endpoints
Before wiring up custom scripts, make sure you're using the right endpoint for the metric you need.
| Feature | Completions Usage API | Costs API |
|---|---|---|
| Endpoint URL | https://api.openai.com/v1/organization/usage/completions | https://api.openai.com/v1/organization/costs |
| Primary metric | Token counts and request totals | Billed currency amounts (usd) |
Supported bucket_width | 1m, 1h, 1d | 1d only |
Default bucket_width | 1d | 1d |
Supported group_by options | model, project_id, user_id, api_key_id | project_id, line_item |
| Required parameters | start_time (Unix seconds) | start_time (Unix seconds) |
| Non-completion tracking | Requires separate usage response models | Bundled automatically under line items |
Handling pagination and sending a curl request
Both APIs handle pagination identically. Responses return buckets inside the data array. If more buckets exist for your query window, the JSON response includes a next_page cursor string. To fetch the next chunk, send the exact same GET request but add the page query parameter set to that cursor value.
Here is a concrete curl example that requests hourly completion token counts grouped by model and project ID for a 24-hour period:
curl -X GET "https://api.openai.com/v1/organization/usage/completions?start_time=1736616660&end_time=1736703060&bucket_width=1h&group_by=model&group_by=project_id" \
-H "Authorization: Bearer sk-admin-example-key" \
-H "Content-Type: application/json"If the returned payload has a next_page value such as page_abc123, append &page=page_abc123 to your query string on the next run.
Automating cost controls and killswitches
Building custom pollers to query these endpoints works fine until you have to maintain state, manage rate limits, and write alerting logic across multiple services. If you prefer an existing system, Costbrake monitors spend across 23 cloud and AI providers, including OpenAI, Anthropic, AWS, and Google Cloud.
Costbrake runs hourly checks on its Free plan ($0 for 2 connections and 3 budgets) and 5-minute checks on Pro ($12 a month). During a spike - defined as an hour costing over 3x your 7-day baseline and at least $5 more than usual - it checks every 2 minutes.
When a runaway loop hits, alerting is often not enough. Costbrake includes opt-in brakes for 18 providers. For OpenAI, an admin can click to freeze a project or the entire organization. The brake works through OpenAI's Spend Limits API, setting the monthly hard limit to $0.01. Once OpenAI enforces it, subsequent paid API calls immediately fail with a 429 error, protecting your card from massive overages. You can connect it via agent setup or review plan options on Costbrake pricing. To handle spending limits manually, read our guide on How do I set a hard spending limit on the OpenAI API?.
Questions and answers
Does OpenAI have a usage API?
Yes. OpenAI provides the Completions Usage API (/v1/organization/usage/completions) for token and request counts, as well as the Costs API (/v1/organization/costs) for dollar spend.
What is an OpenAI admin key?
An Admin API key is a specialized credential created at https://platform.openai.com/settings/organization/admin-keys that starts with sk-admin-. Unlike standard API keys, Admin keys manage organization settings, spend alerts, and usage data, but they cannot execute model completions.
How current is OpenAI usage data?
Completions usage can be queried down to 1-minute (1m) or 1-hour (1h) buckets using the Completions Usage API. Billed dollar figures in the Costs API, however, are aggregated into daily (1d) buckets.
Can I get 1-minute cost data from the Costs API?
No. The Costs API currently only supports 1d for its bucket_width parameter. If you need intraday granular tracking, you must pull raw token counts from the Completions Usage API.
What happens if I forget the group_by parameter?
If you query the Completions Usage API without specifying group_by, metadata fields like project_id, model, and api_key_id return as null. You'll get an aggregated total for each bucket across the entire organization instead of a granular breakdown.
Sources
Updated