OpenAI Usage Stats Parser

Extract and cost-estimate token usage from an OpenAI API response.

Paste an OpenAI API response object and instantly see prompt tokens, completion tokens, cached tokens, reasoning tokens, and a per-model cost estimate in a clean summary card. Works fully in your browser with no key required. It runs free in your browser on Gera Tools, with nothing uploaded.

Last updated Source: Gera Tools

Do I need an API key?

No. This tool only parses a response you already received. Everything runs locally in your browser and nothing is sent anywhere.

Parse OpenAI token usage and estimate cost

The OpenAI Usage Stats Parser reads the usage object from any OpenAI API response and lays out the token counts you actually care about — prompt, completion, cached input, and reasoning tokens — alongside an estimated cost for the call. No API key is needed because you are parsing a response you already have.

How it works

The tool parses your pasted JSON and looks for a usage object using both the chat-completions field names (prompt_tokens, completion_tokens) and the responses-API names (input_tokens, output_tokens). It also reads prompt_tokens_details.cached_tokens and completion_tokens_details.reasoning_tokens when present. Cost is computed from published list prices for the model you select, billing cached input at the discounted rate and the rest at the standard input price.

What the OpenAI usage object looks like

The usage object returned by OpenAI’s chat completions API looks like this:

{
  "usage": {
    "prompt_tokens": 1024,
    "completion_tokens": 512,
    "total_tokens": 1536,
    "prompt_tokens_details": {
      "cached_tokens": 768,
      "audio_tokens": 0
    },
    "completion_tokens_details": {
      "reasoning_tokens": 0,
      "audio_tokens": 0,
      "accepted_prediction_tokens": 0,
      "rejected_prediction_tokens": 0
    }
  }
}

The responses API (used with Assistants and the /v1/responses endpoint) uses slightly different field names — input_tokens and output_tokens instead of prompt_tokens and completion_tokens. This parser handles both formats automatically.

How cost is calculated from token counts

Cost is determined by counting three categories of tokens and multiplying by their respective per-million-token prices:

  1. Non-cached input tokensprompt_tokens − cached_tokens, billed at the standard input rate
  2. Cached input tokenscached_tokens from prompt_tokens_details, billed at the discounted cached-input rate (typically 50% of the standard input price)
  3. Output tokenscompletion_tokens including reasoning tokens, billed at the output rate (usually higher than the input rate)

The formula: cost = (non_cached_input / 1M × input_price) + (cached_input / 1M × cached_price) + (output / 1M × output_price)

Reading the results: what to watch

High cached token count. If your cached_tokens is a large fraction of prompt_tokens, your prompt caching is working well. A stable system prompt that fills thousands of tokens can be served from cache on repeated calls, cutting input costs substantially. A cached count near zero on repeated calls suggests your prompt structure is changing in a way that prevents cache hits.

High reasoning tokens. On o-series models (o1, o3, etc.), reasoning tokens represent the model’s internal thinking process before producing a response. They are billed as output tokens and can easily dwarf the final visible completion on hard problems. If a call costs more than expected, check completion_tokens_details.reasoning_tokens first.

Rejected prediction tokens. When using speculative decoding features, rejected tokens represent draft tokens that were not accepted by the verifier. They are billed even though they did not contribute to the final output.

Troubleshooting: no usage object found

If the parser reports that no usage object was found, common causes are:

  • You pasted only the message content (the choices[0].message.content string) rather than the full API response JSON
  • The response is from a streaming call — streaming responses emit tokens incrementally and the usage object may appear only in the final data: [DONE] chunk or as a separate final object depending on the streaming mode
  • The response is from a non-completion endpoint (such as embeddings or images) that uses different field names

Paste the complete raw JSON object from your API call to get a valid parse.