Recipes
Real automation patterns for picx-cli — batch generation, folder edits, and agent-driven scripting.
Practical scripts built from the commands in the Command Reference. Every example uses --json where the output needs to be parsed by another command.
Batch generate for social media
Different aspect ratios for different platforms, run back to back:
picx image "minimal flat-lay coffee, aesthetic" --aspect-ratio 1:1 # IG post
picx image "bold dramatic thumbnail" --aspect-ratio 16:9 --size 2K # YouTube thumbnail
picx image "behind the scenes shot" --aspect-ratio 9:16 # IG story
Batch edit a folder
Upload every image in a directory, then apply the same edit to each:
for f in ./photos/*.jpg; do
url=$(picx upload "$f" --json | jq -r .url)
picx image edit "vintage film grain" -i "$url"
done
-ialso accepts a local path directly and uploads it for you, so the loop above can drop the explicitpicx uploadstep:for f in ./photos/*.jpg; do picx image edit "vintage film grain" -i "$f" done
This requires
jqto parse the--jsonoutput. If you don't have it installed, parse the output with your shell's own JSON tooling instead — the shape is stable and documented in the Command Reference.
Poll a video generation to completion
job_id=$(picx video "a drone shot flying over a coastline" --json | jq -r .id)
while true; do
status=$(picx job "$job_id" --json | jq -r .status)
echo "status: $status"
[ "$status" = "completed" ] && break
[ "$status" = "failed" ] && { echo "generation failed"; exit 1; }
sleep 10
done
picx job "$job_id" --json | jq -r .output_url
Lip-sync a talking-head clip to a voice track
lipsync mode takes no prompt — the audio drives the mouth. It needs both a source video and an audio track:
clip=$(picx upload ./presenter.mp4 --json | jq -r .url)
voice=$(picx upload ./voiceover.mp3 --json | jq -r .url)
job_id=$(picx video --mode lipsync \
--source-video "$clip" --audio "$voice" --json | jq -r .id)
picx job "$job_id" --watch
Replay a failed webhook delivery
When a delivery to your endpoint failed (endpoint was down, returned a 5xx), find it and re-fire the same signed payload. The redelivery is a real outbound POST — only run it when you're ready to receive it:
# find the failed delivery for a webhook endpoint
del_id=$(picx webhook deliveries wh_abc123 --json \
| jq -r '.deliveries[] | select(.status=="failed") | .id' | head -1)
# re-fire it
picx webhook redeliver "$del_id"
Check credit balance before a large batch
balance=$(picx balance --json | jq -r .credits)
echo "current balance: $balance"
if [ "$balance" -lt 500 ]; then
echo "low balance — top up before running the batch"
exit 1
fi
Connect an AI agent instead of shelling out
If the consumer of these commands is itself an AI agent (Claude Code, a custom LLM loop, etc.), it's usually better to connect it directly to the PicX MCP server rather than have it shell out to picx commands — the agent gets structured tool calls instead of parsing CLI stdout:
picx mcp install --client claude
picx mcp doctor
Use CLI scripting (the recipes above) for deterministic pipelines you control; use MCP for an agent that decides what to generate based on conversation.
FAQ
Can I run these recipes in CI?
Yes — picx-cli has no interactive prompts once PICX_API_KEY is set, so every command here is CI-safe. Store the key as a CI secret, not in the script.
Do these recipes handle rate limits or retries?
No — they're minimal examples. For production automation, wrap calls in a retry loop with backoff on non-2xx --json output, and check picx usage periodically to stay ahead of your account's rate limit.
What's the difference between using these recipes and connecting via MCP?
CLI recipes are for deterministic, script-driven pipelines you write once and run repeatedly (a cron job, a CI step, a batch export). MCP is for an AI agent that decides at runtime what to generate based on a conversation — see MCP Overview.