DEV Community

Chapri
Chapri

Posted on

I generate cinematic video ads from a Bun script with the Runway API

I needed cinematic 5-second video clips for a chess app's ads. No camera, no actors, no budget for either. So I wired up Runway's API and generated them from a Bun script. Here's the whole thing, including the part the docs gloss over.

The shape of the API

Runway's video generation is async. You don't get a video back from one call. You start a task, then poll it until it's done, then download the result. Three steps, and the polling is where people trip.

The models that matter for text-to-video right now:

  • gen4.5 at 12 credits/sec. My default. Good enough that a still frame passes for stock footage.
  • veo3.1 at 20-40 credits/sec. Google's model. Better motion, costs more.
  • gen4_turbo at 5 credits/sec, but it needs an input image.

At 12 credits/sec a 5-second clip is 60 credits. Credits run about a penny each, so ~60 cents a clip. I generated a dozen clips iterating on prompts and it cost me less than a sandwich.

Auth, and the one thing not to do

The key lives in an env var, RUNWAYML_API_SECRET. Do not pass it as a CLI flag. It ends up in your shell history and in ps output for anyone on the box. Env var or a .env file, nothing else.

Check your balance before you batch anything:

curl -s https://api.dev.runwayml.com/v1/organization \
  -H "Authorization: Bearer $RUNWAYML_API_SECRET" \
  -H "X-Runway-Version: 2024-11-06" | jq .creditBalance
Enter fullscreen mode Exit fullscreen mode

That X-Runway-Version header is required. Leave it off and you get a confusing error that has nothing to do with the actual problem.

What actually worked

For portrait reels I set the ratio to 720:1280. This matters more than the prompt. Generate at 1280:720 and then crop to vertical and you throw away half your pixels and the framing is wrong. Ask for the aspect ratio you're shipping.

The prompts that gave me usable footage were boring and specific:

Cinematic vertical shot of a young woman studying a wooden chessboard by warm window light, focused expression, photorealistic, shallow depth of field, soft film grain

Every word there is doing work. "Cinematic" and "shallow depth of field" get you the blurred background. "Soft film grain" kills the plastic AI sheen. "Photorealistic" keeps it from drifting into illustration. Drop any of them and quality drops with it.

Vague prompts gave me vague, floaty, obviously-generated garbage. The model rewards you for describing a real shot a real DP would set up.

The polling gotcha

The task sits in RUNNING for 60 to 120 seconds for a 5-second gen4.5 clip. Your script has to poll and wait, not fire-and-forget. And gen4.5 has a concurrency limit of 1 on my tier, so if you're generating a batch you run them in series, not with Promise.all. I learned that by watching the second call fail while the first was still cooking.

Rough loop:

  1. POST to start the task, get back a task id
  2. GET the task every few seconds
  3. When status flips to SUCCEEDED, pull the output URL and download it
  4. When it's FAILED, read the reason. SAFETY.INPUT means your prompt tripped moderation, reword it. ASSET.INVALID means a bad input image.

Was it worth it

Yeah. The clips came out looking like real ads. I dropped captions and a voiceover on top with ffmpeg and shipped them as reels. A frustrated player under a desk lamp, a kid in a suit making a move, a woman by a window. None of them are real people. All of them look real enough that nobody scrolling past would guess.

The whole thing runs from a script. I describe a scene, wait two minutes, get a clip. That's a wild place to be compared to a year ago.

If you're building anything that needs video and you don't have a film crew, this is the cheat code. It's the app I made the ads for: aichess.guru, an AI coach that tells you why you lost. Free to start.

Building video pipelines on Runway or Veo or Kling? I want to know what prompts you found that consistently work. Mine still feel like guesswork half the time.

Top comments (0)