[iris]
Reference

API Reference

SDK reference for the Iris sandbox API

How authentication works

Iris has two API surfaces:

  • Gateway (api.iris.dev) — sandbox lifecycle: create, fork, list, suspend. Authenticated with your API key.
  • Data plane (sandbox.domain) — exec, files, checkpoints, services, store. Authenticated with a short-lived JWT issued by the gateway, scoped to one sandbox.

The SDK handles both automatically. You only ever set IRIS_API_KEY — token refresh for data plane calls is wired into the transport layer.


Sandbox management

Create

import { Sandbox } from '@iris/sdk'

const sandbox = await Sandbox.create()
const named   = await Sandbox.create({ name: 'my-agent' })

console.log(sandbox.id)     // "sb_abc123"
from iris import IrisClient

client = IrisClient()
sandbox = client.sandboxes.create()
named   = client.sandboxes.create(name="my-agent")

print(sandbox.id)     # "sb_abc123"

List

import { IrisClient } from '@iris/sdk'

const client    = new IrisClient()
const sandboxes = await client.sandboxes.list()

for (const sb of sandboxes) {
  console.log(sb.id, sb.state)
}
from iris import IrisClient

client    = IrisClient()
sandboxes = client.sandboxes.list()

for sb in sandboxes:
    print(sb.id, sb.state)

Fork

Creates a copy-on-write clone. The source keeps running unchanged.

const branch = await sandbox.fork()

await branch.exec.run('python3 risky.py')
await branch.delete()

// original sandbox untouched
branch = sandbox.fork()

branch.exec.run(["python3", "risky.py"])
branch.delete()

# original sandbox untouched

Suspend and resume

Snapshots the sandbox and stops the VM. Compute billing pauses until resumed.

await client.sandboxes.suspend(sandbox.id)
// ... later
await client.sandboxes.resume(sandbox.id)
client.sandboxes.suspend(sandbox.id)
# ... later
client.sandboxes.resume(sandbox.id)

Delete

await sandbox.delete()
// or via client:
await client.sandboxes.delete(sandbox.id)
sandbox.delete()
# or via client:
client.sandboxes.delete(sandbox.id)

Exec

Run shell commands inside the sandbox.

const result = await sandbox.exec.run('echo hello')
console.log(result.stdout)    // "hello\n"
console.log(result.ok)        // true
console.log(result.exit_code) // 0

// Full options
const res = await sandbox.exec.run({
  cmd:        ['python3', 'train.py'],
  dir:        '/app',
  env:        { DEBUG: 'true' },
  timeout_ms: 60_000,
  stdin:      '',
})
result = sandbox.exec.run(["echo", "hello"])
print(result.stdout)    # "hello\n"
print(result.ok)        # True
print(result.exit_code) # 0

# Full options
res = sandbox.exec.run(
    ["python3", "train.py"],
    dir="/app",
    env={"DEBUG": "true"},
    timeout_ms=60_000,
    stdin="",
)

Files

Read and write the sandbox filesystem.

await sandbox.files.write('/app/config.json', JSON.stringify({ debug: true }))

const text  = await sandbox.files.readText('/app/output.txt')
const bytes = await sandbox.files.read('/app/model.bin')

const listing = await sandbox.files.list('/app')
const { exists } = await sandbox.files.exists('/app/data.csv')

await sandbox.files.move({ source: '/tmp/out.json', destination: '/app/out.json' })
await sandbox.files.remove('/tmp/scratch', { recursive: true })
await sandbox.files.mkdir({ path: '/app/logs', parents: true })
import json

sandbox.files.write("/app/config.json", json.dumps({"debug": True}))

text  = sandbox.files.read_text("/app/output.txt")
data  = sandbox.files.read("/app/model.bin")  # bytes

listing = sandbox.files.list("/app")
result  = sandbox.files.exists("/app/data.csv")

sandbox.files.move("/tmp/out.json", "/app/out.json")
sandbox.files.remove("/tmp/scratch", recursive=True)
sandbox.files.mkdir("/app/logs", parents=True)

See Files for the full operation reference.


Checkpoints

Snapshot and restore the sandbox filesystem.

const cp = await sandbox.checkpoint.create({ name: 'after-setup' })
console.log(cp.checkpoint_id)

const { checkpoints } = await sandbox.checkpoint.list()

const restored = await sandbox.checkpoint.restore(cp.checkpoint_id)
console.log(`Restored in ${restored.restore_duration_ms}ms`)

await sandbox.checkpoint.delete(cp.checkpoint_id)
cp = sandbox.checkpoint.create(name="after-setup")
print(cp.checkpoint_id)

result = sandbox.checkpoint.list()
checkpoints = result.checkpoints

restored = sandbox.checkpoint.restore(cp.checkpoint_id)
print(f"Restored in {restored.restore_duration_ms}ms")

sandbox.checkpoint.delete(cp.checkpoint_id)

See Checkpoints and Checkpoint Restore.


Services

Long-running background processes (databases, servers, queues).

await sandbox.services.upsert('redis', {
  cmd:         'redis-server',
  args:        ['--port', '6379'],
  health_port: 6379,
})

await sandbox.services.start('redis')

const svc = await sandbox.services.get('redis')
console.log(svc.status) // "running"

await sandbox.services.stop('redis')
await sandbox.services.delete('redis')
sandbox.services.upsert(
    "redis",
    "redis-server",
    args=["--port", "6379"],
    health_port=6379,
)

sandbox.services.start("redis")

svc = sandbox.services.get("redis")
print(svc.status)  # "running"

sandbox.services.stop("redis")
sandbox.services.remove("redis")

See Services.


Store

Per-sandbox key-value store for agent state.

await sandbox.store.set('progress', {
  value:       { step: 3, score: 0.91 },
  ttl_seconds: 3600,
})

const entry = await sandbox.store.get('progress')
const { keys } = await sandbox.store.list()

await sandbox.store.delete('temp')

await sandbox.store.batch([
  { op: 'set',    key: 'result', value: { score: 0.95 } },
  { op: 'delete', key: 'temp' },
])
sandbox.store.set("progress", {"step": 3, "score": 0.91}, ttl_seconds=3600)

entry = sandbox.store.get("progress")
keys  = sandbox.store.list().keys

sandbox.store.delete("temp")

sandbox.store.batch([
    {"op": "set",    "key": "result", "value": {"score": 0.95}},
    {"op": "delete", "key": "temp"},
])

See Store.


HTTP integration

If you're not using an SDK, the two base URLs and auth headers are:

SurfaceBase URLAuth header
Gatewayhttps://api.iris.devAuthorization: Bearer iris_sk_...
Data planehttps://{sandbox.domain}Authorization: Bearer <data_plane_token>

Gateway requests are POST to /iris.public.v1.SandboxService/{MethodName} with a JSON body. Data plane endpoints are REST — see the concept pages for per-operation HTTP specs.

On this page