Sandbox lifecycle
You do not need to actively manage the development environment state. Judt manages the sandbox lifecycle automatically:- Stopped: When you create an App with
POST /api/apps, itssandbox_statusis"stopped". - Starts on demand: Any request that reads or changes the sandbox starts it automatically. On the first start, Judt initializes the
/appworking directory from the App’s template. - Stops when idle: After 5 minutes with no API actions and no preview requests, Judt commits any uncommitted changes in
/app, saves a durable backup, and stops the sandbox. - Manual stop: If you want, you can stop a sandbox. Its not necessary.
POST /api/apps/{id}/stopwill commit changes, back up/app, and stop the sandbox immediately.
Which endpoints start the sandbox
Sandbox status values
Thesandbox_status field on the App object has one of these values:
Environment and limits
Inside the sandbox, your App lives in/app:
Reserved paths
All file paths in the API are relative to/app and cannot start with / or contain ... The Files API blocks direct access to runtime, dependency, and Git metadata paths (400 reserved_path):
.celld.dev.varsand.dev.vars.*.envand.env.*node_modules.gitdist.cache
.agents/skills/judt-apps directory is read-only. You can read its files, but a write returns 400 reserved_path.
To install packages in node_modules or build output into dist, run a shell command with POST /api/apps/{id}/commands. To set environment credentials, use Secrets.
Read and write files
List and search files
CallGET /api/apps/{id}/files to list files in /app, filter by glob, or search file contents:
When you pass
content or pattern, each matching file in results includes match_count and up to 20 matches ([{ "line": 12, "text": "..." }]).
Read a file
CallGET /api/apps/{id}/files/{path} to read a file:
- Text files: Returns JSON with
path,size,binary: false,content, andline_count. It also includeslineswhen you pass?lines=120,?lines=120-180, or?lines=120-. - Binary files: A JSON request returns metadata with
binary: trueand nocontent. SendAccept: application/octet-streamto download the raw bytes. - ETag caching: Every response includes an
ETagheader (the quoted SHA-256 hash of the file). SendIf-None-Match: "<etag>"on later reads to receive304 Not Modifiedwhen the file has not changed.
Write or delete a file
CallPUT /api/apps/{id}/files/{path} to create or replace a file (up to 1 MiB). Parent directories are created automatically.
- Text files: Send
Content-Type: application/jsonwith{"content": "..."}. - Binary files: Send
Content-Type: application/octet-streamwith the raw file bytes as the request body. - Concurrency control: Send
If-Match: "<etag>"to update the file only if its currentETagmatches, orIf-None-Match: *to create the file only if it does not exist yet. If the condition fails, the API returns412 precondition_failed.
DELETE /api/apps/{id}/files/{path} to delete a file and clean up any empty parent directories. You can also pass If-Match: "<etag>" on DELETE.
Run shell commands
CallPOST /api/apps/{id}/commands to run a shell command with Bash inside /app:
editor in /app. It does not get the App’s Secrets, and its output shows any Secret value as [secret:NAME].
timeout_seconds:1to120seconds (default60). If the command exceeds the timeout, the API terminates the process group and returnsstatus: "timed_out".status: If the command ends without a result, for example because the sandbox was lost, the API returnsstatus: "interrupted"andexit_codeisnull. The effects of the command are unknown, and it does not run again.exit_code: A non-zero exit code still returns HTTP200withstatus: "completed". Always checkexit_codein the response body.output: Combinedstdoutandstderr, up to64 KiB(truncated: trueif output exceeded 64 KiB).
Inspect Git status, commits, and restore
The/app directory is a Git repository.
Inspect uncommitted changes
CallGET /api/apps/{id}/git with a mode query parameter. The response has Git’s output in the output field:
Commit changes
CallPOST /api/apps/{id}/commits with a single-line message (1 to 240 characters) to stage all changes in /app, create a Git commit, and save a durable backup.
Restore an earlier commit
CallPOST /api/apps/{id}/restore with {"commit_id": "cmt_..."} to reset the sandbox working tree (/app) to that commit. Restoring a commit updates the sandbox only; it does not change what is running in production until you deploy.
Next steps
- Test your sandbox on the dev server in Previews and access and Test on the dev server.
- Publish a commit to production in Commits and deployments.