Inferway
Skip to content
Start by intent

Choose the job you need to finish right now.

Happy path

From empty shell to verified request.

  1. 1. Create an account. No credit card, no invite — sign-up is open at inferway.ai.
  2. 2. Copy a key. A Default key is created on your first visit to the Console and shown once. Rotate or add keys anytime under API keys.
  3. 3. Run the request. Set $INFERWAY_API_KEY and run the streaming command below.
  4. 4. Verify it worked. Check status, latency, tokens, and model in Console → Requests.

First request

One-command streaming quickstartbash
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."
    }
  ]
}'
Streaming

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. IDE and agent clients can choose non-streaming internally without exposing any setting: Inferway caps such requests at 4,096 total candidate output tokens and reports the applied per-candidate cap in the X-Inferway-Max-Tokens-Applied and X-Inferway-Max-Tokens-Reason response headers; longer output should still use streaming wherever the client supports it.

That’s it

You are using the same Chat Completions interface you already know.

  • Base URLhttps://api.inferway.ai/v1
  • API key$INFERWAY_API_KEY
  • Modelinferway/qwen3.8-27b

Response shape

Example streamed chunkjson
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]

If the first request does not work

Most first-run issues are configuration issues. Check these before changing application code.

SymptomLikely causeFast fix
401The 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.
404The 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.
429The request reached an account or anonymous quota, or a per-request size bound.Check the error dimension. Reduce input or max_tokens for a request-size limit; otherwise follow Retry-After when present.
504 / timeoutA long non-streaming output hit the roughly 100-second CDN first-byte timeout.Set stream=true on the request.
Drop-in config

Already using an OpenAI client?

OpenAI-compatible environment variablesbash
# 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'
Copy setup for your AI assistantInstalls the SDK, sets base_url and the model id, reads the key from an environment variable, writes a streaming smoke test. The prompt carries a placeholder, never a real key.

Thinking (reasoning tokens)

The served model does not emit reasoning (thinking) tokens unless the request opts in.

Reasoning tokens are billed as output tokens at the output price and are visible in usage.completion_tokens_details.reasoning_tokens.

Enable thinking per request with chat_template_kwargs.enable_thinking=true (OpenAI SDKs: pass it via extra_body) or reasoning: {"enabled": true}.

Chat completions — Python

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.

Pythonpython
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)
SDK & CODING TOOLS

Connect the tool you already use

Choose a tool for setup and supported features. The configuration follows the model selected at the top of this page.

Install the SDK (optional)

The first cURL request needs no dependencies. Install the OpenAI SDK only when you are ready to wire the integration into an application.

Installbash
# Python
pip install openai

# TypeScript / Node.js
npm install openai

Integration guide by tool

OpenCode

Available

Use Inferway as a custom provider in OpenCode. Your account must have model access enabled before connecting.

Model capability
Tool calling supported
Inferway interface
Available/v1/chat/completions
Use in this tool
Chat and coding tasks
ModelQwen3.8 27BView this model

Context 262,144 Max output 131,072

Verified on 1.18.25, macOS 26.6.2 arm64, 2026-09-19: basic conversation and file-read tool round trip against inferway/qwen3.8-27b.

Save this as opencode.json at the root of the scratch folder. The provider section keeps the public model ID as the model key; the composite model selector is provider/model. {env:INFERWAY_API_KEY} interpolates the variable set earlier; the key itself never enters the file. The 1024 output limit is the tested validation preset; a larger limit was not verified here.

Set INFERWAY_API_KEY in the terminal used to launch the client. Keep the key out of the configuration file.

opencode.jsonjson
{
  "$schema": "https://opencode.ai/config.json",
  "model": "inferway/inferway/qwen3.8-27b",
  "provider": {
    "inferway": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "Inferway",
      "options": {
        "baseURL": "https://api.inferway.ai/v1",
        "apiKey": "{env:INFERWAY_API_KEY}"
      },
      "models": {
        "inferway/qwen3.8-27b": {
          "name": "Inferway",
          "limit": {
            "context": 262144,
            "output": 1024
          }
        }
      }
    }
  }
}
OpenCodebash
opencode run --pure --format json --title 'Inferway basic check' --model 'inferway/inferway/qwen3.8-27b' --agent build --dir . 'Reply with exactly: connected'

Confirm the connection

  1. 1Confirm the basic-check response text is exactly connected with no API error.
  2. 2Run the read check below. The prompt does not contain the nonce; confirm the final text is exactly the nonce from the fixture. This verifies the read loop only — edit, shell, and other tools are not claimed here.
  3. 3Open Console → Requests to confirm the inference requests and token usage. Actual billing is the Console's, not any client estimate.

Confirm the connection

