Skip to content

Cap what a single request may cost

Providers compete on price, so the cost of a model is a range rather than a number, and the provider that serves you can change between requests. The X-0G-Provider-Max-Price-Usd-* headers turn that range into a bound you control: providers above your ceiling are removed from the candidate pool before routing happens at all. This page shows how to set the ceiling on chat and image requests, and what to do when the ceiling leaves nothing to route to.

The chat examples use glm-5.2; the image example uses z-image-turbo.

Header Unit Applies to
X-0G-Provider-Max-Price-Usd-Prompt USD per 1M tokens Chat endpoints only
X-0G-Provider-Max-Price-Usd-Completion USD per 1M tokens Chat endpoints only
X-0G-Provider-Max-Price-Usd-Image USD per image Image endpoints only

Each value is a finite, non-negative decimal. Full value domain and rejection rules: Provider routing headers.

A header sent to the wrong kind of endpoint is silently inert — an image ceiling on a chat request neither filters nor errors. That silence is worth remembering, because a typo in the header name behaves identically. Speech-to-text is billed per second and does not support a price ceiling yet.

Set one or both token ceilings. They are independent filters: a provider must satisfy every ceiling you send.

Terminal window
curl https://router-api.0g.ai/v1/chat/completions \
--max-time 120 \
--fail-with-body \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ZG_API_KEY" \
-H "X-0G-Provider-Max-Price-Usd-Prompt: <YOUR_PROMPT_CEILING>" \
-H "X-0G-Provider-Max-Price-Usd-Completion: <YOUR_COMPLETION_CEILING>" \
-d '{
"model": "glm-5.2",
"messages": [{"role": "user", "content": "Summarize this in one sentence."}]
}'

Image generation is priced per image, so it uses its own header and its own unit.

Terminal window
curl https://router-api.0g.ai/v1/images/generations \
--max-time 300 \
--fail-with-body \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ZG_API_KEY" \
-H "X-0G-Provider-Max-Price-Usd-Image: <YOUR_IMAGE_CEILING>" \
-d '{
"model": "z-image-turbo",
"prompt": "A lighthouse at dusk"
}'

The token ceilings do not apply here, and the image ceiling does not apply to chat. Sending the wrong one is inert rather than an error.

This is the property that makes the ceiling trustworthy: it is a hard filter applied before sorting and before failover. A provider over your ceiling is not deprioritized, it is not eligible. So during an outage, when the providers under your ceiling are exactly the ones that are down, the request fails instead of falling back to an expensive provider you had already ruled out.

The trade is explicit. A tight ceiling means a smaller pool, and a smaller pool has less to fail over to. See Handle failover and retries for the availability side of that bargain.

The response is an ordinary completion. Confirm the ceiling did what you wanted by reading the x_0g_trace block: provider tells you who served it, billing tells you what it cost.

{
"id": "chatcmpl-0852f405-6c56-40c2-a800-e6fd70785065",
"object": "chat.completion",
"model": "glm-5.2",
"choices": [
{
"index": 0,
"message": { "role": "assistant", "content": "..." },
"finish_reason": "stop"
}
],
"x_0g_trace": {
"request_id": "b41d7c92-5e83-4a6f-9c17-3d8e2f5a6b09",
"provider": "0xB01EBd79c3fd63ff52fD47C3935119601EEe2FdB",
"billing": { "input_cost": "32890000000000", "output_cost": "1914160000000000", "total_cost": "1947050000000000" }
}
}

Live response, 2026-07-20.

When the ceiling excludes every candidate, you get a 400 instead:

{
"error": {
"message": "failed to select provider: no provider available within max_price_usd: prompt<=1e-06 completion<=0 (USD per 1M tokens) image<=0 (USD per image)",
"type": "invalid_request_error",
"code": "no_provider_within_max_price"
},
"request_id": "ddb21d95-f541-441b-b507-de30f5349e9a"
}

Live response, 2026-07-20.

Status code Cause Fix
400 no_provider_within_max_price Every candidate is above your ceiling Raise the ceiling or pick another model. Do not retry: the pool is empty for structural reasons, not transient ones
400 pinned_provider_exceeds_max_price X-0G-Provider-Address names a provider above the ceiling The pin and the ceiling contradict each other. Drop one
400 invalid_max_price_usd Value is not a finite non-negative decimal Send a plain decimal with no currency symbol or unit suffix
The header appears to do nothing It was sent to the wrong endpoint kind, or the name is misspelled. Cross-dimension headers are inert, not rejected

Full list with retry guidance: Error codes.