Skip to content

Overnight Batch Queue

Clawbot, the videoclaw mascot, illustrating batch queue

Hand it one JSON file listing dozens of video jobs, walk away, and wake up to a folder of finished clips — generated overnight for free on Runway's explore mode, and safe to resume after a crash, a closed laptop, or a rate-limit.

What it does

  • Turns a single operator-authored manifest into N independent video jobs that run unattended overnight.
  • Defaults to the free runway-useapi explore mode (low-res, slow "backfill draft" generation at zero credit cost); switch to dreamina-useapi or seedance-direct when you want paid hi-res.
  • Is resumable and idempotent — re-running the monitor only advances still-pending jobs; finished clips are never re-downloaded and nothing is resubmitted, so it's safe to fire on a schedule.
  • Supports per-job characterRefs so a character sheet locks identity in the provider's reference slot and is never used as the video's first frame (no clip that opens on the character grid).
  • Reuses the exact same native route transports as the normal execute runtime — there is no separate, bug-prone submit/poll path.
  • Ships pure helpers (isExploreThrottled, detectWedgedScenes) for explore-throttle and wedge detection; the batch-monitor CLI loop currently polls on a fixed --interval and does not yet auto-back-off or auto-requeue wedged scenes.

How to use it

First author a manifest (batch.json), then run the three commands. Everything below uses the full node dist/cli/vclaw.js video ... form; once the CLI is on your PATH you can shorten it to vclaw video ....

json
{
  "schemaVersion": 1,
  "route": "runway-useapi",
  "defaults": { "seconds": 8, "aspectRatio": "16:9", "resolution": "720p" },
  "jobs": [
    { "id": "skyline", "prompt": "a neon city skyline at night, slow drift" },
    { "id": "forest", "prompt": "a quiet pine forest at dawn", "keyframe": "/refs/forest.jpg", "seconds": 10 },
    { "id": "hero-walk", "prompt": "the hero strides toward camera", "characterRefs": ["/refs/hero-sheet.png"] }
  ]
}
bash
node dist/cli/vclaw.js video batch-submit --manifest batch.json --out runs/overnight

Reads + validates the manifest, compiles it into one execution payload, submits via the route's native transport, and writes runs/overnight/batch-queue.json.

bash
node dist/cli/vclaw.js video batch-submit --manifest batch.json --out runs/overnight --route dreamina-useapi

Same submit but overrides the manifest route — point a paid hi-res route at the same jobs.

bash
node dist/cli/vclaw.js video batch-monitor --out runs/overnight --once

Does a single poll pass and exits — downloads any completed scenes, copies them to clips/<jobId>.mp4, updates statuses, and writes batch-status.json. This is the call launchd/cron schedules.

bash
node dist/cli/vclaw.js video batch-monitor --out runs/overnight --interval 1200 --max-minutes 600

Loops in the foreground, polling every --interval seconds (defaults to 1200s / 20 min when omitted) until every job is terminal or --max-minutes elapses.

bash
node dist/cli/vclaw.js video batch-status --out runs/overnight

Prints the current done/pending/failed rollup without polling or touching providers.

How it flows

batch queue diagram

Diagram source (live Mermaid)

Artifacts & outputs

Batch artifacts live under the --out directory you pass (not inside a project's projects/<slug>/artifacts tree — a batch spans many independent jobs):

  • <dir>/batch-queue.json — the submit state: { externalJobId, route, outputDir, submittedAt, jobs:[{ id, sceneIndex, taskId, status }] }. Written by batch-submit, advanced by batch-monitor.
  • <dir>/batch-status.json — the latest done/pending/failed rollup, written each monitor pass.
  • <dir>/scene-<i>.mp4 — raw per-scene output the native transport downloads.
  • <dir>/clips/<jobId>.mp4 — the stable, human-named clip each completed scene is copied to (this is what you collect in the morning).

The input manifest is validated against schemas/video/artifacts/batch-queue-manifest.schema.json.

Tips & gotchas

Free overnight backfill

Omit route (or set runway-useapi) to run the whole queue at zero credit cost in explore mode. It's low-res and slow — perfect for unattended draft backfill, not for finals.

characterRefs vs keyframe

Use characterRefs (an array, one per character) to lock identity — they go to the provider's reference slot and never become the first frame. Use keyframe only for a genuine first-frame seed. They're mutually exclusive; if both are present, characterRefs wins. See Characters & identity and Reference sheets.

Idempotent, so schedule it freely

Re-running batch-monitor only moves pending jobs forward. Jobs already done (or whose clips/<id>.mp4 exists) short-circuit — nothing is re-downloaded or resubmitted. That's what makes --once safe to call every 20 minutes from launchd.

Explore mode throttles

Runway's free explore mode allows ~1 concurrent job and returns canUseExploreMode:false / HTTP 429 when saturated, so a long, mostly-pending queue overnight is expected, not a failure. Set a longer --interval to avoid hammering the queue.

Malformed manifests fail loudly

A bad manifest (wrong schemaVersion, missing jobs, duplicate id, invalid route, or a non-string field) throws with a precise message — there is no silent fallback. Fix the JSON and re-run batch-submit.

Driving it from an agent

Run batch-submit once, then schedule batch-monitor --out <dir> --once on an interval (e.g. launchd StartInterval 1200s); each tick advances the queue and exits, and once the rollup is terminal subsequent ticks are no-ops. Poll batch-status --out <dir> between passes and read terminal: true in the rollup to know the whole batch is finished. Submit and monitor exit non-zero on a malformed manifest or an unreadable queue directory, so an agent can branch on exit code. Related: Providers & routes and Projects & lifecycle.

Built to be driven by agent hosts like Claude Code, Claude Desktop, or Codex · Source-available, commercial use requires a paid license.