xargs -P 3: send a prompt file to Wan 3.0 without losing quotes

A 17-line shell script fans a prompts.txt out to Sume /v1/videos with xargs -P 3. Six 2 s 480p Wan 3.0 jobs cost $0.75, and a rerun reuses each prompt's key.

4 min readSume
All posts

When you have a text file of prompts and want video from each, the shortest fan-out is xargs -P. It needs no queue library and no Python, and it works on the macOS and Linux shells that most people already have. It also has a trap that corrupts prompts quietly, and a Sume feature that makes a rerun safe.

The script below submits one Wan 3.0 job per line of prompts.txt, three at a time, at 2 seconds and 480p. Sume prices Wan 3.0 at $0.0625 a second at 480p, so each job is $0.125 and six are $0.75.

The script

It writes a jobs.tsv of job ids and polling URLs for a later poll step, such as the loop in /blog/bash-curl-jq-poll-sume-job-exit-codes-for-ci. I ran it with six prompts against a local stand-in server, and all six requests arrived with the right body.

#!/usr/bin/env bash
set -euo pipefail
export BASE="${SUME_API_BASE:-https://api.sume.com}"
export KEY="${SUME_API_KEY:?set SUME_API_KEY}"

submit() {
  local id body
  id="batch-a-$(printf %s "$1" | shasum | cut -c1-12)"
  body="$(jq -nc --arg p "$1" '{model:"wan-3.0",prompt:$p,duration:2,resolution:"480p"}')"
  curl -sS -X POST "$BASE/v1/videos" -H "Authorization: Bearer $KEY" \
    -H 'Content-Type: application/json' -H "Idempotency-Key: $id" -d "$body" \
    | jq -r '[.id, .polling_url] | @tsv'
}
export -f submit

tr '\n' '\0' < prompts.txt | xargs -0 -P 3 -I{} bash -c 'submit "$1"' _ {} > jobs.tsv
wc -l < jobs.tsv

The quote trap

My first version used xargs -I{} straight on the file. A prompt line containing A "quoted" prompt arrived at the server as A quoted prompt, because xargs reads quote characters in its input as quoting. No error appears; you just pay for the wrong prompt.

The fix is the first half of the last command. tr turns each newline into a NUL byte and xargs -0 splits only on NUL, so every character of the line survives. GNU xargs has a -d option for this, but the BSD xargs on macOS does not, which is why tr is the portable form. The prompt is then passed to the function as $1, not spliced into a command string, and jq --arg builds the JSON, so quotes and backslashes are escaped properly.

A key per prompt

Each request carries Idempotency-Key: batch-a- plus the first 12 characters of the prompt's SHA-1. Sume's guide says a replay with the same key returns the original job, so if the run dies at prompt four and you start it again, the first three come back as the existing jobs and are not billed twice. Change the batch-a prefix when you actually want new takes of the same prompts.

Cost of the prompt-file batch on Wan 3.0 at 2 s, from Sume's pricing tables (read 2026-10-05)
Prompts480p at $0.125720p at $0.251080p at $0.50
6$0.75$1.50$3.00
50$6.25$12.50$25.00
200$25.00$50.00$100.00

Limits to respect

-P 3 keeps the burst small. The API answers 429 rate_limited when you go too fast, and the script has no retry for that. A refused request returns no job id, so check jobs.tsv for empty or null fields before polling. Keep the parallelism low for a first run, and add the 402 and 429 handling from your own error policy before pointing it at hundreds of lines.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume