---
title: "Run a sandbox command"
method: POST
path: "/api/apps/{app_id}/sandbox-bridge/run_command"
---

# Run a sandbox command

`POST /api/apps/{app_id}/sandbox-bridge/run_command`

<Info>This API is in beta. Endpoints, fields, and behavior may still change, so avoid depending on it in production.</Info>

Runs a shell command inside the app's sandbox with bash and returns its output.

Every sandbox-bridge endpoint runs against the app's live sandbox, the same filesystem the Base44 builder edits, so a change here is visible in the builder immediately.

A command that exits non-zero still answers 200. Read `exit_code` to tell a failed command from a failed request, and expect `stderr` to carry output on success too, since many tools log there.

Each call starts in the app root unless you set `cwd`, and `cd` does not carry over between calls, so chain directory changes inside one command instead. The default timeout is 120000 ms and the maximum is 600000 ms; a command that outruns its timeout answers 504. Output is capped at 1 MB per stream, and `truncated` tells you when that happened.

This endpoint is limited to 30 requests per minute per app, its own budget rather than one shared with the other sandbox-bridge endpoints.

<Warning>A write is committed, not checkpointed. Only checkpoints appear in the builder's version history, and a Restore or Revert there rolls the app back to the last checkpoint and discards everything written after it. Call [Create a sandbox checkpoint](/api-reference/create-a-sandbox-checkpoint) when you finish a unit of work and before you stop.</Warning>

<Note>The sandbox bridge needs a Builder plan or higher on the app's workspace, and answers 402 below that. Workspace API keys are not authorized and are rejected with a 403, and it is unavailable for agent apps. A personal API key works as-is. An OAuth access token needs the `sandbox:write` scope.</Note>

<Tip>Every error response carries a stable `extra_data.code` alongside the human-readable `message`. Branch on the code rather than on the message text or the status.</Tip>

## Path parameters

- `app_id` string, required — ID of the app whose sandbox to operate on.

## Request body

- object
  - `branch_id` string, nullable — Optional Base44 branch ID. Omit to operate on main.
  - `command` string, required — Shell command to execute via bash inside the sandbox.
  - `cwd` string, nullable — Working dir relative to the app root. `cd` does not persist across calls — use this or chain commands.
  - `timeout_ms` integer — Timeout in milliseconds (default 120000, max 600000).

## Response `200`

The command ran. Read `exit_code` for its result.

- RunCommandResult — What a command left behind.
  - `stdout` string, required — Everything the command wrote to standard output.
  - `stderr` string, required — Everything the command wrote to standard error. Populated on success too, since many tools log there.
  - `exit_code` integer, required — The command's exit status. `0` means success. A non-zero status is still a 200 from this endpoint: the command ran and failed, which is not a request error.
  - `truncated` boolean, required — `true` when the output hit the 1 MB cap and was cut short. `stdout` and `stderr` are each capped, and either one hitting it sets this.
  - `duration_ms` integer, required — How long the command took, in milliseconds.

## Other responses

- `401` — Missing or invalid credentials.
- `402` — The app's workspace plan doesn't include the sandbox bridge.
- `403` — You don't have access to this app, the app is blocked, your OAuth token is missing the scope this endpoint needs, or you used a workspace API key.
- `404` — App not found.
- `409` — The app is on a branch that can't be written to: a protected main, or a branch that has been merged or closed.
- `422` — Validation Error
- `429` — Rate limit exceeded (30 requests per minute).
- `504` — The sandbox didn't answer in time. Retry the request.

## Changes

- **2026-09-15** `0e0a206b2f33` — 1 info
  - added the new optional request property `branch_id`
- **2026-09-07** `78b01bcee66e` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/base44/apis/base44-app-management-api/changes/api/apps/:app_id/sandbox-bridge/run_command/post.md)

---

[API](https://skmtc.dev/base44/apis/base44-app-management-api.md) · [All operations](https://skmtc.dev/base44/apis/base44-app-management-api/llms.txt) · [OpenAPI document](https://skmtc.dev/base44/apis/base44-app-management-api/revisions/cf164639a9bf?raw)
