# Sandbox quickstart

> Start a sandbox, run code in it and stop it

This starts a machine, writes a Python file to it, runs it and stops the machine. It costs about a cent.

  
#### Create a sandbox

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

    const zavu = new Zavudev({
      apiKey: process.env["ZAVUDEV_API_KEY"], // This is the default and can be omitted
    });

    const { sandbox } = await zavu.sandboxes.create({
      size: "default",
      timeoutSeconds: 1800,
      idempotencyKey: "build-1042",
    });
    console.log(sandbox.id, sandbox.status); // "starting"
    ```

    ```bash
    curl -X POST https://api.zavu.dev/v1/sandboxes \
      -H "Authorization: Bearer $ZAVUDEV_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"size": "default", "timeoutSeconds": 1800, "idempotencyKey": "build-1042"}'
    ```
    

    The answer is `202` with the sandbox in `starting`. You do not need to wait for `running`: commands and file calls made while it starts wait for it.

    Retrying with the same `idempotencyKey` answers `409` with the sandbox the first request created, instead of starting and charging a second one.
  
  
#### Write a file and run it

    
    ```typescript
    await zavu.sandboxes.files.write(sandbox.id, {
      path: "main.py",
      content: "print(2 + 2)\n",
    });

    const { result } = await zavu.sandboxes.commands.run(sandbox.id, {
      command: "python3 main.py",
    });
    console.log(result?.exitCode, result?.stdout); // 0 "4\n"
    ```

    ```bash
    curl -X PUT https://api.zavu.dev/v1/sandboxes/$SANDBOX_ID/files \
      -H "Authorization: Bearer $ZAVUDEV_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"path": "main.py", "content": "print(2 + 2)\n"}'

    curl -X POST https://api.zavu.dev/v1/sandboxes/$SANDBOX_ID/commands \
      -H "Authorization: Bearer $ZAVUDEV_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"command": "python3 main.py"}'
    ```
    

    ```json
    { "result": { "exitCode": 0, "stdout": "4\n", "stderr": "", "stdoutTruncated": false, "stderrTruncated": false, "timedOut": false, "startedAt": "…", "finishedAt": "…" } }
    ```
  
  
#### Stop it

    
    ```typescript
    await zavu.sandboxes.stop(sandbox.id);
    ```

    ```bash
    curl -X POST https://api.zavu.dev/v1/sandboxes/$SANDBOX_ID/stop \
      -H "Authorization: Bearer $ZAVUDEV_API_KEY"
    ```
    

    Billing ends here. The disk is kept 14 days: resume it with `zavu.sandboxes.resume(id)`, or delete it for good with `zavu.sandboxes.delete(id)`.
  

## Next

- [Commands and files](https://www.zavu.dev/docs/guides/sandboxes/commands-and-files): long-running commands and binary files.
- [Ports, SSH and the desktop](https://www.zavu.dev/docs/guides/sandboxes/access): reach what runs inside.
- [Snapshots and environments](https://www.zavu.dev/docs/guides/sandboxes/snapshots-and-environments): start the next sandbox ready to work.
