Scripting mode — file-backed flows
Fork a template once, pull it to disk, mutate the files deterministically, and render with a stable tracer. It's the repeatable posture that lets an AI agent build videos unattended — one video or a hundred.
Key takeaways
- Fork once, reuse the forkId as a stable base; branch from it for variants.
- Pull the files to disk —
composition.html,composition.json, and the.harness/grounding. - Mutate deterministically: parse the HTML as DOM, and treat
composition.jsonas a shallow-merged patch (not JSON Patch). - Render with a stable tracer so every job in a batch is traceable — but remember submits are non-idempotent (each one charges).
- The same REST sequence runs anywhere — a script, Lambda, CI, or your laptop — so an agent can build unattended.
Why file-backed?
Scripting mode is the recommended posture for repeatable template automation. Instead of chatting one edit at a time, you pick a template, fork it once, and drive every edit through the files on disk from a script. Because the whole loop is deterministic and file-backed, an AI agent (or a cron job) can run it unattended — turning a CSV of headlines into a batch of finished MP4s while you sleep.
This is a desktop / local coding-agent flow, not the web copilot. The building blocks are the same REST routes from the REST API chapter , wrapped by vidfarm api and a few convenience commands.
Fork → pull → edit → snapshot → renderThe canonical loop
-
Fork the template once
Fork your base template and keep the
forkId— it's the stable base every variant branches from.Fork onceFORK_ID="$(vidfarm api POST /api/v1/compositions \ --data '{"template_id":"template_xxx"}' --json | jq -r '.fork_id')" -
Pull the files (and the grounding)
Pull the fork to a working dir. This packages the composition files plus the
.harness/grounding an agent reads to edit thrift-first.Pull to diskvidfarm pull "$FORK_ID" --dir ./work # then read ./work/.harness/agent-guide.md and ./work/.harness/context.json -
Mutate deterministically
Edit
./work/composition.htmlby parsing it as DOM (never string-concatenate), and write only the keys you're changing into./work/composition.json— the server shallow-merges it (it is not RFC-6902 JSON Patch). -
Snapshot, then render with a tracer
Snapshot a version, then render with a stable, descriptive tracer so the job is traceable in your history.
Snapshot + rendervidfarm snapshot "$FORK_ID" vidfarm render "$FORK_ID" --dir ./work --tracer "batch-2026-07-09-row-42" --wait
Written out end-to-end with raw vidfarm api calls, the whole loop is just this — copy-paste it as the skeleton for any automation:
BASE_TEMPLATE_ID="template_..."
# fork once → stable base
FORK_ID="$(vidfarm api POST /api/v1/compositions \
--data "{\"template_id\":\"${BASE_TEMPLATE_ID}\"}" --json | jq -r '.fork_id')"
# pull the files
vidfarm api GET "/api/v1/compositions/${FORK_ID}/composition.html" --raw > /tmp/composition.html
vidfarm api GET "/api/v1/compositions/${FORK_ID}/composition.json" --raw > /tmp/composition.json
# ── edit the files in your script (parse HTML as DOM; JSON = shallow merge) ──
# write them back
vidfarm api PUT "/api/v1/compositions/${FORK_ID}/composition.html" \
--body-file /tmp/composition.html --content-type "text/html; charset=utf-8"
vidfarm api PATCH "/api/v1/compositions/${FORK_ID}/composition.json" --data-file /tmp/composition.json
# snapshot a version, then render with a stable tracer
vidfarm api POST "/api/v1/compositions/${FORK_ID}/versions" --data '{"message":"scripting mode snapshot"}'
vidfarm api POST "/api/v1/compositions/${FORK_ID}/render" --data '{"tracer":"scripting-mode"}'$ vidfarm pull <forkId> --dir ./work && tree ./work
./work
├── composition.html # the timeline you edit
├── composition.json # layers, timing, media refs
└── .harness/
├── viral-dna.json # what makes it work
├── editor-harness.json # editing-style brief
└── replication-harness.jsonThe .harness/ filesHow an agent stays grounded
Before touching anything, an AI-authored script reads the pulled grounding. .harness/agent-guide.md renders VidFarm's "three paintbrushes & two replication harnesses" concretely — so the agent rebuilds a template thrift-first (clipping + HyperFrames on free compute before any paid generation) and can recreate it with no wallet at all.
video-context.json— what the source video actually is, scene by scene.editor-harness.json— the editing-style brief (pace, typography, b-roll, transitions).replication-harness.json— the 3-paintbrush cheap-vs-best BUILD plans.scene-annotations.json+context.json— the per-scene detail the agent edits against.
vidfarm pull won't produce them, and you + your agent must decompose the reference video yourselves. See Free mode with NVIDIA credits .vidfarm
Copy the full REST + CLI playbook into your agent, or grab the one-line install command from the ⋮ menu.
tracer still creates a new job and a new charge. Always check render status before retrying, especially in a loop. Render local (free) on a serve box, or cloud (render_target: "cloud", billed at 1.2×) when you need scale.Wire the loop to an eventReactive systems
Because the whole loop is a deterministic REST sequence, it doesn't have to start with you — it can start with an event. Drop the fork → pull → edit → render loop behind a webhook (or a cron), and VidFarm becomes a reactive video factory that fires the instant something happens.
The highest-leverage version is newsjacking. Point a news / trends / social webhook at your script; the moment a relevant story breaks, the handler branches from your base fork, drops the headline into one of your best-performing meme formats, and cloud-renders a timely, on-brand meme — so you're first to the moment instead of scrambling an hour later.
- Newsjacking on a webhook — news breaks → seize it with a well-timed meme in your proven format, published while it's still hot.
- Onboarding videos — a
signupwebhook → a personalized video welcome letter rendered and emailed to each new user. - Scheduled loops — a daily cron → a fresh team summary video (metrics, wins, standup recap) printed for the whole team every morning.
- Any trigger, same loop — Zapier, a Stripe event, a GitHub release, a support ticket — if it's a webhook, it can mint a video.
# reactive handler: fires on a webhook, branches from your base fork, renders a meme
# (BASE_FORK_ID = a template you forked ONCE and keep as the stable base)
HEADLINE="$1" # e.g. piped in from the news/webhook payload
# branch a fresh working copy from the base
vidfarm pull "$BASE_FORK_ID" --dir ./work
# swap the headline into your best meme format (parse composition.html as DOM), then:
vidfarm snapshot "$BASE_FORK_ID"
vidfarm render "$BASE_FORK_ID" --dir ./work \
--tracer "newsjack-$(date +%Y%m%d-%H%M)" --wait --cloud--cloud) so the job runs without a machine sitting idle waiting for the event — and because the trigger is unattended, keep the same guard as any loop: check render status before retrying, since every submit is a fresh charge.Where to go next
Build a batch unattended
Fork once, pull to disk, mutate deterministically, and render with a stable tracer. That's the whole loop an AI agent runs to build videos while you're away.
Get your API key