How to use Runtime's OpenAPI spec
Download https://api.withruntime.com/v1/openapi.json, an OpenAPI 3.1 document of every route, and feed it to a client generator.
Runtime's OpenAPI document is generated from the same route definitions the
server validates requests with, so it cannot drift from what the API
accepts. On 25 September 2026 it described 143 operations on 116 paths,
every product in one file, with no key needed to fetch it. Its
info.version is the API version you are talking to, 0.2.0 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 security scheme, 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 |
components.schemas.Error |
The one error shape: code, status, message, requestId, hint, 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 |
Ranges are in the schema itself. The create body, for instance, gives
timeoutSeconds from 60 to 3600 with a default of 1800, and
idlePauseSeconds 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, write 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: { funding: "trial" } });const { data: run } = await api.POST("/v1/sandboxes/{id}:exec", { params: { path: { id: sbx.id } }, body: { command: "python3 -c 'print(6 * 7)'" },});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 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 and 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 and names every wrong one in one
invalid_requestanswer, 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 answers the first result; with a different body it is refused with 422. - Treating a listed route as switched on. A route in the spec can answer
503
unavailablewhere a capability is off. Check the products page. - Calling 0.1.0 routes. They answer 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 September 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 September 2026.