Skip to content

Chat completions

Generate a text response with a specific model, or stream the answer as it arrives.

POST/v1/chat/completionsBearer token required

Request body

Send JSON with your selected model and conversation messages. Authentication uses a Router API key with paid access explicitly enabled, or a signed-in Playground session.

Every inference request must include a caller-generated UUID in Idempotency-Key. X-Max-Charge-Credits sets a lower maximum when needed; when omitted, the default maximum is 5 credits. Use a six-decimal string for an explicit limit, such as 5.000000 or 0.050000. Keep the same UUID and body for retries of the same logical request.

ParameterTypeDescription
modelstring · requiredExact enabled API edition ID. Router preserves your choice.
messagesarray · requiredText messages with system, user, or assistant roles.
streamboolean · optionalReturn a stream of content deltas instead of a full response.
max_tokensinteger · optionalMaximum output tokens, within the selected edition’s limit.
slippage_toleranceinteger · optionalPercent above the stored model suggestion, 0–100. Defaults to 30 for all callers, including explicit provider selection.
temperaturenumber · optionalSampling temperature accepted by the API definition.
provider_selectionobject · optionalSelect a published computer/model offer using its offer_id and integer pricing_revision. Omit for Auto routing.

Validation limits

  • messages must contain 1 through 16 items.
  • Roles are limited to system, user, and assistant.
  • Combined message text is limited to the edition’s max_prompt_bytes, at most 196,608 UTF-8 bytes.
  • Input longer than the edition’s context_length in tokens is rejected with context_length_exceeded; it is never truncated.
  • max_tokens is at least 1 and cannot exceed the selected edition’s limit or the 2,048-token platform ceiling. It defaults to 512, or the edition’s lower limit.
  • temperature is between 0 and 2.
  • A non-streaming request (stream omitted or false) must finish within about 110 seconds, because a silent connection is cut off by network timeouts. It allows at most 512 output tokens and about 24 KB of message text (roughly 8K tokens); a larger request is rejected with stream_required before anything is charged. Stream longer work.
  • Unknown properties and unsupported content shapes are rejected.

Example request

Set your base URL and API key as described in the Quickstart.

Request
ROUTER_REQUEST_ID="$(uuidgen)" # Reuse this ID if you retry the same request.curl "$ROUTER_BASE_URL/chat/completions" \  -H "Authorization: Bearer $ROUTER_API_KEY" \  -H "Idempotency-Key: $ROUTER_REQUEST_ID" \  -H "X-Max-Charge-Credits: 5.000000" \  -H "Content-Type: application/json" \  -d '{    "model": "gemma3:1b",    "messages": [      { "role": "user", "content": "Hello!" }    ]  }'

Price tolerance

Both provider input and output rates must be at most (1 + slippage_tolerance / 100) times the model's corresponding stored suggested rate. At the default 30%, a $1 suggestion permits a provider rate up to $1.30. Set "slippage_tolerance": 40 to allow up to $1.40, or 0 to allow only rates at or below the suggestion. Provider medians are for display only and never raise this baseline or the 2× provider save cap.

When no otherwise eligible offer fits, Router returns 503 slippage_tolerance_exceeded before admission, without reserving credits. Its optional error.minimum_slippage_tolerance is the lowest integer tolerance for a currently eligible offer within your credit limit. Review that value before sending a new logical request with a new idempotency UUID; prices and availability may change. Router never increases your tolerance automatically.

json
{"error":{"type":"router_error","code":"slippage_tolerance_exceeded","message":"No available provider fits your 30% slippage tolerance.","minimum_slippage_tolerance":40}}

A missing stored baseline starts background pricing research. While it runs, 503 pricing_pending includes Retry-After: 5; retry unchanged terms with the same UUID after the delay. No request is admitted until the baseline is persisted. suggested_price_unavailable indicates unreadable storage or research that cannot start; wait or choose another model.

Select a specific provider

Auto routing is the default: Router chooses the lowest eligible conservative credit reservation and rotates equal rounded reservations. See choosing a provider for the decision and provider discovery for the complete response contract. To choose a particular computer/model offer, fetch GET /public/provider-offers?model=gemma3%3A1b at the API origin (outside /v1). This public response includes provider identity, offer_id, pricing_revision, separate input/output rates in USD per 1M tokens, and availability. Use next_cursor as the next request's cursor query parameter to load more results. GET /public/provider-offers/{offer_id} retrieves one published offer directly.

Review the returned price, then include both selection fields. This synthetic example uses a placeholder offer UUID and revision; replace them with values from discovery.

bash
curl "$ROUTER_BASE_URL/chat/completions" \  -H "Authorization: Bearer $ROUTER_API_KEY" \  -H 'Content-Type: application/json' \  -H "Idempotency-Key: $REQUEST_ID" \  -H 'X-Max-Charge-Credits: 5.000000' \  -d '{    "model": "gemma3:1b",    "messages": [{"role": "user", "content": "Explain retrieval in two sentences."}],    "max_tokens": 128,    "provider_selection": {      "offer_id": "00000000-0000-4000-8000-000000000001",      "pricing_revision": 3    }  }'

REQUEST_ID must be a new caller-generated UUID for this logical request. The offer must match the requested model. A provider cannot serve paid requests from their own account. Selection is explicit on each API request; Playground's selection lasts only for its current conversation.

Router checks publication, eligibility, capacity and the displayed pricing revision before accepting the request. It never silently substitutes another offer or switches to Auto. Once accepted, the quote is immutable: later price changes or unpublishing do not alter that request. An interrupted accepted request may still incur a charge for accepted provider-reported usage; token counts are not independently verified; check its credit receipt.

StatusCodeRecovery
409provider_price_changedFetch the current offer, review the new price, and explicitly accept its new revision.
409provider_offer_unavailableThe offer is unpublished, no longer eligible, or does not match this model. Select another offer or explicitly choose Auto.
503selected_provider_unavailableThe selected computer is busy or offline. Wait, choose another offer, or explicitly choose Auto.
503self_provider_onlyChoose an offer owned by another account.

To explicitly use Auto, omit provider_selection. Changing the selection or pricing revision is a new logical request and requires a new UUID. For an uncertain result, keep the original UUID and unchanged body; do not create another paid request just to recover. See retry guidance.

Response

Read the assistant text from choices[0].message.content. A non-streaming response also includes request metadata and provider-reported usage. This abbreviated example uses synthetic values.

json
{  "id": "request_example",  "object": "chat.completion",  "created": 1789952400,  "model": "gemma3:1b",  "choices": [{    "index": 0,    "message": { "role": "assistant", "content": "Hello!" },    "finish_reason": "stop"  }],  "usage": {    "prompt_tokens": 8,    "completion_tokens": 2,    "total_tokens": 10  }}

The response includes an X-Request-Id header matching the caller's idempotency UUID. Store it with your application trace. The owner can check settlement through GET /v1/credits/requests/{request_id}; a completed answer and a confirmed final charge are distinct states.

Finish reasons

ValueMeaning
stopThe provider reached a normal stop condition.
lengthGenerated tokens reached the assigned output limit; the text may be incomplete.

Streaming

With stream: true, consume ordered content deltas and wait for the terminal event. Treat an interrupted stream as incomplete. See the streaming guide.

Errors

Account and spending limits return explicit errors. If no eligible priced provider is available, Router returns an explicit unavailable outcome. Provider eligibility is automatic after the required ownership, model, pricing, and capacity checks; it does not require administrator approval. A billing dependency outage does not fall back to an uncharged request.

Router fails explicitly when it cannot serve the request. See errors and limits for recovery guidance.