> ## 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.

# Image Upscaler

> Increase image resolution with an available upscaling model.

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

## Before you start

1. Create an [API key](/docs/enterprise/authentication) with your organization selected.
2. Confirm the product is enabled and your organization has Beeble Cloud credits.
3. Select a model below and complete any required consent in Beeble Cloud.

## Choose a model

List the models available to your organization:

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/image_upscaler/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/image_upscaler/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/image_upscaler/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)

## Prepare your inputs

Provide your image using the model’s image input. Check its allowed scale or target-resolution parameters; these differ by model.

For each media field supported by your model, provide a Beeble URI, an authorized
Beeble CDN URL, a public/presigned HTTPS URL, or a base64 data URI. HTTPS and data
URIs do not require a separate upload. Follow the [shared media limits](/docs/guides/uploads#choose-a-media-input)
and the selected model's file requirements.

## 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.

**Request template:** replace `MODEL_ID_FROM_CATALOG` and fill `inputs` from
the model schema. Save as `request.json`. Use a unique `idempotency_key`
for each new job; keep it unchanged on retries.

```json theme={null}
{
  "model_id": "MODEL_ID_FROM_CATALOG",
  "billing_unit": "credits",
  "idempotency_key": "image_upscaler-example-001",
  "inputs": {}
}
```

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

<CodeGroup>
  ```bash cURL theme={null}
  curl --fail-with-body https://api.beeble.ai/v1/products/image_upscaler/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/image_upscaler/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/image_upscaler/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": {}
}
```

<span id="retrieve-results" />

## 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": "image_upscaler",
  "status": "success",
  "outputs": {
    "media_kind": "image",
    "primary_url": "https://cdn.beeble.ai/example/upscaled.png?signed-parameters",
    "thumbnail_url": "https://cdn.beeble.ai/example/thumbnail.webp?signed-parameters"
  }
}
```

Download `outputs.primary_url` for the upscaled image.