Read checkbash
opencode run --pure --format json --title 'Inferway read fixture' --model 'inferway/inferway/qwen3.8-27b' --agent build --dir . 'Read the file read-tool-fixture.txt and reply with exactly the nonce it contains, nothing else.'
Set up your key, full steps, and troubleshooting

Before you start

Install the named client using its official instructions. Pi here means the pi-mono coding agent; Hermes means Nous Research's Hermes Agent.

Once your Inferway account is activated, get an API key from Console → API keys. Use a dedicated key for this client and review its model access and spending limits. Both live and test prefixes use the same inference and billing path; test is an environment label, not a free or simulated inference mode.

Use an Inferway key for Inferway's endpoint. An OpenRouter key belongs to OpenRouter and cannot authenticate to this address.

Keep the key in the client's credential store or your local environment. Do not paste it into a prompt, screenshot, or committed configuration. These examples use bash/zsh on macOS or Linux.

Make the key available to this terminal

The prompt below hides your input and keeps the key out of shell history. Start the client from this same terminal; a separately opened app may not inherit this variable.

INFERWAY_API_KEYbash
printf 'Inferway API key: '
IFS= read -r -s INFERWAY_API_KEY
printf '\n'
export INFERWAY_API_KEY

Confirm the endpoint and model

Use the full model ID inferway/qwen3.8-27b. The Base URL ends in /v1 once; do not append /chat/completions to a Base URL setting. Check that the response below contains the model ID.

List modelsbash
curl --fail-with-body --silent --show-error --max-time 30 \
  'https://api.inferway.ai/v1/models' \
  -H "Authorization: Bearer $INFERWAY_API_KEY"

Create the scratch folder

OpenCode can load a project config from the project root (per-project config and custom paths are covered in the OpenCode configuration docs). Work in a scratch folder so the test never touches your daily settings or your global provider list.

The accepted live test used OpenCode CLI on macOS 26.6.2 arm64 against the catalog model below; check your own installed version before following along. git init just gives OpenCode a clean project root; no commit is needed for the check.

Scratch folderbash
# Scratch folder with a small read fixture
mkdir inferway-opencode-verify && cd inferway-opencode-verify && git init -q
printf 'nonce-7f3a9c\n' > read-tool-fixture.txt

Optional: use Inferway in your daily config

After the checks pass, copy the provider block (and the model entry under it) into your existing OpenCode config, keeping your own settings. You do not need the scratch folder or the test fixture for daily use.

Cost and usage

Actual consumption is recorded by Inferway: open Console → Requests to see each request's status and token usage, and Console → Usage for totals. Numbers a client shows locally are its own estimates, not billing amounts; rely on the Console.

If a request fails

Authentication: check that an API key is present, active, and allowed to use the model. Reopen the client from the terminal containing the variable. Never print the full key when debugging.

Wrong endpoint or model: check for a duplicate /v1, use the exact published model ID, and confirm the client is using Chat Completions. A request to /responses or /completions cannot be repaired by changing the key.

Limits or timeout: check wallet balance and key limits, respect Retry-After, and reduce the prompt or output budget. Keep streaming enabled for long outputs. Avoid repeated agent retries while diagnosing.

When contacting support, share the client version, model ID, timestamp, and request ID if available. Redact credentials and source code.

To disconnect: revoke this tool's key in the Console and remove the Inferway provider from the client.

Standalone guide

MCP (Model Context Protocol)

Live

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.

Accounts with no spendable balance are routed to the free lane automatically instead of getting a 402 error — the same free tier as the REST API (60 requests/minute). Registered users are never treated worse than anonymous guests.

MCP server entryjson
{
  "mcpServers": {
    "inferway": {
      "url": "https://api.inferway.ai/v1/mcp/sse",
      "headers": {
        "Authorization": "Bearer $INFERWAY_API_KEY"
      }
    }
  }
}

Production checklist

  • Keep keys server-side. Never ship inferway_live_… keys in browsers, mobile apps, or public repos.
  • Stream long outputs. Anything that can exceed the CDN first-byte window must set stream=true.
  • Budget max tokens. Enforce a per-route max_tokens ceiling so costs and latency stay predictable.
  • Monitor metadata. Track status, latency, token counts, and model; never log prompt or completion bodies if you need zero-retention semantics end to end.
Transparency checklist

Before you put traffic behind Inferway, start with the hub, then drill into live status and raw reports.

Endpoint reference

Inferway keeps the OpenAI-compatible path small and predictable, then exposes account, billing, usage, and agent operations as separate first-party endpoints.

OpenAI-compatible API/v1/chat/completions

Use this for chat, tools, JSON mode, and streaming with OpenAI SDKs.

Interactions API/v1/interactions

