Skip to main content
Responses include the charged cost:
Text is billed by exact token usage, not a flat request fee. Read GET /api/v1/pricing for the live machine-readable rate sheet, or pricing on each GET /api/v1/models record; the same tables drive routing and billing.

Developer Balance

You prepay a balance and requests draw from it — the same balance covers the REST API and the MCP server, and it never expires. Add funds at Developers → Billing — any amount from $5 to $2,000, with $25, $100, and $250 presets — or verify your phone on your first paid action to unlock a $0.50 starter balance free. Every top-up carries an 8% service fee ($25 of credit costs $27 at checkout); model prices carry no hidden markup. What a pack buys: it depends on the selected model, prompt size, cached input, and output length. Run POST /api/v1/estimate against your real prompts and enforce routing.max_cost_usd when a request needs a hard ceiling.

Text — POST /api/v1/responses or /chat/completions

Billed per token: input at the metered input rate, provider-cache-read tokens at the cached-input rate, output at the metered output rate. Models with a long-context tier bill the whole request at the higher tier once the prompt passes the threshold. Rates below are GET /api/v1/pricing (pricing_version 2026-09-01.provider-rails.1) filtered to models that are servable right now; always read live numbers before you budget.Those are the models most people start with. All 169 chat models are priced — read GET /api/v1/pricing for the complete machine-readable sheet, or open any model’s page from Models for its own rate. Those are the numbers that bill you; this table is a convenience copy of a handful of them.gpt-5.5-pro’s cached-input rate equals its input rate on purpose: OpenAI offers no cached-input discount on that model, so it is passed through unchanged.ninja/auto bills at whichever model it resolves to.

Provider rails can price differently

Most models are served by more than one provider. The rate above is the model’s default rail — the one you normally get. When that provider is unavailable and your request fails over, you are billed the rail that actually served, at its own published rate, which can be higher or lower than the default.Each provider’s rate is on the model record: GET /api/v1/models/{id} returns a providers array, and any rail that prices differently from the default carries its own pricing. Every response still reports what it actually cost in cost_usd, and routing.max_cost_usd remains a hard ceiling regardless of which rail serves.

Images — POST /api/v1/images/generations

n images = n × the per-image price.

Video — POST /api/v1/videos

A seedance-2.5 request that attaches reference_video is $14.52 (the provider bills a video input at four times the clip rate); GET /pricing reports it as per_video_with_reference_video_cents.Revising a finished gemini-omni-flash clip in place (video_id on POST /videos) is $1.15 per edit and $1.35 per extension — the clip is carried as context on top of the seconds rendered.Failed video jobs are refunded automatically.

Search — POST /api/v1/search

$0.05 per query.

Live price sheet

GET /api/v1/pricing is public (no key) and returns the same tables billing uses:
  • metered_input_per_mtok, metered_output_per_mtok, and metered_cached_input_per_mtok are the billing rates. long_context is null for models without a tier; when present, the tier applies to the whole request once the prompt passes threshold_tokens.
  • typical_request_cents is a derived 5,000-in / 1,000-out reference for comparison only (flat_request_cents is its deprecated alias). Requests pre-authorize an estimated maximum and settle to actual usage.
  • Caching — two different things, priced differently. NinjaChat runs no response cache: send the same request twice and it executes twice and bills twice. What you can use is the provider’s prompt cache — set routing.caching: "auto", and input tokens that hit the provider’s cache bill at metered_cached_input_per_mtok instead of metered_input_per_mtok. cache_hit_fraction is deprecated and always null; it described a response-cache discount that no longer exists.
  • Video prices are ceilings. per_video_cents is the model’s longest accepted duration (basis: "max_duration"), not a typical charge. Shorter requests settle lower — per-second models bill each second up to their cap, bucketed models (Veo, Kling) bill the nearest supported length. Each model’s GET /models record carries its per-second rate and duration bounds — price a specific duration from those. POST /estimate prices chat only.
  • The sheet lists every priced id, including models that are not currently servable. Check servable on GET /models before pinning one.

You’ll never be surprised

Cap each request

Use routing.max_cost_usd with an explicit model or ninja/auto.

Warnings before walls

Signed balance.low webhooks fire at $5 and $1. Project budget.alert events fire at 50%, 80%, and 100%. Out of funds returns a clean 402 before execution.

Failures don't bill

Failed generated requests are not charged. Failed video jobs are refunded automatically.

Watch it live

Per-request logs and spend in the console.

From code

Python SDK