SDKs
Create computers, run commands and fork them from JavaScript or Python.
The workpaper package does from code what the CLI does from a terminal. There's one for JavaScript (Node 18+, Bun, Deno) and one for Python (3.9+), with the same calls, and neither has dependencies.
npm install workpaper
pip install workpaper
1. Make an API key
Sign in with the CLI, then make a key. It's shown once; keep it as WORKPAPER_API_KEY.
workpaper auth login
workpaper keys create my-app
A key acts as you, so keep it out of code and repositories. Revoke it any time with workpaper keys rm <id>.
2. Start a computer and use it
import { Workpaper } from "workpaper";
const wp = new Workpaper(); // reads WORKPAPER_API_KEY
const c = await wp.run("my-agent"); // create it, or wake it if it exists
const { exitCode, stdout, stderr } = await c.exec("npm test", { cwd: "/home/user/app" });
await c.write("/home/user/notes.txt", "hello");
const text = await c.readText("/home/user/notes.txt");
exec runs under bash and returns once the command ends. A non-zero exit code is a result, not an error. Pass onStdout and onStderr to stream output as it comes, env for variables, and timeoutMs to stop a command that runs too long.
From Python
from workpaper import Workpaper
wp = Workpaper() # reads WORKPAPER_API_KEY
c = wp.run("my-agent")
r = c.exec("pytest -q", cwd="/home/user/app", on_stdout=print)
print(r.exit_code)
c.write("/home/user/notes.txt", "hello")
c.stop(); c.start()
copy = c.fork("try-b")
Python names use snake case (read_text, exit_code, memory_mb), and timeout on exec is in seconds. Everything else matches the reference below.
3. Stop, start and fork
await c.stop(); // disk and memory saved, billing stops
await c.start(); // running programs carry on from the same moment
const copy = await c.fork("try-b"); // files, memory and running programs
await copy.delete();
Reference
| Call | What it does |
|---|---|
new Workpaper({ apiKey?, waitSeconds?, onWait? }) | When every computer is busy, calls that start one wait in line (up to waitSeconds, default 900) and call onWait(position). Nothing is charged while waiting. |
wp.run(name, { size?, timeout? }) | Create or wake. size is "small" or "large"; timeout is seconds per start, at most 3600. |
wp.create(name) · wp.find(name) · wp.list() | Make a new computer, look one up by name (or null), list them all. |
c.exec(cmd, opts) | Run a command: { exitCode, stdout, stderr }. |
c.read(path) · c.readText(path) · c.write(path, data) | Files on the computer. |
c.stop() · c.start() · c.fork(name) · c.delete() | Same as the CLI commands. |
Errors are WorkpaperError, with status and, when the service is full, reason: "at_capacity". The same limits apply as with the CLI.