Use this for video generation: durable background jobs you submit once and poll until the result is ready.

Console API/v1/keys · /v1/billing · /v1/usage · /v1/requests

Use this for server-side key, wallet, usage, and request-metadata workflows.

EndpointMethodPurpose
/v1/chat/completionsPOSTOpenAI-compatible chat completions
/v1/interactionsPOSTAsynchronous video generation jobs (four operations on one route)
/v1/modelsGETList published models with capability and pricing metadata
/v1/mcp/sse · /v1/mcp/messagesGET · POSTMCP server endpoint (live)
/v1/keysGET / POST / DELETEManage direct API keys
/v1/billingGETWallet summary and recent usage
/v1/billing/transactionsGETWallet ledger transactions
/v1/billing/checkoutPOSTCreate a Stripe Checkout top-up session
/v1/usageGETAggregated usage for a time window
/v1/requestsGETRequest metadata history (no content)
/healthGETGateway and backend health status
/v1/statsGETPublic status page payload

Interactions: one route, four operations

Video generation does not return inline. Every call goes to POST /v1/interactions and names the operation in the body's op field; the job is durable, so a dropped connection never loses work already paid for.

opPurpose
prepare_uploadRequest a short-lived, size-bounded upload contract for input media.
createSubmit a generation intent and receive an interaction id. Charged once, at the ordered duration.
getRead the durable state, the current stage, and — once delivery commits — the result and its download URL.
cancelBest-effort cancellation of a queued or in-flight job.
  • mode must be "background". Synchronous and streaming modes are rejected with 422; there is no inline variant of this route.
  • Idempotency-Key is required on create. The same key with the same request returns the original receipt without charging again; the same key with a different request fails closed with 409.
  • model, mode, duration_seconds and prompt are all top-level fields of the request body. duration_seconds is required and accepts only the published whole-second tiers — it is what the job is billed on.
  • Poll with the get operation until the state is terminal. Our own console polls every 2 seconds; there is no webhook and no long-poll.

Supported public endpoints are POST /v1/chat/completions, POST /v1/interactions and GET /v1/models. The legacy POST /v1/completions is not served: it answers 501 (not implemented) and names the chat completions route to use instead. POST /v1/messages (Anthropic-format) is served but not yet open to API keys: a configured client is refused with a permission error until we announce it.

Models

2

Choose a model to see its published capability facts. API examples and tool setup use the same selection.

Authentication

Authentication headerhttp
Authorization: Bearer $INFERWAY_API_KEY
  • API keys. Every key is prefixed inferway_live_… and is issued for server-side workloads.
  • Browser apps. Do not expose direct keys client-side; proxy requests through your backend.

Error codes

Inferway returns OpenAI-compatible error objects: {"error": { "type": "...", "message": "...", "code": "..." }}

Paid requests reserve prompt-estimate × input price + max_tokens × output price up front. Eligible requests can use registered FREE quotas when spendable funds are exhausted; FREE requests do not charge the wallet. A 402 refusal happens before dispatch and charges nothing. An authenticated request refused with 400 before it is dispatched appears in your Console request history with zero tokens and zero cost, so the failure can be diagnosed later. Balances render with 4 decimals; prices come from the live rate card.

Cached input tokens are reported in usage.prompt_tokens_details.cached_tokens and bill at the cache rate. On qwen3.8-27b the cache matches whole 1,600-token blocks and never reuses a prompt's last full block, so a request needs roughly 3,200 input tokens or more before any of it can hit; shorter requests always bill at the input rate.

Live error catalog

The complete set of error codes /v1/chat/completions and /v1/agent/chat can return, read from the gateway's own catalog rather than transcribed. Each row carries the HTTP status, whether a retry is safe, and the exact message the API sends. Checkout, billing and key-management endpoints return their own codes, not listed here.

CodeHTTPRetry safeMeaning
admission_paused503Yes — back off firstPaid admission is paused while we finish a service change. Retry shortly; nothing is wrong with this request.
authentication_error401NoAuthentication failed.
conflict409NoA conflict occurred with the current state of the resource.
free_quota_exhausted429Yes — back off firstFree quota exhausted. Please retry later.
free_tier_unavailable503Yes — back off firstThe free tier is temporarily unavailable; please retry shortly.
internal_error500NoAn internal error occurred.
internal_tool_failure500NoAn internal tool error occurred.
invalid_request400NoThe request was invalid.
malformed_upstream502NoReceived an invalid response from the upstream service.
model_unavailable503Yes — back off firstThis model is temporarily out of service. Other models are unaffected; please retry later.
payment_required402NoPayment required. Add credit at https://inferway.ai/console/billing
rate_limited429Yes — back off firstRate limit exceeded. Please retry later.
service_unavailable503NoService outage in progress. Live status: https://inferway.ai/status
upstream_rejected422NoThe upstream service rejected the request.
upstream_unavailable503Yes — back off firstThe service is temporarily unavailable.
Codes, statuses and retry policy read from GET /v1/public/errors

