Simple and clean API for OpenAI model cost calculation and tracking with automatic pricing updates
Project description
OpenAI Models Pricing
Comprehensive OpenAI pricing solution with automated data updates and Python library for cost calculation.
This project provides two integrated components:
- Pricing Data Provider - Automatically scrapes and publishes OpenAI pricing data via JSON API
- Python Library (
openai-pricing-api) - Clean API for calculating costs and tracking usage
๐ฏ Features
Pricing Data Provider
- Daily automatic price updates via GitHub Actions
- JSON API for integration into your projects
- Web interface for browsing prices
- Price history for the last 90 days
- Search and filter models
Python Library
- Simple and clean API for cost calculation
- Support for all OpenAI model types (GPT, DALL-E, Whisper, Sora)
- Automatic pricing updates with local caching
- Credit-based billing support
- Variance tracking (estimated vs actual costs)
- Mixed usage calculation across multiple models
- Zero dependencies (only Pydantic required)
Demo
Site available at: https://bes-dev.github.io/openai-pricing-api/
๐ฆ Quick Start - Python Library
Install the library:
pip install openai-pricing-api
Calculate costs:
from openai_pricing_api import PricingCalculator
calculator = PricingCalculator()
# Calculate cost for GPT-4o
cost = calculator.calculate_token_cost(
"gpt-4o",
input_tokens=1000,
output_tokens=500
)
print(f"Cost: ${cost:.4f}") # Cost: $0.0125
# Calculate cost for DALL-E-3
cost = calculator.calculate_image_cost(
"dall-e-3",
count=5,
size="1024x1024",
quality="hd"
)
print(f"Cost: ${cost:.4f}") # Cost: $0.4000
# Mixed usage (multiple models)
usage = {
"analyze": {"model": "gpt-4o", "input_tokens": 1000, "output_tokens": 500},
"generate": {"model": "dall-e-3", "count": 5, "size": "1024x1024"}
}
total = calculator.calculate_mixed_usage(usage)
print(f"Total: ${total:.4f}")
For complete library documentation, see Python Library Usage section.
๐ Project Structure
openai-pricing-api/
โโโ .github/workflows/
โ โโโ update-pricing.yml # Daily pricing updates
โ โโโ publish-pypi.yml # PyPI publishing (WIP)
โ โโโ tests.yml # Library tests (WIP)
โโโ github_pages/ # GitHub Pages site
โ โโโ index.html # Web interface
โ โโโ script.js # Frontend JavaScript
โ โโโ styles.css # Styling
โ โโโ api.json # Simplified API (generated)
โ โโโ pricing.json # Full data (generated)
โ โโโ history.json # Price history (generated)
โโโ scripts/
โ โโโ fetch_openai_pricing.py # Price scraping script
โโโ src/openai_pricing/ # Python library source
โ โโโ __init__.py
โ โโโ calculator.py # Main calculator class
โ โโโ pricing.py # Pricing data provider
โ โโโ models.py # Pydantic data models
โโโ examples/
โ โโโ basic_usage.py # Library usage examples
โ โโโ README.md # Examples documentation
โโโ pyproject.toml # Python package configuration
โโโ requirements.txt # Scraper dependencies
๐ Quick Start
Option 1: Use Python Library (Recommended)
pip install openai-pricing-api
See Python Library Usage for full documentation.
Option 2: Fork Repository for Custom Data Provider
1. Fork the Repository
Fork this repository to your GitHub account.
2. Enable GitHub Pages
Important: You must enable GitHub Pages before the workflow can deploy.
- Go to your repository on GitHub
- Click Settings (top menu)
- Scroll down to Pages (left sidebar)
- Under Source, select GitHub Actions from the dropdown
- Click Save (if available)
Note: If you don't see the "GitHub Actions" option:
- Make sure your repository is public (or you have GitHub Pro for private repos)
- The workflow must run at least once to create the deployment
- You may need to wait a few seconds and refresh the page
3. Enable GitHub Actions
- Go to the Actions tab
- If prompted, click "I understand my workflows, go ahead and enable them"
- The workflow will run automatically on push or on schedule (daily at 12:00 UTC)
4. Run Workflow Manually
- Go to Actions โ Update OpenAI Pricing
- Click "Run workflow" dropdown (right side)
- Select branch (usually
mainormaster) - Click green "Run workflow" button
- Wait for completion (~2-3 minutes)
- If it fails with "Pages not enabled", go back to step 2 and enable Pages first
5. Check the Result
After the workflow completes successfully:
- Open https://bes-dev.github.io/openai-pricing-api/
- It may take 1-2 minutes for the site to become available
- Check the Actions tab for the deployment URL in the workflow summary
API Usage
Simple API (Recommended)
curl https://bes-dev.github.io/openai-pricing-api/api.json
Response:
{
"models": {
"gpt-4o": {
"model": "gpt-4o",
"pricing_type": "per_1m_tokens",
"input": 2.5,
"output": 10.0,
"timestamp": "2025-01-27T12:00:00Z"
}
},
"timestamp": "2025-01-27T12:00:00Z",
"models_count": 20,
"source": "openai_official_pricing_page"
}
JavaScript Example
fetch('https://bes-dev.github.io/openai-pricing-api/api.json')
.then(res => res.json())
.then(data => {
console.log('Models:', data.models);
console.log('Last updated:', data.timestamp);
});
Python Example
import requests
url = 'https://bes-dev.github.io/openai-pricing-api/api.json'
data = requests.get(url).json()
# Filter by category
for model_name, model_data in data['models'].items():
if model_data.get('category') == 'image_generation_token':
print(f"{model_name} ({model_data['category']}):")
print(f" Input: ${model_data.get('input', 0)}/1M tokens")
print(f" Output: ${model_data.get('output', 0)}/1M tokens")
print()
# Or show all models with their categories
for model_name, model_data in data['models'].items():
category = model_data.get('category', 'unknown')
pricing_type = model_data.get('pricing_type', 'unknown')
print(f"{model_name}: {category} ({pricing_type})")
Available Endpoints
/api.json- Simplified data (recommended)/pricing.json- Full data with all details/history.json- Price change history for the last 90 days
Local Testing
Install Dependencies
pip install -r requirements.txt
playwright install chromium
Run the Script
python scripts/fetch_openai_pricing.py
This will create files in the github_pages/ directory:
pricing.jsonapi.jsonhistory.json
View Results
Open github_pages/index.html in your browser.
Update Schedule
GitHub Actions workflow runs:
- Daily at 12:00 UTC (automatically)
- On push to master/main (automatically)
- Manually via GitHub Actions web interface
Configuration
Change Schedule
Edit .github/workflows/update-pricing.yml:
schedule:
- cron: '0 12 * * *' # Daily at 12:00 UTC
Examples:
'0 */6 * * *'- Every 6 hours'0 0 * * *'- Daily at midnight UTC'0 12 * * 1'- Every Monday at 12:00 UTC
Change Pricing URL
Edit scripts/fetch_openai_pricing.py:
PRICING_URL = "https://platform.openai.com/docs/pricing" # API docs (recommended)
# OR
PRICING_URL = "https://openai.com/api/pricing/" # Marketing page (limited data)
Note: The API docs URL (platform.openai.com) contains more comprehensive pricing data (60+ models) compared to the marketing page.
Data Structure
pricing.json
Full model data:
{
"gpt-4o": {
"model": "gpt-4o",
"pricing_type": "per_1m_tokens",
"category": "language_model",
"input": 2.5,
"output": 10.0,
"timestamp": "2025-01-27T12:00:00Z"
},
"gpt-image-1": {
"model": "gpt-image-1",
"pricing_type": "per_1m_tokens",
"category": "image_generation_token",
"input": 10.0,
"output": 40.0,
"timestamp": "2025-01-27T12:00:00Z"
},
"dall-e-3": {
"model": "dall-e-3",
"pricing_type": "per_image",
"category": "image_generation",
"price": 0.04,
"timestamp": "2025-01-27T12:00:00Z"
}
}
history.json
Price change history:
[
{
"date": "2025-01-27",
"timestamp": "2025-01-27T12:00:00Z",
"models": { ... },
"models_count": 20
},
{
"date": "2025-01-26",
"timestamp": "2025-01-26T12:00:00Z",
"models": { ... },
"models_count": 19
}
]
Data Fields
Each model in the JSON has the following fields:
model- Model namepricing_type- How the model is billed (per_1m_tokens, per_image, per_second, etc.)category- Model category (see below)input- Input price (for token-based models)output- Output price (for token-based models)cached_input- Cached input price (if available)price- Fixed price (for non-token models)timestamp- When the data was last updated
Pricing Types
per_1m_tokens- Price per 1 million tokens (language, image-gen, embeddings)per_image- Price per image (DALL-E)per_second- Price per second (Sora video generation)per_minute- Price per minute (Whisper audio transcription)per_1k_chars- Price per 1K characters (TTS)
Categories
language_model- GPT-5, GPT-4, GPT-3.5, davinci, babbagereasoning- o1-pro, o3-pro, o3-deep-researchimage_generation_token- gpt-image-1 (token-based image generation)image_generation- DALL-E (fixed price per image)video_generation- Sora modelsaudio_transcription- Whisper modelstext_to_speech- TTS modelsembeddings- text-embedding modelscomputer_use- Computer use modelsstorage- Storage pricingother- Other models
๐ Python Library Usage
The openai-pricing-api Python library provides a clean API for calculating costs across all OpenAI model types.
Installation
# From PyPI
pip install openai-pricing-api
# From source (for development)
git clone https://github.com/bes-dev/openai-pricing-api.git
cd openai-pricing-api
pip install -e .
Basic Usage
from openai_pricing_api import PricingCalculator
calculator = PricingCalculator()
API Reference
calculate_token_cost(model, input_tokens=0, output_tokens=0, cached_tokens=0)
Calculate cost for token-based models (GPT-4, GPT-3.5, embeddings, etc.).
# GPT-4o
cost = calculator.calculate_token_cost(
"gpt-4o",
input_tokens=1000,
output_tokens=500
)
print(f"${cost:.4f}") # $0.0125
# With cached tokens
cost = calculator.calculate_token_cost(
"gpt-4o",
input_tokens=500,
output_tokens=500,
cached_tokens=500 # 90% cheaper
)
calculate_image_cost(model, count=1, size="1024x1024", quality="standard")
Calculate cost for image generation (DALL-E, gpt-image-1).
# DALL-E-3
cost = calculator.calculate_image_cost(
"dall-e-3",
count=5,
size="1024x1024",
quality="hd"
)
print(f"${cost:.4f}") # $0.4000
# gpt-image-1
cost = calculator.calculate_image_cost(
"gpt-image-1",
count=10,
size="1024x1024",
quality="low"
)
calculate_video_cost(model, duration_seconds)
Calculate cost for video generation (Sora).
cost = calculator.calculate_video_cost(
"sora-2",
duration_seconds=30
)
calculate_mixed_usage(usage)
Calculate total cost from multiple models and stages.
usage = {
"analysis": {
"model": "gpt-4o",
"input_tokens": 1000,
"output_tokens": 500
},
"generation": {
"model": "gpt-4o",
"input_tokens": 2000,
"output_tokens": 800
},
"images": {
"model": "dall-e-3",
"count": 5,
"size": "1024x1024",
"quality": "standard"
}
}
total = calculator.calculate_mixed_usage(usage)
print(f"Total: ${total:.4f}")
estimate_credits(items, overhead, per_item, currency="credits")
Estimate cost in credits or custom units.
estimate = calculator.estimate_credits(
items=10, # Number of items
overhead=3, # Fixed overhead
per_item=2, # Cost per item
currency="credits"
)
print(f"Total: {estimate.total} {estimate.currency}") # Total: 23 credits
print(f"Breakdown: {estimate.overhead} + ({estimate.items} ร {estimate.per_item})")
calculate_actual_cost(estimated, usage)
Calculate actual cost and compare with estimate (variance tracking).
# Charge user 23 credits (estimated)
estimated_usd = 23 * 0.05 # Convert to USD
# After generation, calculate actual cost
actual = calculator.calculate_actual_cost(
estimated=estimated_usd,
usage={
"stage1": {"model": "gpt-4o", "input_tokens": 1000, "output_tokens": 500},
"stage2": {"model": "dall-e-3", "count": 5}
}
)
print(f"Estimated: ${actual.estimated:.4f}")
print(f"Actual: ${actual.actual:.4f}")
print(f"Variance: {actual.variance_percent:+.1f}%")
print(f"Is over budget: {actual.is_over_budget}")
print(f"Savings/Loss: ${actual.savings:.4f}")
get_model_pricing(model)
Get pricing information for a specific model.
pricing = calculator.get_model_pricing("gpt-4o")
if pricing:
print(f"Model: {pricing.model}")
print(f"Type: {pricing.pricing_type}")
print(f"Input: ${pricing.input_price}/1M tokens")
print(f"Output: ${pricing.output_price}/1M tokens")
if pricing.cached_input_price:
print(f"Cached: ${pricing.cached_input_price}/1M tokens")
get_available_models()
Get list of all available models.
models = calculator.get_available_models()
print(f"Available models: {len(models)}")
print(models[:5]) # ['gpt-4o', 'gpt-5', 'dall-e-3', ...]
refresh_pricing()
Force refresh pricing data from API.
success = calculator.refresh_pricing()
if success:
print("Pricing data refreshed successfully")
Configuration
Custom API URL
calculator = PricingCalculator(
api_url="https://your-custom-api.com/pricing.json"
)
Custom Cache Location
from pathlib import Path
calculator = PricingCalculator(
cache_file=Path("/custom/path/pricing_cache.json")
)
Custom Cache Duration
from datetime import timedelta
calculator = PricingCalculator(
cache_duration=timedelta(hours=24) # Cache for 24 hours
)
Data Models
CostEstimate
class CostEstimate:
items: int # Number of items
overhead: float # Fixed overhead
per_item: float # Cost per item
total: float # Total cost
currency: str # Currency unit
ActualCost
class ActualCost:
estimated: float # Estimated cost
actual: float # Actual cost
variance_percent: float # Variance percentage
is_over_budget: bool # True if over budget
savings: float # Savings (negative if over)
details: dict # Detailed breakdown
ModelPricing
class ModelPricing:
model: str # Model identifier
pricing_type: str # Type of pricing
input_price: Optional[float] # Input price per 1M tokens
output_price: Optional[float] # Output price per 1M tokens
cached_input_price: Optional[float]
image_pricing: Optional[dict] # Image pricing by size/quality
video_price_per_second: Optional[float]
source: str # Data source
Examples
Complete examples are available in the examples/ directory:
python examples/basic_usage.py
This will demonstrate:
- Token-based cost calculation
- Image generation cost
- Mixed usage calculation
- Credit-based billing
- Variance tracking
- Model information retrieval
Error Handling
The library raises ValueError for invalid inputs:
try:
cost = calculator.calculate_token_cost("invalid-model", input_tokens=1000)
except ValueError as e:
print(f"Error: {e}") # Error: Model not found: invalid-model
Caching
The library automatically caches pricing data:
- Location:
~/.openai_pricing_api/pricing_cache.json - Duration: 12 hours (configurable)
- Fallback: Uses cached data if API is unavailable
- Update: Automatically refreshes expired cache
To force refresh:
calculator.refresh_pricing()
Integration with tiktoken
For accurate token counting:
import tiktoken
from openai_pricing_api import PricingCalculator
# Count tokens
encoding = tiktoken.encoding_for_model("gpt-4o")
input_tokens = len(encoding.encode("Your input text"))
output_tokens = len(encoding.encode("Model response"))
# Calculate cost
calculator = PricingCalculator()
cost = calculator.calculate_token_cost(
"gpt-4o",
input_tokens=input_tokens,
output_tokens=output_tokens
)
How to Calculate Costs (Manual Method)
This section explains how to use the pricing data to calculate the cost of using different OpenAI models.
Understanding Tokens
What is a token? A token is the basic unit of text processing in OpenAI models. It can be a word, subword, punctuation mark, or symbol.
Rule of thumb:
- 1 token โ 4 characters of English text
- 1,000 tokens โ 750 English words
- 100 tokens โ 75 words
Example: The sentence "Hello, how are you today?" contains approximately 6-7 tokens.
Cost Calculation Formulas
1. Language Models (per_1m_tokens)
Models: GPT-4, GPT-3.5, o1, embeddings, etc.
Formula:
Total Cost = (Input Tokens / 1,000,000 ร Input Price) + (Output Tokens / 1,000,000 ร Output Price)
Example with GPT-4o:
- Input price: $2.50 / 1M tokens
- Output price: $10.00 / 1M tokens
- Your request: 500 input tokens, 1,500 output tokens
Cost = (500 / 1,000,000 ร $2.50) + (1,500 / 1,000,000 ร $10.00)
= $0.00125 + $0.015
= $0.01625 (โ $0.016)
With cached input:
Total Cost = (Cached Input / 1,000,000 ร Cached Price) + (New Input / 1,000,000 ร Input Price) + (Output / 1,000,000 ร Output Price)
2. Image Generation - Token-based (image_generation_token)
Models: gpt-image-1, gpt-image-1-mini
These models have two pricing components:
A) Text tokens (for your prompt):
Text Cost = (Input Tokens / 1,000,000 ร Input Price) + (Output Tokens / 1,000,000 ร Output Price)
B) Image generation (per image by resolution and quality):
Image Cost = Number of Images ร Price per Image (from image_pricing)
Example with gpt-image-1:
- Input: $10.00 / 1M tokens
- Output: $40.00 / 1M tokens
- Image (low quality, 1024x1024): $0.011 / image
Generate 1 image with prompt "A beautiful sunset over mountains" (โ10 tokens input, โ50 tokens output):
Text Cost = (10 / 1,000,000 ร $10.00) + (50 / 1,000,000 ร $40.00)
= $0.0001 + $0.002 = $0.0021
Image Cost = 1 ร $0.011 = $0.011
Total Cost = $0.0021 + $0.011 = $0.0131 (โ $0.013)
Quality comparison (1 image, 1024x1024):
- Low quality: $0.011 per image
- Medium quality: $0.063 per image (5.7ร more expensive)
- High quality: $0.25 per image (23ร more expensive)
Resolution comparison (low quality):
- 1024x1024: $0.011
- 1024x1536: $0.016 (45% more expensive)
- 1536x1024: $0.016 (45% more expensive)
3. Image Generation - Fixed Price (image_generation)
Models: DALL-E 3, DALL-E 2
Formula:
Total Cost = Number of Images ร Price per Resolution
Example with DALL-E 3:
- 1024x1024: $0.12 per image
- 1024x1536: $0.12 per image
Cost for 5 images (1024x1024) = 5 ร $0.12 = $0.60
4. Audio Transcription (audio_transcription)
Models: Whisper
Formula:
Total Cost = Audio Duration (minutes) ร Price per Minute
Example:
- Price: $0.006 / minute
- Audio: 15 minutes
Cost = 15 ร $0.006 = $0.09
5. Text-to-Speech (text_to_speech)
Models: TTS
Formula:
Total Cost = (Characters / 1,000) ร Price per 1K Characters
Example:
- Price: $0.015 / 1K characters
- Text: 5,000 characters
Cost = (5,000 / 1,000) ร $0.015 = $0.075
6. Video Generation (video_generation)
Models: Sora
Formula:
Total Cost = Duration (seconds) ร Price per Second
Example:
- Price: $0.05 / second
- Video: 30 seconds
Cost = 30 ร $0.05 = $1.50
Practical Tips
-
Use the tiktoken library to count tokens accurately before making API calls:
import tiktoken encoding = tiktoken.encoding_for_model("gpt-4o") tokens = encoding.encode("Your text here") token_count = len(tokens)
-
Monitor your usage in the OpenAI dashboard to track actual token consumption.
-
Optimize costs:
- Use lower-quality image generation when high quality isn't needed
- Use smaller models (e.g., GPT-3.5 instead of GPT-4) for simpler tasks
- Cache frequently used prompts to benefit from cached input pricing
- Keep prompts concise to reduce input token count
-
Estimate before production:
- Test with small samples to measure actual token usage
- Account for system messages and API formatting overhead
- Add 10-20% buffer for unexpected token usage
-
Image token consumption varies:
- Low quality: ~85 tokens per image
- Medium quality: ~300-400 tokens per image
- High quality: ~765 tokens per image
Cost Comparison Example
Generate 100 images with text prompt (1024x1024):
| Model | Quality | Text Cost | Image Cost | Total Cost |
|---|---|---|---|---|
| gpt-image-1-mini | Low | $0.11 | $0.50 | $0.61 |
| gpt-image-1 | Low | $0.21 | $1.10 | $1.31 |
| gpt-image-1-mini | Medium | $0.11 | $1.50 | $1.61 |
| DALL-E 2 | Standard | $0 | $1.60 | $1.60 |
| gpt-image-1-mini | High | $0.11 | $5.20 | $5.31 |
| gpt-image-1 | Medium | $0.21 | $6.30 | $6.51 |
| DALL-E 3 | Standard | $0 | $12.00 | $12.00 |
| gpt-image-1 | High | $0.21 | $25.00 | $25.21 |
Assumes 1,000 input tokens and 5,000 output tokens for text processing.
Automated Cost Calculator
For automated cost calculation, use the openai-pricing-api Python library:
pip install openai-pricing-api
See the Python Library Usage section for complete documentation.
Or run the examples:
python examples/basic_usage.py
Additional Resources
- Official Pricing Page: https://openai.com/api/pricing/
- OpenAI Documentation: https://platform.openai.com/docs/
- Tokenizer Tool: https://platform.openai.com/tokenizer
- tiktoken Library: https://github.com/openai/tiktoken
Notes
- Data is scraped from the official OpenAI pricing page
- Always verify current prices on openai.com/api/pricing
- Script uses Playwright for dynamic content loading
- GitHub Actions is free for public repositories
License
Apache License 2.0 - see LICENSE
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file openai_pricing_api-0.1.0.tar.gz.
File metadata
- Download URL: openai_pricing_api-0.1.0.tar.gz
- Upload date:
- Size: 38.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e354649f0f858a1c774b026ed216406fc252dfec1a498b41f674480e3cea34ce
|
|
| MD5 |
b35a3e1744dec7fdee1d07ae891acfd6
|
|
| BLAKE2b-256 |
feb57788a3ff62a7b7a538e900dcc1652204ccdd9639d620c17938f9f78dc2b0
|
File details
Details for the file openai_pricing_api-0.1.0-py3-none-any.whl.
File metadata
- Download URL: openai_pricing_api-0.1.0-py3-none-any.whl
- Upload date:
- Size: 20.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7121848dba11e924890988b8dcbc73beb9f893e8ce716e67b44dc57c9d21d6c0
|
|
| MD5 |
9ab725df3de0dac9fe441392068673a0
|
|
| BLAKE2b-256 |
6998a14b2dea7ea31d4ff4c9f65a5c0b48a4498fa36e81afae6c0d01c1621184
|