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

# Sandbox Compute

> Run supported open-weight and specialized models in VideoDB workflows by starting a sandbox and passing sandbox_id.

Sandbox Compute is VideoDB's managed runtime for supported open-weight and specialized models.

Create a sandbox, wait until it is active, then pass `sandbox_id` to supported APIs. VideoDB routes that job to your sandbox runtime instead of the default hosted path.

Sandbox is not only an indexing feature. It can power understanding analyzers, indexing pipelines, and generation workflows such as text-to-speech, image generation, audio generation, and text generation.

For hosted/default models, omit `sandbox_id`. For Sandbox Compute/open-weight models, pass `sandbox_id` explicitly.

***

## When to use Sandbox Compute

Use Sandbox Compute when you want:

* **Open-weight model access** for VLM, object detection, speech, audio, image, or text workflows.
* **Specialized models** such as Gemma, Qwen, Whisper, OmniVoice, FLUX, Stable Audio, or RT-DETR.
* **Predictable routing** by pinning a job to a specific sandbox ID.
* **Runtime-based pricing** for compatible workloads.

***

## Create a sandbox

Choose a tier based on the largest model you plan to run. Creating a sandbox returns immediately while compute is provisioning.

```python theme={null}
import videodb
from videodb import SandboxTier

conn = videodb.connect()
coll = conn.get_collection()

sandbox = conn.create_sandbox(
    tier=SandboxTier.medium,
    models=["google/gemma-4-31B-it-FP8"],
)

sandbox.wait_for_ready(timeout=300, interval=5)
print(sandbox.id)
```

You can prepare the sandbox by model category instead of exact model names:

```python theme={null}
sandbox = conn.create_sandbox(
    tier=SandboxTier.medium,
    model_categories=["vlm", "object_detection", "image_generation"],
)

sandbox.wait_for_ready()
```

Supported category names include:

| Category           | Use for                                 |
| ------------------ | --------------------------------------- |
| `vlm`              | visual scene understanding models       |
| `object_detection` | object detection models such as RT-DETR |
| `speech_to_text`   | speech recognition models               |
| `text_to_speech`   | speech generation models                |
| `image_generation` | image generation models                 |
| `audio_generation` | audio/music/sound generation models     |
| `text_generation`  | text generation models                  |

<Note>
  Submit sandbox-backed jobs only after the sandbox is active.
</Note>

***

## Pick a model

Sandbox supports VLMs, speech-to-text, text-to-speech, image generation, audio generation, object detection, and text generation models. Use the smallest sandbox tier that supports the largest model in your workflow.

<Card title="Sandbox Models" icon="brain-circuit" href="/pages/core-concepts/sandbox-models">
  See the current model catalog and minimum tier for each model.
</Card>

***

## Route jobs to the sandbox

Pass `sandbox_id=sandbox.id` to supported APIs.

If `sandbox_id` is omitted, VideoDB uses the hosted/default path. For production workflows with Sandbox models, pass the ID explicitly so routing is predictable.

***

## Use Sandbox with Understanding and Indexing

Sandbox affects the **understanding** step: it controls where the model runs. The **indexing** step is unchanged: index the resulting artifact with `video.index(...)`.

```python theme={null}
sandbox = conn.create_sandbox(
    tier=SandboxTier.medium,
    models=["google/gemma-4-31B-it-FP8"],
)
sandbox.wait_for_ready()

video = coll.get_video("m-xxx")

understanding = video.understand(
    analyzers=[
        {
            "type": "vlm",
            "name": "scene",
            "config": {
                "model": "google/gemma-4-31B-it-FP8",
                "sandbox_id": sandbox.id,
                "prompt": "Describe the scene in a clear, concise way.",
                "schema": {
                    "scene_description": "string",
                    "activity": "string",
                    "setting": "string",
                },
            },
        }
    ],
)

understanding.wait_until_complete()
scene = understanding.get_analyzer("scene")

video.index(
    name="scene",
    source=scene,
    use_for=["semantic", "query"],
    fields={
        "semantic": ["scene_description", "activity", "setting"],
        "filter": ["activity", "setting"],
    },
)
```

Search the index like any other VideoDB index:

```python theme={null}
results = video.semantic_search(
    query="person presenting an AI demo",
    index_name="scene",
    return_fields=["scene_description", "activity", "setting"],
)
```

For complete indexing options, see [Create an Index](/pages/understand/indexing-pipelines/create-an-index).

***

## Use Sandbox for object detection

For sandbox-backed object detection, choose the detection model in the analyzer config. Configure object filters and aggregations when you create the index.

```python theme={null}
sandbox = conn.create_sandbox(
    tier=SandboxTier.small,
    models=["rtdetr-v2-r50vd"],
)
sandbox.wait_for_ready()

understanding = video.understand(
    analyzers=[
        {
            "type": "object_detection",
            "name": "objects",
            "config": {
                "model": "rtdetr-v2-r50vd",
                "sandbox_id": sandbox.id,
            },
        }
    ],
)

understanding.wait_until_complete()
objects = understanding.get_analyzer("objects")

video.index(
    name="objects",
    source=objects,
    use_for=["query", "aggregate"],
    fields={
        "filter": ["object_labels", "object_counts"],
        "aggregate": ["object_labels"],
    },
)
```

