Skip to main content
This guide shows you how to set up an OpenCode sandbox using Novita Sandbox. You’ll configure the environment, launch OpenCode, and run your coding agent in an isolated runtime.

What you’ll build

You will build a reusable sandbox template with OpenCode pre-installed, then start a sandbox from it and hand OpenCode a coding task. OpenCode runs entirely inside the sandbox: it writes files, runs shell commands, and executes the code it generates there, while a Novita-hosted model does the reasoning. Your machine only sends the task and reads back the result.

Prerequisites

  • Novita API key — create one in Key Management and export it as NOVITA_API_KEY. The same key authenticates both the sandbox and the model calls.
  • Novita Sandbox SDK — Python 3.10+ or Node.js 20+:
  • OpenCode version — this guide installs the opencode-ai npm package and was written against OpenCode 1.19. The configuration uses the provider / permission format that OpenCode 1.19 reads. The providers / permissions format in the newer published schema is not supported by 1.19 and is silently ignored or rejected.

Quickstart

1. Build an OpenCode sandbox template (one time)

A template bakes OpenCode into the sandbox image, so each new sandbox starts in seconds instead of reinstalling it. Build it once; reuse it for every run.

2. Run OpenCode in a sandbox

The script below writes an OpenCode config that points at the Novita LLM API, runs one non-interactive task with opencode run, and kills the sandbox.
opencode run "<prompt>" runs OpenCode without its terminal UI: it processes the prompt, prints the result, and exits, which makes it scriptable. OpenCode already allows most tool use by default; the explicit permission settings pin file edits (edit) and shell commands (bash) to allow, so a project-level config in a cloned repo can’t switch them to prompting and stall a headless run. That is safe here because everything happens inside a disposable sandbox.

How it works

OpenCode gets a full Linux environment inside the sandbox. You drive it with the SDK: files to move data in and out, commands to run OpenCode and anything else. The snippets below assume a sandbox created and configured as in the Quickstart.

Execute generated code

OpenCode writes code and runs it in the sandbox’s shell. Its stdout and stderr stream back to you through on_stdout / on_stderr, and the call returns the exit code.

Read and write files

Upload inputs before the run and read the agent’s output afterwards. For whole repositories, use sandbox.git.clone; for large files, see Upload and Download.

Run commands yourself

You can run any command next to the agent — install dependencies before it starts, or verify its work afterwards without trusting its own report.
A command that exits non-zero raises CommandExitException (Python) or CommandExitError (JavaScript). Catch it when a failing test run is an expected outcome.

Use Novita models

The Quickstart already routes OpenCode through Novita’s OpenAI-compatible API. To switch models, change one line — MODEL — to any model ID from the Novita model library, for example moonshotai/kimi-k2.7-code or zai-org/glm-5.3.
The model ID must match the Model Hub value exactly. Model usage is billed separately from sandbox runtime, at the model’s own per-token rate.

Production tips

  • Timeouts — timeout (seconds; timeoutMs in JavaScript) on sandbox.create is the sandbox’s maximum lifetime; extend it while the agent works with set_timeout. Pass timeout=0 to commands.run so a long agent turn isn’t cut off at the SDK’s default command timeout.
  • Pause and resume — for multi-step jobs, pause the sandbox between steps instead of killing it. Files, installed packages and OpenCode’s session state survive, and CPU and RAM billing stops while it is paused.
  • Concurrency — each sandbox is isolated, so you can run one OpenCode task per sandbox in parallel. Concurrent sandboxes are capped by your account tier (5 on Free, 100 on Paid); see Quota Limits.
  • Cost — sandboxes are billed per second while running. A 2 vCPU / 2 GiB sandbox costs about $0.0000260/s, so a 10-minute task is roughly $0.016 in sandbox time, plus model tokens. See Pricing.
  • Always clean up — kill sandboxes in a finally block (as above) so a crash in your script doesn’t leave one running until its timeout.

Troubleshooting

Your account balance can’t cover a new sandbox. Top up on the Billing page or claim the new-user credits described in Pricing, then retry.
The name passed to sandbox.create must match the name you built (opencode-agent above) in the same team as your API key. Run novita.template.list() to see your templates, or pass build.template_id directly.
Check that the model value is novita/<model ID>, that the same ID is a key under provider.novita.models, and that NOVITA_API_KEY was passed in envs — run echo $NOVITA_API_KEY in the sandbox to check it isn’t empty, because an unset variable becomes an empty key and shows up as Unauthorized. Run opencode debug config in the sandbox — it prints the resolved configuration and reports an invalid file — and opencode models to check that novita/<model ID> is listed.

Next steps

Sandbox SDK reference

Every option for creating and managing sandboxes.

Build templates

Add your own tools and dependencies to the OpenCode image.

Sandbox cookbook

Runnable Novita Sandbox examples on GitHub.

More agent integrations

Run Claude Code, Codex, or OpenClaw in a sandbox.
Last modified on November 11, 2026