Beeble SwitchX
The cloud node that relights your video without touching the subject
- source
- reference_image
- alpha
- source_video
- alpha_video
- output
- output_alpha
- job_id
- render_url
- raw_json
- video
Here's the honest pitch before you get excited: Beeble SwitchX is a paid cloud API, and this node is a wrapper for it. Every generation bills your Beeble account in USD - no free tier, no local GPU, and no per-job price quote before you run. So you reach for this when the thing you want is genuinely hard locally: re-generating everything outside a masked subject in a video while keeping the original pixels inside it, and relighting the subject to match. That's usually days of VFX-compositor work, sold as a single API call.
Give it a source video (or image), an optional reference for the look, an optional alpha mask, and a prompt, and it handles the whole lifecycle: upload, submit, poll with a live progress bar, then hand you back rendered frames plus the alpha track as plain IMAGE tensors.
How it works
Mechanically it's a clean three-phase flow. First, upload: a wired IMAGE input gets encoded locally - PNG for image jobs, MP4 (via imageio[ffmpeg]) for video - then pushed to a presigned URL in two steps (POST /v1/uploads for the URL, then PUT the bytes). Alternatively, type a beeble:// or https:// URI into source_uri / reference_image_uri / alpha_uri and it's passed through verbatim - no upload at all. Then it submits POST /v1/switchx/generations. Then it polls GET /v1/switchx/generations/{id} every 15 seconds - capped at 5 RPM on the read side, so the node backs off exponentially if you hit a 429 - until the job completes, fails, or the 30-minute timeout runs out.
One naming gotcha baked into ComfyUI: an IMAGE socket is always a batch [B, H, W, C], so source and alpha accept a single still or a multi-frame batch depending on the job type. reference_image is always a single still - the Beeble API hardcodes it to one image, no array form, so don't go hunting for a per-frame option that doesn't exist.
The inputs that actually matter
You'll set three things on every run:
generation_type-imageorvideo(video is capped at 240 frames). The wired source must match.alpha_mode- start withauto, where Beeble auto-detects the foreground.selectmeans you provide a clean first-frame alpha and the API propagates it;custommeans full per-frame masks;fillkeeps everything as-is - really just global relight/re-style.max_resolution- 1080 (the API default) or 720. 720 is cheaper and faster; use it for tests.
And the one rule that trips people: at least one of prompt or reference_image is required - the node enforces it client-side. fps only matters when you're encoding a wired frame batch as MP4 for upload.
The outputs are the useful part: output (IMAGE), output_alpha (IMAGE - a 1×1 black placeholder when no alpha comes back, like in fill mode), job_id (STRING, swx_...), render_url (STRING, a CDN link that expires after 72h - re-fetch via the job id later), and raw_json for debugging. Wire output into a Video Combine (VHS) or an AM Write Video node and you're done.
Installing it
Install comfyui-beeble-ai from ComfyUI Manager, or take the manual route:
cd ComfyUI/custom_nodes
git clone https://github.com/am-pipeline-prod/comfyui-beeble-ai.git
cd comfyui-beeble-ai
pip install -r requirements.txt
Restart ComfyUI and you'll get a "Beeble AI" category. Dependencies are light - requests, imageio[ffmpeg], Pillow, numpy - and there are no model files to download, because the model lives on Beeble's servers, not yours.
The thing everyone trips on is the API key, and the author deliberately doesn't take it as a widget (it'd get baked into saved workflows and screenshots). Grab one at developer.beeble.ai/api-keys, then either:
export BEEBLE_API_KEY="bbl_sk_..."
or a config file at ~/.config/comfyui-beeble-ai/config.toml (%APPDATA%\comfyui-beeble-ai\config.toml on Windows) with one line: api_key = "bbl_sk_...".
Common issues
No Beeble API key found- you skipped the step above.SOURCE_TOO_LARGE/VIDEO_TOO_MANY_FRAMES- the API caps sources at ~2.77M pixels and video at 240 frames. Downsample or trim before the node.CONCURRENT_LIMIT_EXCEEDED- you have 10 SwitchX jobs in flight on the account. Wait, or check the Beeble dashboard.RATE_LIMIT_EXCEEDEDwhile polling - auto-retries with backoff; if it's constant, raisepoll_interval_secondsabove 15.- Hangs in
in_progress- the 30-minute default timeout is real; long videos can exceed it. Raisepoll_timeout_seconds.
One last wallet warning: cancelling the ComfyUI run does not cancel the API job - it keeps running and keeps billing. Also, this is a self-serve MIT wrapper by Adrian Meyer (am-pipeline-prod), not actively maintained and not affiliated with Beeble. It works; if you depend on it for work, budget for a fork.
Inputs (15)
| Name | Type | Default | Description |
|---|---|---|---|
| generation_type | COMBO | video | 'image': single still in, single still out. 'video': multi-frame in, multi-frame out (max 240 frames). The wired source must match this setting. |
| alpha_mode | COMBO | auto | auto: API auto-detects the foreground subject. select: Provide first-frame alpha; API propagates. fill: Keep everything as-is, no masking. custom: Provide a full per-frame alpha sequence. |
| max_resolution | COMBO | 1080 | Output resolution cap (longest side). 1080 is the API default; 720 is faster and cheaper. |
| fps | FLOAT | 24.01–240 | FPS used when encoding a wired source/alpha frame batch as MP4 for upload (video mode only). Ignored when generation_type='image' or when you supply URIs directly. |
| prompt | STRING | Text description guiding the new look. Recommended even when a reference image is provided. Either prompt or reference_image (or both) is required by the API. | |
| sourceopt | IMAGE | Source media. Single image for image jobs, multi-frame batch (e.g. from Load Video) for video jobs. Overrides source_uri when wired. | |
| reference_imageopt | IMAGE | Single still image used as a style/look reference. The Beeble API hardcodes this to one image -- no array, no per-frame targeting. Overrides reference_image_uri when wired. | |
| alphaopt | IMAGE | Alpha mask. Single image for image jobs and 'select' mode (first-frame alpha). Multi-frame batch for 'custom' mode in video jobs. Overrides alpha_uri when wired. | |
| source_uriopt | STRING | beeble:// or https:// URL. Used only when 'source' is not wired. | |
| reference_image_uriopt | STRING | beeble:// or https:// URL. Used only when 'reference_image' is not wired. | |
| alpha_uriopt | STRING | beeble:// or https:// URL. Used only when 'alpha' is not wired. | |
| poll_interval_secondsopt | FLOAT | 155–120 | Seconds between status polls. Read endpoints are capped at 5 RPM per account, so 12+ s is safe. |
| poll_timeout_secondsopt | FLOAT | 180060–86400 | Maximum wall-clock time to wait per job (seconds). |
| source_videoopt | VIDEO | Optional VIDEO source. Forces generation_type = video, uploads the underlying file directly (no IMAGE re-encode). Takes precedence over `source` and `source_uri`. Wire from Topaz, AM Read Video → VIDEO output, or a lazy AM transform chain. | |
| alpha_videoopt | VIDEO | Optional VIDEO alpha (per-frame mask sequence). Same upload semantics as source_video. Takes precedence over `alpha` and `alpha_uri`. Use with alpha_mode='custom' for per-frame masks. |
Outputs (6)
| Name | Type | Description |
|---|---|---|
| output | IMAGE | — |
| output_alpha | IMAGE | — |
| job_id | STRING | — |
| render_url | STRING | — |
| raw_json | STRING | — |
| video | VIDEO | — |