# Run a command

> Run a shell command in the sandbox, in /home/user unless cwd says otherwise.

`POST https://api.zavu.dev/v1/sandboxes/{sandboxId}/commands`

Run a shell command in the sandbox, in `/home/user` unless `cwd` says otherwise.

Synchronous by default: the response carries the exit code and output, waiting up to `timeoutSeconds` (max 120). Set `background` for anything longer: the response is `202` with a command `id` to poll.

A command is never retried: if the call fails mid-way, the command may still be running. Not available with test-mode keys.

## Parameters

- `sandboxId` (path, string, required): Sandbox ID.

## Body

- `command` (string, required): Run with a shell, so pipes and `&&` work.
- `cwd` (string): Working directory, relative to `/home/user`.
- `timeoutSeconds` (integer): For a synchronous command: how long to wait before it is killed and `timedOut` is true. Use `background` for anything longer.
- `background` (boolean): Start it and return a command `id` at once. Read its status and output with `GET /v1/sandboxes/{sandboxId}/commands/{commandId}`.

## Responses

### 200

The command finished, or was killed at its timeout. `result` is set.

- `result` (object)
  - `exitCode` (integer, required, nullable): Null when the command was killed.
  - `stdout` (string, required)
  - `stderr` (string, required)
  - `stdoutTruncated` (boolean, required)
  - `stderrTruncated` (boolean, required)
  - `timedOut` (boolean, required)
  - `startedAt` (string<date-time>, nullable)
  - `finishedAt` (string<date-time>, nullable)
- `command` (object)
  - `id` (string, required): Pass it to `GET /v1/sandboxes/{sandboxId}/commands/{commandId}`.
  - `status` (string, required) One of: `running`.

### 202

Started in the background. `command` is set.

- `result` (object)
  - `exitCode` (integer, required, nullable): Null when the command was killed.
  - `stdout` (string, required)
  - `stderr` (string, required)
  - `stdoutTruncated` (boolean, required)
  - `stderrTruncated` (boolean, required)
  - `timedOut` (boolean, required)
  - `startedAt` (string<date-time>, nullable)
  - `finishedAt` (string<date-time>, nullable)
- `command` (object)
  - `id` (string, required): Pass it to `GET /v1/sandboxes/{sandboxId}/commands/{commandId}`.
  - `status` (string, required) One of: `running`.

### 400

Invalid body, or a test-mode key.

- `code` (string, required)
- `message` (string, required)
- `details` (object)

### 401

Unauthorized.

- `code` (string, required)
- `message` (string, required)
- `details` (object)

### 404

Sandbox not found, or it belongs to another project.

- `code` (string, required)
- `message` (string, required)
- `details` (object)

### 409

`sandbox_not_running`: the sandbox is stopped, stopping, failed or deleted; resume it first. `sandbox_not_ready`: it is still starting and did not become ready in time; retry.

- `code` (string, required)
- `message` (string, required)
- `details` (object)

### 503

`sandbox_unavailable`: no machine capacity right now. Nothing was charged for machine time; retry shortly.

- `code` (string, required)
- `message` (string, required)
- `details` (object)

## Example

```bash
curl -X POST "https://api.zavu.dev/v1/sandboxes/sandbox_abc123/commands" \
  -H "Authorization: Bearer $ZAVUDEV_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "command": "pip install requests && python3 main.py",
  "cwd": "app",
  "timeoutSeconds": 90
}'
```

```typescript
import Zavudev from "@zavudev/sdk";

const zavu = new Zavudev({ apiKey: process.env.ZAVUDEV_API_KEY });

const result = await zavu.sandboxes.commands.run("sandbox_abc123", {
  command: "pip install requests && python3 main.py",
  cwd: "app",
  timeoutSeconds: 90,
});

console.log(result);
```