Rate limits and quotas

Quota denials return HTTP 429. Check the error code, window and dimension, and follow Retry-After when present. Per-request size limits require reducing input or max_tokens; waiting does not change them.

SubjectLimitWindow
Anonymous playground60per minute, per IP
Anonymous playground300per hour
Anonymous playground1,000per rolling 24 hours
Funded accountsAccount limitsFree caps no longer apply — visible in the console

Registered free accounts

Registered free accounts: 8 requests/second burst, 60 requests/minute, 300 requests/hour and 1,000 requests/day, with 2 concurrent requests. No per-request input or output token cap, and no per-minute or daily token quota.

Hourly and daily request counts are rolling windows, not a reset at a fixed time. API keys on the same account share these request counts.

Each request is still bounded by the model's own context length and maximum output. Use streaming for outputs above 4,096 tokens.

  • X-RateLimit-Limit. The quota of the current RPM window.
  • X-RateLimit-Remaining. Requests remaining in the current window.
  • X-RateLimit-Reset. Unix timestamp when the current window resets.
  • Retry-After. Seconds to wait before retrying after a 429.

Operational limits

  • Concurrency ceiling. Registered FREE accounts allow 2 concurrent requests. Funded accounts follow their account and key policies.
  • Data retention. Zero for content; metadata only, for billing and reliability.

OpenAI compatibility for the chat API

The matrix below reflects how the gateway actually handles each parameter, based on real runtime verification.

ParameterStatusNotes
modelSupportedRewritten to the backend model ID before proxying.
messagesSupportedRequired non-empty list; validated and forwarded to the inference engine.
streamSupportedStreaming path implemented; stream_options.include_usage is injected automatically.
temperatureSupportedPassed through to the inference engine; also logged for billing metadata.
top_pSupportedListed in supported_sampling_parameters and forwarded.
max_tokensSupportedPassed through to the inference engine.
stopSupportedListed in supported_sampling_parameters and forwarded.
nUntestedNo gateway-level handling; forwarded unchanged. Behavior depends on the backend.
logprobsUntestedNo gateway-level handling; forwarded as part of the raw body. Not verified against live responses.
toolsSupportedListed in supported_features: ["tools", "json_mode"] and forwarded.
response_formatSupportedGateway advertises json_mode; the field is forwarded as part of the raw body.
vision inputUntestedModel metadata declares input_modalities: ["text"]. Gateway extracts image_url only for the CSAM hash check; inference behavior unverified.

Thinking is off by default. To turn it on, send "reasoning": {"enabled": true} and budget at least ~16k max_tokens for that request — a smaller budget can be spent entirely on reasoning, leaving no visible answer.

Image input — minimal examples

Two minimal request shapes that each ship an inline image to a model whose catalog declares image_input. The image is inlined as a base64 data URL or base64 source; the gateway enforces the same per-image, per-kind total and request-level 16 MiB envelope as the playground.

Behavior of every snippet below is currently bounded by the same inference-unverified declaration listed in the compatibility matrix above.

OpenAI Chat Completions

image_url.content points at a data URL with the image bytes base64-encoded. The MIME matches what the catalog accepts.

OpenAI Chat Completionsjson
POST https://api.inferway.ai/v1/chat/completions
Authorization: Bearer $INFERWAY_API_KEY
Content-Type: application/json

{
  "model": "inferway/qwen3.8-27b",
  "messages": [
    {
      "role": "user",
      "content": [
        {"type": "text", "text": "What is in this image?"},
        {
          "type": "image_url",
          "image_url": {
            "url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII="
          }
        }
      ]
    }
  ]
}

Anthropic Messages

Anthropic takes a base64 source object instead of a data URL; the gateway routes Anthropic-format requests to the same image_input envelope. The Messages endpoint is not yet open to API keys — see the endpoint reference above.

Anthropic Messagesjson
POST https://api.inferway.ai/v1/messages
Authorization: Bearer $INFERWAY_API_KEY
Content-Type: application/json

{
  "model": "inferway/qwen3.8-27b",
  "max_tokens": 1024,
  "messages": [
    {
      "role": "user",
      "content": [
        {"type": "text", "text": "What is in this image?"},
        {
          "type": "image",
          "source": {
            "type": "base64",
            "media_type": "image/png",
            "data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII="
          }
        }
      ]
    }
  ]
}

Minimal sample app

Minimal sample apppython
#!/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})

Next steps