> ## Documentation Index
> Fetch the complete documentation index at: https://docs.novita.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Create Sandbox

## Create Sandbox

The simplest way to create a sandbox is to call `novita.sandbox.create()` without any arguments.

<CodeGroup>
  ```js JavaScript & TypeScript icon="js" theme={"system"}
  import 'dotenv/config'
  import { Novita } from 'novita-sandbox'

  const novita = new Novita()
  const sandbox = await novita.sandbox.create()

  await sandbox.kill()
  ```

  ```python Python icon="python" theme={"system"}
  from dotenv import load_dotenv
  from novita_sandbox import Novita

  load_dotenv()

  novita = Novita()
  sandbox = novita.sandbox.create()

  sandbox.kill()
  ```

  ```bash CLI icon="terminal" theme={"system"}
  # Create a sandbox from the base template and connect a terminal (alias: sandbox cr)
  novita-sandbox-cli sandbox create base

  # Create without connecting a terminal (detached), returns the sandbox ID
  novita-sandbox-cli sandbox create base -d
  ```
</CodeGroup>

## From Template

You can create a sandbox from a template by passing the template name or ID.

```python Python icon="python" theme={"system"}
from dotenv import load_dotenv
from novita_sandbox import Novita

load_dotenv()

novita = Novita()

# Create a sandbox from a template name or template ID.
sandbox = novita.sandbox.create(
    "my-python-app",   # template name or ID
    timeout=300,        # seconds, optional
    metadata={"env": "demo"},
    envs={"KEY": "value"},
)

print("Sandbox ID:", sandbox.sandbox_id)

# Use it.
result = sandbox.commands.run("python3 --version")
print(result.stdout)

sandbox.kill()
```

Use a context manager for automatic cleanup:

<CodeGroup>
  ```python Python icon="python" theme={"system"}
  from novita_sandbox import Novita

  novita = Novita()

  with novita.sandbox.create("my-python-app") as sandbox:
      print(sandbox.commands.run("echo hello").stdout)
  # Automatically killed when exiting the with block.
  ```

  ```js JavaScript & TypeScript icon="js" theme={"system"}
  import 'dotenv/config'
  import { Novita } from 'novita-sandbox'

  const novita = new Novita()

  // Create a sandbox from a template name or template ID.
  const sandbox = await novita.sandbox.create('my-python-app', {
    timeoutMs: 300_000, // milliseconds, optional
    metadata: { env: 'demo' },
    envs: { KEY: 'value' },
  })

  console.log('Sandbox ID:', sandbox.sandboxId)

  // Use it.
  const result = await sandbox.commands.run('python3 --version')
  console.log(result.stdout)

  await sandbox.kill()
  ```

  ```bash CLI icon="terminal" theme={"system"}
  # Create a sandbox from a specific template (by name or template ID)
  novita-sandbox-cli sandbox create <template>

  # Detached (no terminal), prints the new sandbox ID
  novita-sandbox-cli sandbox create <template> -d
  ```
</CodeGroup>

## Environment Variables

You can set environment variables when creating a sandbox, and override or append them on a single command.

<CodeGroup>
  ```python Python icon="python" theme={"system"}
  from dotenv import load_dotenv
  from novita_sandbox import Novita

  load_dotenv()

  novita = Novita()

  # Set environment variables when creating the sandbox.
  sandbox = novita.sandbox.create(
      "my-python-app",
      envs={
          "API_KEY": "secret-123",
          "LOG_LEVEL": "debug",
          "PORT": "8000",
      },
  )

  # Verify.
  result = sandbox.commands.run("echo $API_KEY")
  print(result.stdout)   # secret-123

  # You can also override/append envs on a single command.
  result = sandbox.commands.run(
      "echo $LOG_LEVEL",
      envs={"LOG_LEVEL": "info"},
  )
  print(result.stdout)   # info

  sandbox.kill()
  ```

  ```js JavaScript & TypeScript icon="js" theme={"system"}
  import 'dotenv/config'
  import { Novita } from 'novita-sandbox'

  const novita = new Novita()

  // Set environment variables when creating the sandbox.
  const sandbox = await novita.sandbox.create('my-python-app', {
    envs: {
      API_KEY: 'secret-123',
      LOG_LEVEL: 'debug',
      PORT: '8000',
    },
  })

  // Verify.
  let result = await sandbox.commands.run('echo $API_KEY')
  console.log(result.stdout) // secret-123

  // You can also override/append envs on a single command.
  result = await sandbox.commands.run('echo $LOG_LEVEL', {
    envs: { LOG_LEVEL: 'info' },
  })
  console.log(result.stdout) // info

  await sandbox.kill()
  ```
</CodeGroup>

## Metadata

Sandbox metadata lets you attach custom key-value information to a sandbox.

Common uses include:

* Connecting a sandbox to a user session.
* Saving custom user-related data for a sandbox, such as API keys.
* Linking a sandbox to a user ID so it can be reconnected later.

Metadata is provided when the sandbox is created. Later, it can be read when listing active sandboxes with `novita.sandbox.list()`. Sandboxes can also be filtered using metadata when listing.

<CodeGroup>
  ```js JavaScript & TypeScript icon="js" theme={"system"}
  import { Novita, SandboxState } from 'novita-sandbox'

  const novita = new Novita()

  // Start a sandbox and attach custom metadata.
  const sbx = await novita.sandbox.create({
    metadata: {
      userId: '123',
    },
  })

  // Retrieve active sandboxes and inspect their metadata.
  const page = await novita.sandbox.list()
  const active = await page.nextItems()

  console.log(active[0].metadata)
  // Example output:
  // { userId: '123' }

  // Filter by metadata.
  let sandboxes = await novita.sandbox.list({
    query: { metadata: { env: 'demo' } },
  })

  // Combine metadata and state filters (multiple conditions are AND).
  sandboxes = await novita.sandbox.list({
    query: {
      metadata: { env: 'demo' },
      state: [SandboxState.RUNNING],
    },
  })

  for (const sandbox of sandboxes) {
    console.log(sandbox.sandboxId, sandbox.state, sandbox.metadata)
  }
  ```

  ```python Python icon="python" theme={"system"}
  from novita_sandbox import Novita, SandboxQuery, SandboxState

  novita = Novita()

  # Start a sandbox and attach custom metadata.
  sbx = novita.sandbox.create(
      metadata={
          "userId": "123",
      },
  )

  # Retrieve active sandboxes and inspect their metadata.
  page = novita.sandbox.list()
  active = page.next_items()

  print(active[0].metadata)
  # Example output:
  # {"userId": "123"}

  # Filter by metadata.
  sandboxes = novita.sandbox.list(
      query=SandboxQuery(metadata={"env": "demo"})
  )

  # Combine metadata and state filters (multiple conditions are AND).
  sandboxes = novita.sandbox.list(
      query=SandboxQuery(
          metadata={"env": "demo"},
          state=[SandboxState.RUNNING],
      )
  )

  for sandbox in sandboxes:
      print(sandbox.sandbox_id, sandbox.state, sandbox.metadata)
  ```
</CodeGroup>
