Pricing & Costs
Spectra calculates costs for every tracked AI request. The pricing system is database-driven, supporting both token-based pricing for language models and unit-based pricing for image, audio, and video models. Prices are organized by provider, model, and tier, and can be updated at runtime through the dashboard or by re-importing a pricing catalog — no configuration file changes or deployments required.
All costs are stored in cents with decimal precision (for example, 0.004200 cents), providing sub-cent accuracy for high-volume token-based operations.
How Pricing Works
When a tracked request completes, Spectra's cost calculation pipeline performs the following steps:
- Model identification — The model name is extracted from the API response (not the request), ensuring accuracy even when the provider resolves an alias to a specific snapshot.
- Pricing lookup — The
PricingServicequeries thespectra_modelsandspectra_pricingtables for a matching provider, model, and tier combination. Lookups are cached for performance. - Pricing unit resolution — The
pricing_unitfield on the model record determines which cost formula to apply:tokens,image,video,minute,second, orcharacters. - Cost calculation — The appropriate formula is applied using the extracted metrics (tokens, image count, duration, etc.) and the resolved prices.
- Persistence — The calculated cost is stored in
prompt_cost,completion_cost, andtotal_cost_in_centson the request record.
Pricing Units
Each model in the pricing catalog has a pricing_unit that determines how its cost is calculated:
| Unit | Used By | Calculation Basis |
|---|---|---|
tokens | LLMs, embeddings | Per 1M tokens (separate input and output prices) |
image | DALL-E, Stable Diffusion | Per image generated |
video | Sora | Per video generated |
minute | Whisper STT | Audio duration in minutes |
second | Replicate video/audio | Duration in seconds |
characters | OpenAI TTS, ElevenLabs | Per 1M characters of input text |
Token-Based Cost Formula
For models priced per token — the most common case for language models and embeddings — Spectra applies a formula that accounts for both regular and cached prompt tokens. Cached token pricing reflects the reduced rates offered by providers like OpenAI, Anthropic, Google, and xAI for prompt caching:
regular_prompt_tokens = max(0, prompt_tokens - cached_tokens)
cached_price = cached_input_price ?? input_price
prompt_cost = (regular_prompt_tokens × input_price + cached_tokens × cached_price) / 1,000,000
completion_cost = (completion_tokens × output_price) / 1,000,000
total_cost = prompt_cost + completion_costPrices in the spectra_pricing table are stored in cents per million tokens. The division by 1,000,000 in the formula converts from per-million pricing to the actual cost for the number of tokens consumed.
Unit-Based Cost Formulas
For non-token models, cost is calculated based on the model's pricing unit and the relevant metric extracted from the response:
| Unit | Formula |
|---|---|
| Per image | image_count × price_per_unit |
| Per video | video_count × price_per_unit |
| Per minute | (duration_seconds / 60) × price_per_unit |
| Per second | duration_seconds × price_per_unit |
| Per character | (input_characters × price_per_unit) / 1,000,000 |
Pricing Tiers
Some providers offer multiple pricing tiers with different price points for the same model. Spectra supports per-tier pricing, allowing accurate cost tracking regardless of how you access the API.
OpenAI Tiers
| Tier | Description |
|---|---|
standard | Regular pricing (default) |
batch | Approximately 50% discount for asynchronous processing with up to 24-hour turnaround |
flex | Approximately 30% discount with higher latency tolerance |
priority | Premium pricing with faster processing guarantees |
Anthropic Tiers
| Tier | Description |
|---|---|
standard | Regular pricing (default) |
batch | Discounted rate for asynchronous batch processing |
Configure the default tier per provider in config/spectra.php. This tier is used when no explicit tier is specified on the request:
'costs' => [
'provider_settings' => [
'openai' => [
'default_tier' => env('SPECTRA_OPENAI_PRICING_TIER', 'standard'),
],
'anthropic' => [
'default_tier' => env('SPECTRA_ANTHROPIC_PRICING_TIER', 'standard'),
],
],
],You can override the tier on a per-request basis using the provider macro:
Http::openai('gpt-4o', pricingTier: 'batch')
->post('/chat/completions', [...]);Or set the tier globally for all requests in the current process:
Spectra::withPricingTier('batch');
// All subsequent requests use batch pricing
// ...
Spectra::clearGlobals();Importing Pricing Data
Spectra ships with a default pricing catalog in database/data/pricing.json that covers all built-in providers. Import it using the Artisan command:
php artisan spectra:pricing --forceTo use a custom pricing file — for example, to add pricing for a custom provider or update prices ahead of the next package release:
php artisan spectra:pricing --path=/path/to/my-pricing.json --forceThe command creates or updates records in spectra_models and spectra_pricing, matching by provider name and model internal name. See Artisan Commands for the full JSON format specification.
Managing Pricing in the Dashboard
The Pricing screen in the dashboard (/spectra/pricing) provides a graphical interface for managing the pricing catalog at runtime. You can browse all providers and their models, view and edit per-tier prices, add new models to a provider, delete models you no longer need, and clear the pricing cache after making changes. This is particularly useful for updating prices without a deployment or for adding models that are not yet included in the bundled catalog.
Pricing Cache
Pricing lookups are cached in memory to avoid repeated database queries on every tracked request. The cache uses your application's default cache driver with a configurable TTL:
'costs' => [
'cache' => [
'enabled' => true,
'store' => null, // Uses default cache driver
'ttl' => 3600, // 1 hour in seconds
],
],The cache is cleared automatically when you import pricing via the Artisan command. You can also clear it manually through the dashboard or by calling the API endpoint:
POST /spectra/api/pricing/cache/clear