Start

Get started

upstream gives every AI agent its own Firecracker microVM: a real Linux machine with its own kernel, network and disk. You create sandboxes, run commands and move files through one API, and fork a running sandbox into as many copies as you need.

Private beta. API keys are issued to invited teams. Everything on this page works the same once you have one.

Install#

The Python SDK is upstm-py. It supports Python 3.10 and later, and imports as upstream.

bash
$ pip install upstm-py

Authenticate#

API keys start with ak_. Keep yours in an environment variable and pass it to the client:

bash
$ export UPSTREAM_API_KEY=ak_…
python
import os
from upstream import Upstream

client = Upstream(api_key=os.environ["UPSTREAM_API_KEY"])

The key travels as a bearer token, so calling the API directly works the same way.

Run your first sandbox#

hello.py
with client.sandbox(template="python") as sb:
    result = sb.exec(["python3", "-c", "import platform; print(platform.system())"])
    print(result.stdout)      # Linux
    print(result.exit_code)   # 0

client.sandbox() starts a microVM from the python template and returns once it is ready. Leaving the with block destroys it.

Read and write files#

python
with client.sandbox(template="python") as sb:
    sb.write_file("/workspace/main.py", "print(sum(range(10)))")
    print(sb.exec(["python3", "/workspace/main.py"]).stdout)   # 45
    print(sb.list_files("/workspace"))

Commands run in /workspace by default. For large files, use pre-signed URLs instead of sending contents through the API.

Fork it#

A fork is a copy of a running sandbox. It resumes with its parent's memory, files and processes, and shares the parent's pages until it writes to them. Prepare a machine once, then branch from it as often as you like.

fork.py
with client.sandbox(template="python") as base:
    base.write_file("/workspace/state.txt", "prepared")

    child = base.fork()
    child.write_file("/workspace/state.txt", "changed in the fork")

    print(base.read_file_text("/workspace/state.txt"))    # prepared
    print(child.read_file_text("/workspace/state.txt"))   # changed in the fork
    child.destroy()

The forking guide covers parallel attempts, debugging from a failure, snapshots and pausing.

Next steps#