Skip to main content
Every box has its own isolated filesystem. Upload, write, read, list, and download files inside the box.

API

Upload files

Push local files into the box. Each entry maps a local path to a destination inside the box workspace.
await box.files.upload([
  { path: "./data/report.csv", destination: "/work/report.csv" },
  { path: "./config.json", destination: "/work/config.json" },
])
box.files.upload([
    {"path": "./data/report.csv", "destination": "/work/report.csv"},
    {"path": "./config.json", "destination": "/work/config.json"},
])
You can upload multiple files in a single call. All uploads run in parallel.

Write files

Create or overwrite a file directly from a string. Useful when you want to inject configuration, scripts, or generated content without a local file.
await box.files.write({
  path: "/work/script.js",
  content: `console.log("hello from box")`,
})
box.files.write(
    path="/work/script.js",
    content='console.log("hello from box")',
)

Read files

Read the contents of a file as a string.
const content = await box.files.read("/work/output.json")
console.log(JSON.parse(content))
import json

content = box.files.read("/work/output.json")
print(json.loads(content))

List files

List the entries in a directory. Each entry includes the path, size, type, and last modified timestamp.
const files = await box.files.list("/work")

console.log(files)
// [
//   { path: "/work/report.csv", size: 1024, type: "file", modifiedAt: "2026-02-23T..." },
//   { path: "/work/output", size: 4096, type: "directory", modifiedAt: "2026-02-23T..." },
// ]
files = box.files.list("/work")

print(files)
# [
#   FileEntry(name="report.csv", path="/work/report.csv", size=1024, is_dir=False, mod_time="2026-02-23T..."),
#   FileEntry(name="output", path="/work/output", size=4096, is_dir=True, mod_time="2026-02-23T..."),
# ]

Download files

Pull files from the box back to your local machine. Call with no arguments to download the entire workspace, or pass a folder to download a specific file or directory.
await box.files.download()
await box.files.download({ folder: "/work/output" })
box.files.download()
box.files.download(folder="/work/output")

Examples

Feed data to an agent

Upload input files, run the agent, then read back the structured result.
import { Agent, Box } from "@upstash/box"
import { z } from "zod"

const box = await Box.create({
  runtime: "node",
  agent: { harness: Agent.ClaudeCode, model: "anthropic/claude-opus-4-6", apiKey: process.env.ANTHROPIC_API_KEY },
})

await box.files.upload([
  { path: "./resumes/candidate.pdf", destination: "/work/resume.pdf" },
])

const run = await box.agent.run({
  prompt: "Read /work/resume.pdf. Extract the candidate's name, email, and skills.",
  responseSchema: z.object({
    name: z.string(),
    email: z.string(),
    skills: z.array(z.string()),
  }),
})

console.log(run.result)
// { name: "Jane Doe", email: "jane@example.com", skills: ["TypeScript", "PostgreSQL"] }

await box.delete()
import os
from pydantic import BaseModel
from upstash_box import Box, Agent

class Candidate(BaseModel):
    name: str
    email: str
    skills: list[str]

box = Box.create(
    runtime="node",
    agent={"harness": Agent.CLAUDE_CODE, "model": "anthropic/claude-opus-4-6", "api_key": os.environ["ANTHROPIC_API_KEY"]},
)

box.files.upload([
    {"path": "./resumes/candidate.pdf", "destination": "/work/resume.pdf"},
])

run = box.agent.run(
    prompt="Read /work/resume.pdf. Extract the candidate's name, email, and skills.",
    response_schema=Candidate,
)

print(run.result)
# Candidate(name="Jane Doe", email="jane@example.com", skills=["TypeScript", "PostgreSQL"])

box.delete()

Inject config before a run

Write environment-specific configuration into the box, then let the agent use it.
import { Agent, Box } from "@upstash/box"

const box = await Box.create({
  runtime: "node",
  agent: { harness: Agent.ClaudeCode, model: "anthropic/claude-opus-4-6", apiKey: process.env.ANTHROPIC_API_KEY },
  git: { token: process.env.GITHUB_TOKEN },
})

await box.git.clone({ repo: "github.com/your-org/your-api" })

await box.files.write({
  path: "/work/your-api/.env.test",
  content: `DATABASE_URL=postgres://localhost:5432/test\nREDIS_URL=redis://localhost:6379`,
})

await box.agent.run({
  prompt: "Run the integration test suite using the config in .env.test",
})
import os
from upstash_box import Box, Agent

box = Box.create(
    runtime="node",
    agent={"harness": Agent.CLAUDE_CODE, "model": "anthropic/claude-opus-4-6", "api_key": os.environ["ANTHROPIC_API_KEY"]},
    git={"token": os.environ["GITHUB_TOKEN"]},
)

box.git.clone(repo="github.com/your-org/your-api")

box.files.write(
    path="/work/your-api/.env.test",
    content="DATABASE_URL=postgres://localhost:5432/test\nREDIS_URL=redis://localhost:6379",
)

box.agent.run(prompt="Run the integration test suite using the config in .env.test")

Collect outputs from parallel boxes

Fan out work across multiple boxes, then download each result locally.
import { Agent, Box } from "@upstash/box"

const prompts = [
  "Analyze /work/data.csv and write a summary to /work/summary.md",
  "Generate charts from /work/data.csv and save PNGs to /work/charts/",
  "Find anomalies in /work/data.csv and write a report to /work/anomalies.md",
]

const results = await Promise.all(
  prompts.map(async (prompt) => {
    const box = await Box.create({
      runtime: "node",
      agent: { harness: Agent.ClaudeCode, model: "anthropic/claude-opus-4-6", apiKey: process.env.ANTHROPIC_API_KEY },
    })

    await box.files.upload([
      { path: "./data.csv", destination: "/work/data.csv" },
    ])

    await box.agent.run({ prompt })
    await box.files.download({ folder: "/work" })
    await box.delete()
  })
)
import asyncio
import os
from upstash_box import AsyncBox, Agent

prompts = [
    "Analyze /work/data.csv and write a summary to /work/summary.md",
    "Generate charts from /work/data.csv and save PNGs to /work/charts/",
    "Find anomalies in /work/data.csv and write a report to /work/anomalies.md",
]

async def run_one(prompt: str) -> None:
    box = await AsyncBox.create(
        runtime="node",
        agent={"harness": Agent.CLAUDE_CODE, "model": "anthropic/claude-opus-4-6", "api_key": os.environ["ANTHROPIC_API_KEY"]},
    )
    await box.files.upload([{"path": "./data.csv", "destination": "/work/data.csv"}])
    await box.agent.run(prompt=prompt)
    await box.files.download(folder="/work")
    await box.delete()

async def main() -> None:
    # fan out across boxes in parallel
    await asyncio.gather(*(run_one(p) for p in prompts))

asyncio.run(main())