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

# Jobs & retries

> Track asynchronous work, retrieve results, and retry safely.

## Submit and track a job

Submit to `POST /v1/products/{product}/jobs`. The `202` response returns a public
`dap_…` job ID. Save it and read `GET /v1/product-jobs/{job_id}` for status and results.
Use the same organization and team context for uploads, submission, and reads.

## Poll for completion

[Request parameters and response schema](/docs/api-reference/products/get-a-product-job)

Set `JOB_ID` to the returned job ID, `BEEBLE_API_KEY` to your key, and
`BEEBLE_TEAM_ID` if your organization uses internal teams:

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

  ```python Python theme={null}
  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(
      f"https://api.beeble.ai/v1/product-jobs/{os.environ['JOB_ID']}",
      headers=headers,
      timeout=30,
  )
  response.raise_for_status()
  print(response.json())
  ```

  ```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/product-jobs/${process.env.JOB_ID}`,
    { headers, signal: AbortSignal.timeout(30_000) },
  )
  if (!response.ok) throw new Error(await response.text())
  console.log(await response.json())
  ```
</CodeGroup>

**Response (200, abbreviated):**

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

| Status                                   | Action                                              |
| ---------------------------------------- | --------------------------------------------------- |
| `success`                                | Download the files in `outputs`.                    |
| `failed`, `cancelled`, `credit_required` | Stop polling and inspect the error or credit issue. |
| Other statuses                           | Wait before polling again.                          |

Set a polling timeout and save the job ID to resume later. A client timeout does
not cancel the job. You can also use [webhooks](/docs/enterprise/webhooks).

## Download results

Read `outputs` after `success`. For SwitchX, download `outputs.render`;
other products use different fields. Each [product guide](/docs/products) includes a
completed response and the field to download. Check that a URL is non-null before downloading.
If a signed URL expires, read the same job again for a fresh URL.

### Output schemas

Use the response schema for the endpoint you called. The model catalog's
`input_schema` describes submission inputs, not the returned files.

The [OpenAPI response schema](/docs/enterprise/schemas/product-job) defines the job
envelope. `outputs` is an open object; product-specific download fields are not
typed in that schema. For SwitchX with `alpha_mode: "fill"`, `outputs.alpha` is `null`.

## Safe retries

1. Save the **idempotency key and request body before submitting**.
2. On a timeout or lost response, retry with the same key, body, organization, and team.
3. Use a new idempotency key for each new job. Before replacing an earlier attempt, confirm it was rejected or failed.

<Warning>
  `submitting` or `unknown` may mean the job has already started and charged.
  Replay the original request; do not submit a replacement with a new key.
</Warning>

Changing the body under the same key returns `409`. See
[Billing & credits](/docs/guides/billing#charges-and-refunds) before assuming a failed job was refunded.

<Accordion title="Uncertain submissions">
  Organization API keys have no concurrent-job limit. An uncertain submission
  still retains its original request identity: waiting does not resolve its
  outcome or make a replacement safe. Replay the same request, and contact
  support if its outcome cannot be confirmed.
</Accordion>

## List jobs

<CodeGroup>
  ```bash cURL theme={null}
  curl --fail-with-body "https://api.beeble.ai/v1/product-jobs?limit=20" \
    -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/product-jobs?limit=20",
      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/product-jobs?limit=20", {
    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>

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

**Response (200, empty page):**

```json theme={null}
{
  "jobs": [],
  "next_cursor": null
}
```

The response contains `jobs` and `next_cursor`. Pass a non-null `next_cursor`
as `before` to read the next page. `limit` accepts 1–100 and defaults to 20.
Listings contain saved statuses; read an individual job for fresh status and
output URLs.

## Access after submission

Reads are scoped to the key owner, organization, and selected team. Disabling
a product for new submissions still allows reads and replay of its existing
jobs, subject to continuing key, membership, and organization security checks.
Revoking a key or removing its access can also stop callback delivery.
