Runtime's OpenAPI document is generated from the same route definitions that
the server uses to validate requests. So it cannot drift from what the API
accepts. On 25 October 2026, it described 190 operations on 149 paths. Every
product is in one file. No key is needed to fetch it. Its info.version is the
API version you are using, 0.2.0 on that day
(API reference).
Fetch it
Terminalcurl -sS https://api.withruntime.com/v1/openapi.json -o runtime-openapi.jsonjq -r '.info.version' runtime-openapi.json # 0.2.0jq -r '.paths | keys[]' runtime-openapi.json | head # /v1/me, /v1/usage, /v1/sandboxes ...The document needs no authentication. The API it describes does: the
document's default security is the bearer scheme, or oauth2 for the same
key got by OAuth sign-in, so send Authorization: Bearer <key>.
What is in it
| Part | What you find |
|---|---|
openapi |
3.1.0 |
info.version |
The API version, 0.2.0 |
servers |
https://api.withruntime.com |
components.securitySchemes |
bearer: HTTP bearer auth; oauth2: the same key, got by OAuth 2.1 sign-in |
components.schemas.Error |
The one error shape: code, status, message, requestId, hint, retryable, retryAfterMs, details |
paths |
Every route, with operationId such as sandboxes.create or audit.list |
Operation tags |
One per product: sandboxes, files, commands, images, volumes and the rest |
| Parameters | Idempotency-Key on writes, with the pattern it must match |
| Request schemas | Every field with its default, range and a description, unknown fields refused |
x-mcp-tools |
The MCP server's tools, each with its name, description and input schema |
The schema itself gives the ranges. For example, the create body sets
timeoutSeconds up to 86,400 seconds (24 hours). Its default is 0, which means
no time limit. idlePauseSeconds ranges from 0 to 86,400.
Generate TypeScript types
openapi-typescript reads OpenAPI 3.0
and 3.1 and writes a .d.ts file:
Terminalnpx openapi-typescript https://api.withruntime.com/v1/openapi.json -o ./runtime-api.d.tsnpm install openapi-fetchThen openapi-fetch makes typed calls.
In TypeScript, call createClient<paths>(...), with paths imported from the
generated file. Plain JavaScript looks like this:
JavaScriptimport createClient from "openapi-fetch";const api = createClient({ baseUrl: "https://api.withruntime.com", headers: { Authorization: `Bearer ${process.env.RUNTIME_API_KEY}` },});const { data: sbx } = await api.POST("/v1/sandboxes", { body: {} });const { data: run } = await api.POST("/v1/sandboxes/{id}:exec", { params: { path: { id: sbx.id } }, body: { command: "python3 -c 'print(sum([125, 250, 375]))'" },});console.log(run.stdout);await api.POST("/v1/sandboxes/{id}:stop", { params: { path: { id: sbx.id } } });Read it from a script
The spec is plain JSON, so any language can list what the API offers. This script prints each product and its operations:
Pythonimport jsonimport urllib.requestfrom collections import defaultdictwith urllib.request.urlopen("https://api.withruntime.com/v1/openapi.json") as response: spec = json.load(response)by_tag = defaultdict(list)for path, methods in spec["paths"].items(): for method, op in methods.items(): for tag in op.get("tags", []): by_tag[tag].append(f"{method.upper()} {path} ({op['operationId']})")print(spec["info"]["version"])for tag in sorted(by_tag): print(tag, len(by_tag[tag]))Prefer the SDKs where there is one
For JavaScript, TypeScript and Python, the official SDKs are thin layers over this same API. They add what a generated client lacks: an idempotency key on every write and retries with it, a create that waits for capacity, streaming, resumable uploads and typed errors. A generated client is the right tool for Go, Rust, Java, a language with no SDK, or an API gateway that imports OpenAPI.
Mistakes and how Runtime handles them
- Generating once and never again. New products add paths. Regenerate on
each upgrade and compare
info.version. - Adding fields the schema does not list. The server refuses unknown
fields. It names every wrong field in one
invalid_requestresponse. So a typo fails loudly instead of being ignored. - Retrying writes from a generated client with no key. Send your own
Idempotency-Keyheader on writes. The same key with the same body returns the first result. With a different body, the request is refused with 422. - Treating a listed route as switched on. A route in the spec can return
501
unavailablewhere a capability is off. Check the products page. - Calling 0.1.0 routes. They return 410
upgrade_requiredwithdetails.replacement. See migration.
Related
- How to call the REST API with curl
- Runtime Cloud MCP, whose tools the spec also lists
- Model Context Protocol
- JavaScript SDK and Python SDK
Sources
Checked 25 October 2026.
- Runtime OpenAPI document, fetched and counted that day
- openapi-typescript introduction
- openapi-fetch and its API
Facts on this page were checked on 25 October 2026.