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

> ## Agent Instructions
> This site documents two API families. Choose the family before generating integration code and keep its request fields, billing, statuses, responses, and webhooks together.
> SwitchX API: POST /v1/switchx/generations; use /quickstart and /authentication. Completed generation files are under output.
> Enterprise API: POST /v1/products/{product}/jobs and GET /v1/product-jobs/{job_id}; use /enterprise/quickstart and /products. Check /enterprise for current access requirements. Completed product files are under outputs.
> For product jobs, fetch model-specific input_schema from GET /v1/products/{product}/models. OpenAPI defines the common job response; product guides show illustrative completed outputs. Do not treat output examples as exhaustive schemas.
> SwitchX 2.0 Finish uses the separate switchx_finish product and model_id switchx-2.0. Follow /products/switchx-finish: pass inputs.parent_job_id (a completed Standard switchx product generation's public dap_ ID owned by the same key owner, organization, and team) and inputs.target_resolution (1080 or 2160), without uploading media. Fast results, Finish results, and legacy SwitchX API generations cannot be parents. Estimate the transition, then submit and poll the new child ID; result files are under outputs.
> For product APIs, authenticate with an Organization API Key in x-api-key and keep the same organization and X-Beeble-Team-Id context for uploads, estimates, submissions, and reads. Use Beeble Cloud credits; product routes do not support USD.
> Follow /enterprise/llms-txt for the product API workflow: discover products and models, upload media, estimate credits, submit with an idempotency_key, and poll or receive webhooks. On an uncertain submission, retry the same body and key; do not create a replacement job.
> Product-job success is status=success; stop polling on failed, cancelled, or credit_required. Use the chosen product guide for completed response examples and download fields. Refer to /enterprise/errors, /enterprise/rate-limits, /guides/billing, and /guides/jobs for failures, limits, and refunds.

# VFX Passes

> Extract material, alpha, and depth passes for relighting and compositing.

**Product ID:** `vfx_passes` · **Billing:** Beeble Cloud credits

Turn an image or video into passes you can use separately for relighting,
background replacement, and compositing. VFX Passes uses SwitchLight 3.0;
the API model ID is `switchlight-3`.

The [VFX Pass Generator product guide](https://docs.beeble.ai/beeble/vfx-pass-generator)
shows how the passes work together in a VFX workflow.

## Before you start

1. Create an [API key](/docs/enterprise/authentication) for an organization with this product enabled.
2. [Prepare your media](/docs/guides/uploads#choose-a-media-input) as Beeble URIs, authorized CDN URLs, public/presigned HTTPS URLs, or base64 data URIs.
3. Select an available model below; complete any required consent in Beeble Cloud.

## Models and inputs

Set `BEEBLE_API_KEY` and, for internal teams, `BEEBLE_TEAM_ID`.

<CodeGroup>
  ```bash cURL theme={null}
  curl --fail-with-body "https://api.beeble.ai/v1/products/vfx_passes/models" \
    -H "x-api-key: $BEEBLE_API_KEY" \
    -H "X-Beeble-Team-Id: ${BEEBLE_TEAM_ID:-}"
  ```

  ```python Python theme={null}
  import json
  import os
  import requests

  headers = {"x-api-key": os.environ["BEEBLE_API_KEY"]}
  if team_id := os.environ.get("BEEBLE_TEAM_ID"):
      headers["X-Beeble-Team-Id"] = team_id

  response = requests.get(
      "https://api.beeble.ai/v1/products/vfx_passes/models",
      headers=headers,
      timeout=30,
  )
  response.raise_for_status()
  print(json.dumps(response.json(), indent=2))
  ```

  ```javascript JavaScript theme={null}
  const headers = { "x-api-key": process.env.BEEBLE_API_KEY }
  if (process.env.BEEBLE_TEAM_ID) {
    headers["X-Beeble-Team-Id"] = process.env.BEEBLE_TEAM_ID
  }
  const response = await fetch(
    "https://api.beeble.ai/v1/products/vfx_passes/models",
    {
      headers,
      signal: AbortSignal.timeout(30_000),
    },
  )
  if (!response.ok) throw new Error(await response.text())
  console.log(JSON.stringify(await response.json(), null, 2))
  ```
</CodeGroup>

**Response (200):** `models` contains each model's `id`, `name`,
`input_schema`, and any `requires_consent` value. Use the selected model's
`input_schema` for required inputs, types, defaults, and supported values.

[Request parameters and response schema](/docs/api-reference/products/list-product-model-input-schemas)

| Pass                          | Use it for                                     |
| ----------------------------- | ---------------------------------------------- |
| Base Color                    | Surface color separated from lighting.         |
| Normal                        | Surface orientation for relighting.            |
| Roughness, Specular, Metallic | Material response to light.                    |
| Alpha                         | Foreground opacity for background replacement. |
| Depth                         | Depth-based compositing and 3D integration.    |

The completed response below shows the JSON field names for these passes.

## Submit a job

**Schemas:** [Request body](/docs/enterprise/schemas/product-job-request) ·
[Response](/docs/enterprise/schemas/product-job). The `inputs` object follows your
selected model's `input_schema` above.

Save as `request.json` with your media URIs. The Beeble URIs below can be replaced
with any [supported single-file media input](/docs/guides/uploads#choose-a-media-input). Use a unique `idempotency_key`
for each new job; keep it unchanged on retries.

```json theme={null}
{
  "model_id": "switchlight-3",
  "billing_unit": "credits",
  "idempotency_key": "vfx_passes-example-001",
  "inputs": {
    "source": "beeble://uploads/your-upload-id/source.png"
  }
}
```

Python requires `requests`; JavaScript examples run in Node.js.

<CodeGroup>
  ```bash cURL theme={null}
  curl --fail-with-body https://api.beeble.ai/v1/products/vfx_passes/jobs \
    -H "x-api-key: $BEEBLE_API_KEY" \
    -H "X-Beeble-Team-Id: ${BEEBLE_TEAM_ID:-}" \
    -H "Content-Type: application/json" \
    --data-binary @request.json
  ```

  ```python Python theme={null}
  import json
  import os
  from pathlib import Path

  import requests

  headers = {"x-api-key": os.environ["BEEBLE_API_KEY"]}
  if team_id := os.environ.get("BEEBLE_TEAM_ID"):
      headers["X-Beeble-Team-Id"] = team_id

  response = requests.post(
      "https://api.beeble.ai/v1/products/vfx_passes/jobs",
      headers=headers,
      json=json.loads(Path("request.json").read_text()),
      timeout=120,
  )
  response.raise_for_status()
  job_id = response.json()["id"]
  print(job_id)
  ```

  ```javascript JavaScript theme={null}
  import { readFile } from "node:fs/promises"

  const headers = {
    "x-api-key": process.env.BEEBLE_API_KEY,
    "Content-Type": "application/json",
  }
  if (process.env.BEEBLE_TEAM_ID) {
    headers["X-Beeble-Team-Id"] = process.env.BEEBLE_TEAM_ID
  }

  const response = await fetch(
    "https://api.beeble.ai/v1/products/vfx_passes/jobs",
    {
      method: "POST",
      headers,
      body: await readFile("request.json", "utf8"),
      signal: AbortSignal.timeout(120_000),
    },
  )
  if (!response.ok) throw new Error(await response.text())
  const { id: jobId } = await response.json()
  console.log(jobId)
  ```
</CodeGroup>

**Response (202, abbreviated):**

```json theme={null}
{
  "id": "dap_example",
  "status": "processing",
  "outputs": {}
}
```

## Results and constraints

The server measures source metadata before estimating or submitting; you can
omit media type, frame count, frame rate, and duration.

See [Billing & credits](/docs/guides/billing) for spending caps and refunds.

## Completed response

[Poll the job](/docs/guides/jobs#poll-for-completion) using the returned `id` until
`status` is `success`. Stop on `failed`, `cancelled`, or `credit_required`.

**Example response (200, success; abbreviated):** URLs are illustrative.
Available outputs depend on the model and input media.

```json theme={null}
{
  "id": "dap_example",
  "product": "vfx_passes",
  "status": "success",
  "outputs": {
    "basecolor": {
      "png": "https://cdn.beeble.ai/example/basecolor.png?signed-parameters"
    },
    "normal": {
      "png": "https://cdn.beeble.ai/example/normal.png?signed-parameters"
    },
    "roughness": {
      "png": "https://cdn.beeble.ai/example/roughness.png?signed-parameters"
    },
    "specular": {
      "png": "https://cdn.beeble.ai/example/specular.png?signed-parameters"
    },
    "metallic": {
      "png": "https://cdn.beeble.ai/example/metallic.png?signed-parameters"
    },
    "alpha": {
      "png": "https://cdn.beeble.ai/example/alpha.png?signed-parameters"
    },
    "depth": {
      "png": "https://cdn.beeble.ai/example/depth.png?signed-parameters",
      "exr": "https://cdn.beeble.ai/example/depth.exr?signed-parameters"
    },
    "all": "https://cdn.beeble.ai/example/all-passes.zip?signed-parameters"
  }
}
```

For images, download a pass such as `outputs.basecolor.png`, or `outputs.all` for the archive. Video jobs return per-pass `mp4` and sequence archives; `outputs.all` contains `mp4` and `png` archive URLs.
