Generate Video (AI CustomURL)
The Sora node that actually handles the async polling for you
- image
- video_url
- video_id
- api_key
- status
- response_json
Video is the one place where the closed labs still hold a real quality lead - Sora-grade output simply isn't coming off a consumer GPU, and even the KB's own history lesson is that open video keeps catching up but hasn't finished. This node is the pragmatic bridge: it calls POST /videos/create on an OpenAI-compatible API (sora-2 by default) and - this is the part that actually saves you - it handles the messy async wait itself. No babysitting a job that takes minutes.
How it works
Video generation on these APIs isn't one request-and-done like an image. You submit a job, get back an ID, and then you poll GET /videos/{id} until it's completed. This node wraps that whole dance. Submit, then poll every poll_interval seconds (default 5) for up to max_wait_time seconds (default 1200 - twenty minutes). Status updates stream to the console so you can watch it grind.
Two details are worth knowing because they're OpenAI-specific and the source code goes out of its way to handle them:
- Duration gets snapped. OpenAI only accepts 4, 8, or 12 second videos, so your
durationis silently rounded to the nearest legal value and the console tells you it did. Non-OpenAI providers get your exact number. - Resolution gets mapped. OpenAI only ships four sizes -
1280x720,720x1280,1024x1792,1792x1024. The node maps yourresolution+aspect_ratiocombo onto the closest one. Other APIs get the full mapping (up to1920x1080etc.).
The optional image input converts an IMAGE to a base64 data URL for image-to-video, so you can animate a frame that came from a local sampler.
The outputs and how they chain
Five outputs, and they're designed to plug into the pack's other nodes:
video_url- the finished download URL. Feed it to Save Video from URL to pull it to disk (OpenAI's content URLs need anAuthorizationheader, which is why Save Video has its ownapi_keyinput).video_id- the job ID, kept for resume.api_key- your key, passed straight through so the save node can reuse it.status-completed,failed,timeout (status: …), orprocessing.response_json- the raw API response for debugging.
If you disable auto_poll, or it times out, you don't lose the job: take the video_id and hand it to Retrieve Video Status (AI CustomURL) whenever you're ready to check back.
Installing it
ComfyUI Manager → search "AI CustomURL" → Install, restart. Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/bowtiedbluefin/ComfyUI-AI-CustomURL
cd ComfyUI-AI-CustomURL
pip install -r requirements.txt
API-only - no model downloads. Just requests, aiohttp, pillow, numpy, torch, torchaudio, and opencv-python.
Common issues
- "No valid video URL" downstream - the generation errored or timed out before a URL existed. Check
statusandresponse_json, don't assume. - Timeout at the default 20 minutes - big prompts or crowded API queues happen. Raise
max_wait_timeor setauto_polltofalseand poll manually with the retrieve node. - Sora access - the default model name means nothing if your account doesn't have video API access; expect a "model not found"-style error until it does.
Reality check: this is a tiny single-author pack with zero community footprint as of writing. The video endpoint in particular is at the mercy of whatever your provider's API actually looks like. But as the only node family here that genuinely automates the painful async polling, it's the one that earns its keep.
Inputs (13)
| Name | Type | Default | Description |
|---|---|---|---|
| base_url | STRING | https://api.openai.com/v1 | — |
| api_key | STRING | — | |
| model | STRING | sora-2 | — |
| prompt | STRING | — | |
| resolution | COMBO | 1080p | 3 options: 1080p, 720p, 480p |
| duration | INT | 41–60 | — |
| fps | INT | 241–60 | — |
| aspect_ratio | COMBO | 16:9 | 5 options: 16:9, 9:16, 1:1, 4:3, 21:9 |
| auto_poll | COMBO | true | 2 options: true, false |
| poll_interval | INT | 51–60 | — |
| max_wait_time | INT | 120060–7200 | — |
| imageopt | IMAGE | — | |
| advanced_params_jsonopt | STRING | — |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| video_url | STRING | — |
| video_id | STRING | — |
| api_key | STRING | — |
| status | STRING | — |
| response_json | STRING | — |