Skip to main content
If your code already speaks the OpenAI API, three values change and nothing else does.
OpenAI model names such as gpt-4o do not alias to anything here. Pass a model id from GET /v1/models. Streaming, tools, and structured output use the same request and response shapes where the selected model’s page lists that capability. Streams terminate with data: [DONE], tool calls appear on the assistant message, and usage appears on the response.

Set an output budget

This is the one setting that decides whether a reasoning model has room to answer. Reasoning tokens are billed output that count toward max_tokens.
Reasoning models: output budgetreasoning tokens are billed outputmax_tokens: 2048budget exhaustedThe whole budget went to reasoning. content comes back empty, and the tokens are still billed.max_tokens: 16384answer deliveredreasoninganswerEach reasoning model’s page publishes its recommended minimum.Measured 2026-08-14 on this endpoint: at 2,048 tokens both public models returned an empty ortruncated answer, still billed. DeepSeek V4 Flash needs 16,384. Segment widths are illustrative.
Reasoning models: output budgetreasoning tokens are billed outputmax_tokens: 2048budget exhaustedThe whole budget went to reasoning. content comes back empty, and the tokens are still billed.max_tokens: 16384answer deliveredreasoninganswerEach reasoning model’s page publishes its recommended minimum.Measured 2026-08-14 on this endpoint: at 2,048 tokens both public models returned an empty ortruncated answer, still billed. DeepSeek V4 Flash needs 16,384. Segment widths are illustrative.
Where a recommended minimum is published, the model’s page in the Model Library carries it. You pay for tokens generated, not for the ceiling you set, so a generous budget costs nothing extra. If the answer comes back empty, check finish_reason: "length" means raise the budget, not that the model produced nothing.

Where the model’s thinking arrives

RunInfra emits the model’s thinking as reasoning on the message and on each stream delta. Older serving builds used reasoning_content, so a client that reads only the old name sees the answer but not the thinking. Measured per client: The answer is correct in every client above. Only access to the thinking differs, so pick accordingly if you want to render it.

Prompt caching and session affinity

Prefix caching is automatic server behavior on models with a published cached-input price. You do not select cache placement, retention, or reuse per request: prompt_cache_options and prompt_cache_retention are rejected with 400 hosted_parameter_not_supported. To maximize hit rate for multi-turn conversations and agent sessions, give repeat requests a consistent session hint so they keep landing where their cached prefix already lives:
  • Header: x-session-affinity: <your-conversation-or-task-id>
  • Body field: prompt_cache_key (the OpenAI SDK spelling), or a stable user
All of these work on /v1/chat/completions and /v1/responses; the hint is consumed for routing and never reaches the model. Without one, requests are grouped by workspace, which already gives steady sessions a warm cache. Cached tokens appear in usage.prompt_tokens_details.cached_tokens and bill at the cached-input rate published on that model’s page. The model page and public pricing page show any measured cache hit-rate figures that are currently published.

Framework configuration

Every snippet below was executed against https://api.runinfra.ai/v1 on 2026-08-14 with a real workspace key and returned a complete answer. Versions used: ai 7.0.65, @ai-sdk/openai-compatible 3.0.30, openai 7.4.0 (Node) and 2.54.0 (Python), langchain-openai, litellm.

LangChain

LiteLLM

LiteLLM reaches RunInfra through its openai/ provider prefix, and exposes the thinking as reasoning_content.
Add stream=True for deltas, reading chunk.choices[0].delta.content.

LlamaIndex

Both the OpenAI LLM class and OpenAIEmbedding accept a custom api_base.

AI SDK

@ai-sdk/openai-compatible reads reasoning_content and falls back to reasoning, which is the name we emit, so both the answer and the thinking come through.
generateText works the same way, with the thinking on reasoningText.
maxOutputTokens is the AI SDK’s name for the budget above. At maxOutputTokens: 2048 on nemotron-3-5-lightning-30b, text came back as an empty string in 2 of 5 runs and truncated in 4 of 5, because the reasoning stream consumed the budget first. At 4,096 all 5 runs returned a complete answer.
usage.outputTokenDetails.reasoningTokens reports 0 even when the model reasoned, because this endpoint does not yet break reasoning out of completion_tokens. Total outputTokens is correct and is what you are billed for.

Plain fetch, no SDK

A data: line can be split across two network reads, so the trailing partial line stays in buffer rather than being parsed. Dropping that carry is the usual cause of intermittent JSON.parse failures on a stream that works in testing.

Where RunInfra differs from OpenAI

Model APIs serve POST /v1/chat/completions, POST /v1/responses, and GET /v1/models. An endpoint you deployed yourself can expose more routes, such as embeddings or audio, depending on the model behind it; see Deployments.Not supported anywhere: /v1/completions (legacy, non-chat), /v1/files, /v1/assistants, /v1/threads, and /v1/batches. /v1/responses is a chat-completions compatibility adapter and does not implement state, hosted tools (web search, file search), conversation storage, or background jobs.On a model whose page lists tool calling, function tools work end to end on /v1/responses, in both spellings: declare tools flat ({"type": "function", "name", "parameters"}, the Responses shape) or nested under function (the chat shape). The model’s calls come back as function_call output items with call_id, name, and arguments; send results back as function_call_output input items with the matching call_id (string or content-part array), and resend prior output items in input since the endpoint is stateless. Streams carry the full item lifecycle (response.output_item.added, response.content_part.added, text and function_call_arguments deltas, the matching done events, and a spec-complete response.completed), so Codex-style clients that build items from output_item.done work unchanged. Harness fields: store is accepted and always treated as false, nothing is retrievable later; metadata, include (reasoning.encrypted_content, message.output_text.logprobs, or empty), truncation: "disabled", parallel_tool_calls, service_tier, and client_metadata are accepted; truncation: "auto" and previous_response_id are refused with the reason.On /v1/responses, output_text carries the final answer only. The model’s thinking arrives as its own reasoning output item ahead of the message (raw text under content as reasoning_text parts, summary empty), and on streams as response.reasoning_text.delta and response.reasoning_text.done events. A completion that spends its whole token budget thinking returns an empty output_text with the thinking preserved in the reasoning item, so raise max_output_tokens if you see that.
Fields on the forwarding allowlist reach the model unchanged. Fields that are not on it are dropped before the request leaves the gateway, silently rather than as an error, so a request shape that works today keeps working.Chat completions lists the allowlist field by field, and names the few that carry gateway behavior. It is the one authoritative list, so this page does not restate it.
Errors use the OpenAI envelope, { error: { message, type, code } }, with six error.type values: invalid_request_error, authentication_error, permission_error, not_found_error, rate_limit_error, and api_error. There is no server_error type; 5xx responses carry api_error. Every status and code is in Errors, and the triage is in Troubleshooting.Retry behavior belongs to your client configuration. Do not blindly retry a charge-bearing request after a partial stream may have reached your app; use an idempotency key instead. Quote the X-Request-Id response header on any support ticket.

Hugging Face clients

huggingface_hub and @huggingface/inference, verified.

Tool calling

A complete multi-turn loop.

Limits

Context, output, concurrency, tokens per minute.