/v1/chat/completionsUse this for chat, tools, JSON mode, and streaming with OpenAI SDKs.
Start with one copyable request, then follow the path that matches your job.
The docs are organized around the user journey rather than product internals: first request, migration, debugging, and production readiness. Reference details are still below when you need them.
Follow these steps in order. Each step answers the next question a new developer has: where do I sign up, where is my key, what do I run, and how do I know it worked?
Zero-dependency smoke test against the chat completions endpoint. Set $INFERWAY_API_KEY to a inferway_live_… key, paste, and run. Tokens print as they arrive.
export INFERWAY_API_KEY="inferway_live_..." curl https://api.inferway.ai/v1/chat/completions \ -H "Authorization: Bearer $INFERWAY_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "inferway/qwen3-8-27b", "stream": true, "messages": [{"role": "user", "content": "Say hello in one short sentence."}] }'
curl https://api.inferway.ai/v1/chat/completions \
-H "Authorization: Bearer $INFERWAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "inferway/qwen3-8-27b",
"stream": true,
"messages": [{"role": "user", "content": "Say hello in one short sentence."}]
}'Non-streaming requests pass through a CDN with roughly a 100-second first-byte timeout, so any long output must set stream=true. Non-streaming is fine for short completions.
Only three values change when you move an existing OpenAI-compatible integration over.
https://api.inferway.ai/v1$INFERWAY_API_KEYinferway/qwen3-8-27bStreamed chunks are OpenAI-compatible: concatenate choices[0].delta.content as chunks arrive; the final chunk carries usage.
data: {
"id": "chatcmpl_...",
"object": "chat.completion.chunk",
"model": "inferway/qwen3-8-27b",
"choices": [
{
"index": 0,
"delta": { "role": "assistant", "content": "Hello" },
"finish_reason": null
}
]
}
data: [DONE]Most first-run issues are configuration issues. Check these before changing application code.
| Symptom | Likely cause | Fast fix |
|---|---|---|
| 401 | The key is missing, revoked, copied incorrectly, or not exported in this shell. | Re-copy the key from Console → API keys, then run echo $INFERWAY_API_KEY locally before retrying. |
| 404 | The client is pointed at the wrong base URL or duplicated the /v1 path. | Use https://api.inferway.ai/v1 as the base URL and call /chat/completions once. |
| 429 | The request hit the free-use or keyless rate limit. | Read Retry-After, back off, and check the rate-limit table below. |
| 504 / timeout | A long non-streaming output hit the roughly 100-second CDN first-byte timeout. | Set stream=true on the request. |
Keep your existing request shape. Point the client at Inferway, reuse your server-side key, and pin the published model id.
# For OpenAI-compatible clients that read OpenAI env vars export OPENAI_API_KEY="$INFERWAY_API_KEY" export OPENAI_BASE_URL="https://api.inferway.ai/v1" export INFERWAY_MODEL="inferway/qwen3-8-27b"
The official OpenAI Python SDK works against any OpenAI-compatible base URL. Swap the base URL, keep your existing key. This non-streaming shape is fine for short completions; anything long must stream.
import os from openai import OpenAI client = OpenAI( base_url="https://api.inferway.ai/v1", api_key=os.environ["INFERWAY_API_KEY"], ) resp = client.chat.completions.create( model="inferway/qwen3-8-27b", messages=[{"role": "user", "content": "Say hello in one short sentence."}], max_tokens=64, ) print(resp.choices[0].message.content)
The first cURL request needs no dependencies. Install the OpenAI SDK only when you are ready to wire the integration into an application.
# Python pip install openai # TypeScript / Node.js npm install openai
The MCP endpoint is live. Point an MCP-capable client at the server URL below and authenticate with the same API key; tools are served over the standard protocol, and the same zero-retention rules apply.
{
"mcpServers": {
"inferway": {
"url": "https://api.inferway.ai/v1/mcp/sse",
"headers": {
"Authorization": "Bearer $INFERWAY_API_KEY"
}
}
}
}Before you put traffic behind Inferway, start with the hub, then drill into live status and raw reports.
Inferway keeps the OpenAI-compatible path small and predictable, then exposes account, billing, usage, and agent operations as separate first-party endpoints.
/v1/chat/completionsUse this for chat, tools, JSON mode, and streaming with OpenAI SDKs.
/v1/keys · /v1/billing · /v1/usage · /v1/requestsUse this for server-side key, wallet, usage, and request-metadata workflows.
| Endpoint | Method | Purpose |
|---|---|---|
| /v1/chat/completions | POST | OpenAI-compatible chat completions |
| /v1/models | GET | List published models with capability and pricing metadata |
| /v1/mcp/sse · /v1/mcp/messages | GET · POST | MCP server endpoint (live) |
| /v1/keys | GET / POST / DELETE | Manage direct API keys |
| /v1/billing | GET | Wallet summary and recent usage |
| /v1/billing/transactions | GET | Wallet ledger transactions |
| /v1/billing/checkout | POST | Create a Stripe Checkout top-up session |
| /v1/usage | GET | Aggregated usage for a time window |
| /v1/requests | GET | Request metadata history (no content) |
| /health | GET | Gateway and backend health status |
| /v1/stats | GET | Public status page payload |
Start with the published model below, then use /v1/models when your app needs to display capabilities, context window and pricing metadata dynamically.
| Field | Current value | How to use it |
|---|---|---|
| Recommended model | inferway/qwen3-8-27b | Use as the default model in chat-completions calls. |
| Context window | 262,144 | Input token ceiling for a single request. |
| Max output | 32,768 | Output token ceiling for a single response. |
| Precision | NVFP4 | The precision advertised is the precision served, with no downgrade under load. |
Authenticate every direct API request with a bearer token issued in the Console. Treat live keys as server-side secrets and rotate them if exposure is suspected.
Authorization: Bearer $INFERWAY_API_KEY
Inferway returns OpenAI-compatible error objects: {"error": { "type": "...", "message": "...", "code": "..." }}
| HTTP | type | Meaning | What to do |
|---|---|---|---|
| 400 | invalid_request | Malformed request or invalid parameters | Check the request body |
| 401 | invalid_auth | API key invalid, revoked, or session expired | Refresh your key or re-authenticate |
| 402 | insufficient_balance | Wallet + credit below the minimum threshold | Top up via Console → Billing |
| 403 | content_policy | Content policy violation or sanctioned region | Do not retry; review AUP/Terms |
| 429 | rate_limited | Free-use or concurrency limit exceeded | Back off and retry (read Retry-After) |
| 500 | internal_error | Gateway internal error | Retry; contact support if persistent |
| 502 | backend_unavailable | Inference backend is unreachable | Back off and retry |
| 503 | draining | Gateway is draining for maintenance | Retry after the Retry-After interval |
| 530 | upstream_down | Inference unavailable — usually a maintenance window | The status page says what is affected and for how long |
Every /v1/* inference response carries X-RateLimit-* headers. When a limit is hit the response is HTTP 429 with Retry-After and a rate_limited error object.
| Subject | Limit | Window |
|---|---|---|
| Free and keyless use | 60 | per minute, per IP |
| Free and keyless use | 120 | per hour |
| Free and keyless use | 1,000 | per UTC day |
| Funded accounts | Account limits | Free caps no longer apply — visible in the console |
The matrix below reflects how the gateway actually handles each parameter today — not how we wish it handled it.
| Parameter | Status | Notes |
|---|---|---|
| model | Supported | Rewritten to the backend model ID before proxying. |
| messages | Supported | Required non-empty list; validated and forwarded to the inference engine. |
| stream | Supported | Streaming path implemented; stream_options.include_usage is injected automatically. |
| temperature | Supported | Passed through to the inference engine; also logged for billing metadata. |
| top_p | Supported | Listed in supported_sampling_parameters and forwarded. |
| max_tokens | Supported | Passed through; guest sandbox requests are capped to 256 tokens. |
| stop | Supported | Listed in supported_sampling_parameters and forwarded. |
| n | Untested | No gateway-level handling; forwarded unchanged. Behavior depends on the backend. |
| logprobs | Untested | No gateway-level handling; forwarded as part of the raw body. Not verified against live responses. |
| tools | Supported | Listed in supported_features: ["tools", "json_mode"] and forwarded. |
| response_format | Supported | Gateway advertises json_mode; the field is forwarded as part of the raw body. |
| vision input | Untested | Model metadata declares input_modalities: ["text"]. Gateway extracts image_url only for the CSAM hash check; inference behavior unverified. |
Source of truth: the /v1/chat/completions handler and /v1/models capability metadata.
A single-file interactive chat loop with streaming output. Copy, set INFERWAY_API_KEY, and run. Requires pip install openai.
#!/usr/bin/env python3 """Minimal Inferway chat sample. Requires: pip install openai""" import os from openai import OpenAI client = OpenAI( base_url="https://api.inferway.ai/v1", api_key=os.environ["INFERWAY_API_KEY"], ) messages = [{"role": "system", "content": "You are a helpful assistant."}] while True: user = input("You: ") if not user: break messages.append({"role": "user", "content": user}) stream = client.chat.completions.create( model="inferway/qwen3-8-27b", messages=messages, stream=True, ) reply = "" print("Assistant: ", end="", flush=True) for chunk in stream: if not chunk.choices: continue piece = chunk.choices[0].delta.content if piece: reply += piece print(piece, end="", flush=True) print("\n") messages.append({"role": "assistant", "content": reply})