Overview
Ortam is a hosted service that runs AI coding agents, such as Claude Code and Codex, in Sandboxes: Linux VMs whose disks Ortam saves while they work, so the next job starts with the repo, packages and Docker images already in place.
Your software factory, the system that turns tasks into changes with agents, decides which agent works in which Sandbox. Ortam runs the VMs, keeps their disks and records every command.
The four objects
- Sandbox
- A Linux VM with a disk that outlives it. Stopping it keeps its files, and the next start boots from them.
- Snapshot
- A saved version of a Sandbox’s files, for starting new Sandboxes or keeping a milestone.
- Execution
- One command run in a Sandbox, with its result and output kept after it ends. The docs call it a command.
- Connection
- A Claude or ChatGPT account your agents can use, kept and renewed outside the VM.
Your factory keeps its own users, repositories and agents. Your users need no Ortam account: your backend calls the API with an organization key.
Run your first command
Set the API address and your organization key once, then create a Sandbox. It starts out stopped.
export ORTAM_API="https://api.ortam.dev"
export ORTAM_API_KEY="ortam_…" # an organization key
curl -X POST "$ORTAM_API/v1/sandboxes" \
-H "Authorization: Bearer $ORTAM_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"name": "agent-checkout"}'Run a command. If the Sandbox is stopped, this starts it first.
curl -X POST "$ORTAM_API/v1/sandboxes/$SANDBOX_ID/executions" \
-H "Authorization: Bearer $ORTAM_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"argv": ["/bin/bash", "-lc", "npm test"], "timeout_seconds": 600}'Commands run in the background (Retries explains what a 202 response means). Read the command until it has a result before you stop the Sandbox, because Stop ends all work in it. Results stay readable after it stops, and so do its files.
curl "$ORTAM_API/v1/executions/$EXECUTION_ID" \
-H "Authorization: Bearer $ORTAM_API_KEY"
curl -X POST "$ORTAM_API/v1/sandboxes/$SANDBOX_ID/stop" \
-H "Authorization: Bearer $ORTAM_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"The same steps work from the CLI or the TypeScript SDK:
ortam login
ortam create my-sandbox
ortam run my-sandbox -- git clone https://github.com/you/app
ortam run my-sandbox -C app -- npm ci
ortam run my-sandbox -C app -- npm test
ortam attach my-sandbox
ortam stop my-sandbox
ortam snapshot my-sandboximport { Ortam } from "@ortam/sdk";
const ortam = new Ortam(); // reads ORTAM_API_KEY
const repo = "https://github.com/you/app";
const sandbox = await ortam.sandboxes.create({ name: "my-sandbox" });
await sandbox.run(["git", "clone", repo]).result();
await sandbox.run(["npm", "ci"], { cwd: "app" }).result();
const run = sandbox.run(["npm", "test"], { cwd: "app" });
for await (const line of run.output()) console.log(line);
// An exit code, or another outcome such as a timeout
const result = await run.result();