***

## Use Sandbox for generation workflows

Sandbox can also route supported generation jobs. These APIs use `model_name` plus `sandbox_id`.

### OmniVoice text-to-speech

```python theme={null}
job = coll.generate_voice(
    text="Welcome to VideoDB Sandbox Compute.",
    model_name="k2-fsa/OmniVoice",
    sandbox_id=sandbox.id,
)

audio = job.wait(timeout=900, interval=5)
print(audio.id)
```

### Voice design

Use `config.instructions` to guide the voice style.

```python theme={null}
job = coll.generate_voice(
    text="Breaking update: your video workflows now have dedicated inference compute.",
    model_name="k2-fsa/OmniVoice",
    sandbox_id=sandbox.id,
    config={"instructions": "A deep, authoritative news anchor voice"},
)

audio = job.wait(timeout=900, interval=5)
```

### Reusable voice clone

Create a voice clone once from a reference audio asset, then reuse it by passing `voice_clone_id`.

```python theme={null}
ref_audio = coll.upload(
    url="https://www.youtube.com/shorts/8GrguhmR6oQ",
    media_type="audio",
)

voice_clone = coll.create_voice_clone(
    ref_audio_id=ref_audio.id,
    name="Product Narrator",
    description="Reusable narration voice",
    ref_text="Sample reference text for the audio clip",
    language="en",
)

job = coll.generate_voice(
    text="This narration uses a reusable voice clone.",
    model_name="k2-fsa/OmniVoice",
    sandbox_id=sandbox.id,
    voice_clone_id=voice_clone.id,
)

audio = job.wait(timeout=900, interval=5)
```

### FLUX image generation

```python theme={null}
job = coll.generate_image(
    prompt="A futuristic cityscape at sunset, cinematic lighting, high detail",
    model_name="black-forest-labs/FLUX.1-dev",
    sandbox_id=sandbox.id,
    config={
        "size": "1280x720",
        "num_inference_steps": 28,
        "guidance_scale": 4.0,
    },
)

image = job.wait(timeout=900, interval=5)
print(image.id)
```

### Text generation

```python theme={null}
response = coll.generate_text(
    prompt="Summarize the key visual events from this scene description list.",
    model_name="Qwen/Qwen3.5-9B-FP8",
    sandbox_id=sandbox.id,
    max_tokens=300,
    temperature=0.2,
)

print(response)
```

***

## Validation and permissions

When you pass `sandbox_id`, VideoDB validates that:

1. the sandbox exists and belongs to your workspace/account,
2. the sandbox is active,
3. the sandbox tier supports the requested model,
4. the sandbox was created with a matching `models` or `model_categories` value, when model selection was provided.

If validation fails, create or start a compatible sandbox and retry the job with that sandbox ID.

***

## Manage sandboxes

```python theme={null}
# Refresh one sandbox
sandbox.refresh()
print(sandbox.status, sandbox.is_active)

# List sandboxes
for sb in conn.list_sandboxes():
    print(sb.id, sb.name, sb.tier, sb.status)

# Get a sandbox by ID
sb = conn.get_sandbox(sandbox.id)
print(sb)
```

***

## Stop the sandbox

Sandbox billing is based on runtime. Stop the sandbox when your workload is complete.

```python theme={null}
sandbox.stop()
sandbox.wait_for_stop(timeout=120, interval=5)
print(f"Sandbox {sandbox.id} final status: {sandbox.status}")
```

***

## Pricing and limits

Sandbox billing is runtime-based. Billing is recorded when the sandbox stops and is calculated from `started_at` to `stopped_at`, rounded to 2 decimal hours.

| Sandbox tier |        Price |
| ------------ | -----------: |
| `small`      |    `$1/hour` |
| `medium`     | `$3.50/hour` |

| Sandbox tier | Concurrent sandbox limit | Max runtime |
| ------------ | -----------------------: | ----------: |
| `small`      |                        5 |    24 hours |
| `medium`     |                        3 |    24 hours |

***

## Best practices

* Create one sandbox per workflow and reuse it across compatible jobs.
* Use the smallest tier that supports your largest model.
* Use `models=[...]` when you know the exact models your workflow needs.
* Use `model_categories=[...]` when your workflow may use several models in the same category.
* Wait until the sandbox is active before submitting jobs.
* Pass `sandbox_id=sandbox.id` explicitly for production indexing and generation jobs.
* Use `job.wait(timeout=900, interval=5)` for long-running generation jobs.
* Log `sandbox.id` with each job so runs can be debugged or retried.
* Stop the sandbox when work is complete.

<CardGroup cols={3}>
  <Card title="Sandbox Models" icon="brain-circuit" href="/pages/core-concepts/sandbox-models">
    See supported models and minimum tiers.
  </Card>

  <Card title="Understanding Artifacts" icon="eye" href="/pages/understand/indexing-pipelines/understanding-artifacts">
    Configure analyzers and model selection.
  </Card>

  <Card title="Create an Index" icon="layers" href="/pages/understand/indexing-pipelines/create-an-index">
    Index artifacts produced by hosted or sandbox models.
  </Card>
</CardGroup>
