Supported Usage Types¶
Usage.from_openai() accepts every usage object below. Each is normalized into
the same Usage shape with requests=1.
| OpenAI source | Type passed to from_openai |
What is captured |
|---|---|---|
| Chat Completions | openai.types.completion_usage.CompletionUsage |
input/output tokens, cached, reasoning |
| Responses API | openai.types.responses.ResponseUsage |
input/output tokens, cached, reasoning |
| Agents SDK | agents.Usage |
input/output tokens, cached, reasoning |
| Agents SDK (context) | agents.RunContextWrapper |
unwrapped to its .usage |
| Realtime | openai.types.realtime.RealtimeResponseUsage |
input/output tokens, cached, audio, text |
| Batch | openai.types.batch_usage.BatchUsage |
input/output tokens, cached, reasoning |
| Embeddings | openai.types.create_embedding_response.Usage |
input tokens only (no output) |
| Images (gpt-image-1) | openai.types.images_response.Usage |
input/output tokens, image, text |
| Transcription (tokens) | openai.types.audio.transcription.UsageTokens |
input/output tokens, audio, text |
| Transcription (duration) | openai.types.audio.transcription.UsageDuration |
seconds only |
| Assistants run | openai.types.beta.threads.run.Usage |
prompt/completion tokens |
| Assistants run step | openai.types.beta.threads.runs.run_step.Usage |
prompt/completion tokens |
Other providers¶
Two non-OpenAI SDKs are supported through the same from_openai() call, each
behind an optional extra:
| Source | Type passed to from_openai |
What is captured |
|---|---|---|
| Gemini | google.genai.types.GenerateContentResponseUsageMetadata |
input/output tokens, cached, thinking, tool-use prompt, per-modality audio/image/video/text |
| LiteLLM | litellm.types.utils.Usage |
input/output tokens, cached, cache-write, reasoning, audio/image/video/text, cost |
Neither SDK is imported unless you already imported it yourself, so installing the extras is only necessary if you actually pass their objects.
# Gemini
response = client.models.generate_content(model="gemini-2.5-pro", contents="hi")
usage = Usage.from_openai(response.usage_metadata)
# LiteLLM
response = litellm.completion(model="claude-sonnet-4-5", messages=messages)
usage = Usage.from_openai(response.usage)
Two mapping decisions are worth knowing about:
- Gemini reports
thoughts_token_countseparately fromcandidates_token_count.output_tokensis the sum of both, andreasoning_tokensholds the thinking count. - Gemini's
tool_use_prompt_token_countis added toinput_tokens, since it is billed as input.
All the OpenAI types are also re-exported from the package root for convenience and type hints:
from openai_usage import (
BatchUsage,
EmbeddingUsage,
ImagesUsage,
RealtimeResponseUsage,
RunStepUsage,
RunUsage,
TranscriptionUsageDuration,
TranscriptionUsageTokens,
AnyUsage, # the Union of everything from_openai accepts
OpenAIUsage, # the OpenAI-only subset
)
Examples by modality¶
Realtime (audio)¶
from openai_usage import Usage
# event is a `response.done` event from a realtime session
usage = Usage.from_openai(event.response.usage)
print(usage.input_tokens_details.audio_tokens)
print(usage.output_tokens_details.audio_tokens)
Embeddings¶
response = client.embeddings.create(model="text-embedding-3-small", input="hello")
usage = Usage.from_openai(response.usage)
assert usage.output_tokens == 0 # embeddings have no generated output
Image generation¶
result = client.images.generate(model="gpt-image-1", prompt="a red bicycle")
usage = Usage.from_openai(result.usage)
print(usage.input_tokens_details.image_tokens)
print(usage.output_tokens_details.image_tokens)
Transcription¶
from openai_usage import Usage
# gpt-4o-transcribe → billed by tokens
usage = Usage.from_openai(transcription.usage) # UsageTokens
print(usage.input_tokens_details.audio_tokens)
# whisper-1 → billed by duration
usage = Usage.from_openai(transcription.usage) # UsageDuration
print(usage.seconds)
Not LLM usage? Not included.
OpenAI's organization-level Usage API (/organization/usage/*) reports
aggregated billing buckets rather than per-call token counts, so it is
intentionally out of scope for this library.