Yearly Pay yearly and get 2 months free on every paid plan. See plans
Sign in Start free

OpenAI-compatible API

Last updated 11 Nov 2026

What it is

The OpenAI-compatible API lets a tool that speaks OpenAI's chat completions format use ToRun's chat models, paid from your ToRun account. A coding agent such as opencode can use ToRun as its model provider, next to ToRun's MCP tools.

Address and sign-in

Base URL https://mcp.torun.ai/v1
Sign-in Authorization: Bearer <your developer key>

Use the same developer key as for the MCP server: see Developer keys. A key created before the OpenAI-compatible API was added answers 403 insufficient_scope. A key's permissions never change, so create a new key.

The API has two endpoints, GET /v1/models and POST /v1/chat/completions. Any other path under /v1 answers 404 not_found.

Models

GET /v1/models lists torun/auto first, then every text model your plan can use, by its model id. Each model says:

  • how much text it can read (context_length) and how long a reply it can write (max_completion_tokens),
  • whether it can call tools (supports_tools) and read images (supports_vision),
  • its price in Runs per million tokens (pricing: input and output).

torun/auto lets ToRun pick a model for each request: one that reads images when the request has an image, and one that calls tools when it sends tools.

Chat completions

POST /v1/chat/completions accepts:

  • messages, with the roles system, developer (treated as system), user, assistant and tool,
  • tools and tool_choice (auto, none, required or one named function): your tool's own tools come back to it as tool calls, and ToRun never runs them,
  • response_format with json_object. json_schema is accepted and answered as JSON, but the schema itself is not enforced,
  • temperature (0 to 2), top_p (0 to 1), max_completion_tokens or max_tokens, stop (up to 4 sequences), seed and reasoning_effort,
  • stream and stream_options.include_usage.

n above 1, logprobs, top_logprobs, audio and any output other than text are refused with 400 unsupported_parameter rather than ignored.

Images

Send an image inline, as data:image/...;base64,... in an image_url part, up to 20 MB per request. An image sent as a link is refused with 400 image_url_not_supported: ToRun does not fetch it. Images are checked for safety, as in the app.

Streaming

With "stream": true the reply arrives as server-sent events in the chat.completion.chunk shape:

  • The first chunk carries the role assistant, and tool calls stream with their index.
  • While there is nothing to send, a : keepalive comment line arrives every 15 seconds; SSE parsers skip it.
  • data: [DONE] ends a stream that succeeded.
  • With stream_options.include_usage, the last chunk has an empty choices and carries usage.
  • A failure after the stream started arrives as one data: {"error": ...} event, with no [DONE].

A call without streaming is stopped after 110 seconds with 504 timeout. Send long requests with "stream": true.

Usage

usage carries prompt_tokens, completion_tokens, total_tokens, prompt_tokens_details.cached_tokens and completion_tokens_details.reasoning_tokens, plus torun_credits: what the call cost, in Runs.

Use it in opencode

The opencode configuration on the Developers page adds ToRun as a model provider next to the MCP server:

{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "torun": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "ToRun",
      "options": { "baseURL": "https://mcp.torun.ai/v1", "apiKey": "{env:TORUN_API_KEY}" },
      "models": { "torun/auto": { "name": "ToRun Auto" } }
    }
  }
}

Any other tool that speaks the OpenAI chat API works the same way. The page's OpenAI API tab shows this call:

curl https://mcp.torun.ai/v1/chat/completions \
  -H "Authorization: Bearer $TORUN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "torun/auto", "messages": [{"role": "user", "content": "Hello"}]}'

How calls are paid

API calls cost the same Runs as the same use in the app. Only paid funds pay for them: first your paid plan's allowance, then your wallet if you allowed that on the key. The free allowance never pays for API calls. The key's monthly and daily limits apply, and replies are checked for safety like chat replies.

Limits

Each key can make 60 requests a minute to this API and run 4 completions at the same time. Above that, the API answers 429 rate_limit_exceeded with a Retry-After header.

Errors

Every error has the shape {"error": {"message": ..., "type": ..., "param": ..., "code": ...}}. The message is in the language the request's Accept-Language header asks for.

Status Code Meaning
400 invalid_json, missing_parameter, invalid_parameter, unsupported_parameter The request is malformed, or uses a parameter ToRun does not support.
400 image_url_not_supported An image was sent as a link; send it inline.
400 content_blocked The safety check blocked the content.
400 upstream_rejected The model's provider refused the request; the message says why.
401 invalid_api_key The key is missing, mistyped or revoked.
402 insufficient_credits, wallet_spend_not_allowed, spending_cap_reached The account or the key cannot pay for the call.
403 insufficient_scope The key was created before this API was added; create a new key.
403 model_not_available The model is not in your plan.
403 account_suspended, no_developer_access The account is suspended, or has no developer access.
404 model_not_found The model id is not one GET /v1/models lists.
404 not_found There is no such path under /v1.
429 rate_limit_exceeded Too many calls; wait for the time in Retry-After.
500 internal_error Something failed on ToRun's side.
502 upstream_error, empty_reply The model's provider failed, or sent an empty reply.
503 upstream_error, cap_unreadable, scan_unavailable A service the call needs is not available for a moment; try again.
504 timeout A call without streaming ran past 110 seconds.

A request that cannot be paid answers 402, not 429, so a client does not keep retrying it.