skills/pixverse/SKILL.md
Generate AI videos from text or an image via the PixVerse Platform API (text-to-video, image-to-video). Submit a generation, poll for the result, get the MP4 URL. Use for product demos, recipe/cooking videos, social clips, b-roll, or any "turn this prompt/image into a short video" task. Async API (submit returns a video_id, you poll a result endpoint).
npx skillsauth add RonanCodes/ronan-skills pixverseInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
PixVerse Platform API: submit a generation, poll for the result, get an MP4 URL. Async (no streaming). Docs: https://docs.platform.pixverse.ai
https://app-api.pixverse.aiPIXVERSE_API_KEY (a Worker secret / .dev.vars locally; NEVER commit it).API-KEY: <key>Ai-trace-id: <a fresh UUID per request> — load-bearing: reuse the same trace-id and you get the SAME video back, not a new one. Generate a new UUID per submit.Content-Type: application/jsonText-to-video — POST /openapi/v2/video/text/generate
{
"prompt": "string, <= 5000 chars",
"model": "v5",
"duration": 5,
"quality": "540p",
"aspect_ratio": "16:9",
"motion_mode": "normal",
"negative_prompt": "",
"seed": 0,
"water_mark": false
}
Required: prompt, model, duration, quality, aspect_ratio.
model: v3.5, v4, v4.5, v5, v5.5, v5.6, v6, c1. Safe default v5.duration: 5 or 8 (v3.5–v5.6); 1–15 (v6/c1).quality: 360p / 540p / 720p / 1080p.aspect_ratio: 16:9, 9:16, 1:1, 4:3, 3:4, ... (more on v6/c1).generate_audio_switch (v5.5+), sound_effect_switch + sound_effect_content (v5 and below), lip_sync_tts_*.Image-to-video — POST /openapi/v2/video/img/generate (same auth + polling; the body takes an uploaded image reference plus prompt/model/duration/quality — see docs image-to-video-generation).
Submit response:
{ "ErrCode": 0, "ErrMsg": "success", "Resp": { "video_id": 123456 } }
ErrCode === 0 is success; otherwise throw with ErrMsg. Keep Resp.video_id.
GET /openapi/v2/video/result/{video_id} (same three headers).
{ "ErrCode": 0, "Resp": { "status": 1, "url": "https://.../out.mp4", "prompt": "...", "seed": 0 } }
status === 1 → done, Resp.url is the MP4.A Node/tsx script (global fetch, crypto.randomUUID(), no deps):
PIXVERSE_API_KEY from env. Build a prompt.Ai-trace-id; read Resp.video_id.status === 1; return Resp.url.{ prompt, video_id, url } somewhere; print the URL.# load the key, then run
set -a; source .dev.vars; set +a
pnpm tsx scripts/pixverse-video.ts --prompt "a top-down cooking video of ..."
curl smoke test:
curl -s https://app-api.pixverse.ai/openapi/v2/video/text/generate \
-H "API-KEY: $PIXVERSE_API_KEY" -H "Ai-trace-id: $(uuidgen)" -H "Content-Type: application/json" \
-d '{"prompt":"a cinematic top-down shot of pasta boiling","model":"v5","duration":5,"quality":"540p","aspect_ratio":"16:9"}'
# -> {"ErrCode":0,"Resp":{"video_id":N}}, then:
curl -s https://app-api.pixverse.ai/openapi/v2/video/result/N \
-H "API-KEY: $PIXVERSE_API_KEY" -H "Ai-trace-id: $(uuidgen)"
Ai-trace-id per request or you get a cached/duplicate video.url is a download link; persist the MP4 (R2 / your storage) if you need it long-term, don't assume the URL is permanent.quality/duration modest while iterating.The PixVerse Platform API (platform.pixverse.ai) is billed SEPARATELY from the PixVerse web app (app.pixverse.ai). API credits and web credits do not cross over. A web subscription does NOT fund the API, so the API returns ErrCode 500090: Insufficient balance even with a full web plan. The API entry tier is ~$100/mo (Essential, ~15k credits); the web app is cheap pay-as-you-go. For one-off / hackathon generation, use the WEB app (paste prompt + settings), not the API. Reach for the API only when you have an API plan and need programmatic/batch generation.
Two clips per dish, different jobs:
The recipe photo subtly comes alive. Settings: upload the recipe photo as the start frame, model V6, 720p, 1:1, 5s, Multi-Shot OFF, motion strength LOW, Audio OFF. Hard-won rules:
<video loop> is seamless:
ffmpeg -y -i in.mp4 -filter_complex "[0:v]reverse[r];[0:v][r]concat=n=2:v=1:a=0,format=yuv420p[v]" -map "[v]" -an boomerang.mp4
This frees the prompt to use a gentle slow push-in (forward = in, reverse = out, back to start).<video autoPlay loop muted playsInline poster={photo}>, pointer-events-none so it never steals the card tap. Muted+playsInline+autoplay is the only combo iOS autoplays. poster = the photo so frame 0 matches (no flash).The classic step montage. Settings: NO start image (a start image opens on the finished dish; a how-to must start on raw ingredients), text-to-video, V6, 720p, 16:9, 12s, Multi-Shot ON, Audio ON. Optionally set the recipe photo as the last frame via the Transition feature so it lands on the real dish.
Generate (web app) → boomerang (ffmpeg) → upload to an R2 public bucket → store the public URL on the recipe row (recipe_media.video_url) → the card autoplays it. Pre-generate + cache; never generate on the request path. POC CLI: scripts/pixverse-cooking-video.ts (needs an API plan to run).
testing
--- name: linear-pipeline description: The Fable orchestrator for a single dispatched Linear ticket. Holds almost no context itself; it receives `--issue <ID> --detached`, decides the stage sequence, and fans out a sub-agent per stage, passing forward only each stage's artifact (never re-derived, never inlined into its own context). Step zero, before any planning or stage routing, is a boundary triage against `canon/security-boundary.md` (#199): a match tags Ronan Connolly and stops the run, no
development
--- name: in-your-face description: Capture a chat-only answer into a durable artifact (markdown + HTML, PDF when cheap) and launch it automatically so the user cannot miss it. Use when user says "in your face", "don't let me lose this", "save that answer", "make that durable", or right after answering a substantive side question (a recipe, comparison, how-to, or generated prompt) that would otherwise die with the context. category: workflow argument-hint: [--no-open] [--vault <short>] [hint of
tools
One-shot headless OpenAI Codex CLI calls for background/admin AI tasks — summaries, classification, extraction, admin glue. The default engine for anything that runs AI constantly in the background (daemon-driven, per-event), because it bills the flat ChatGPT subscription instead of Claude usage or per-token API spend, and it keeps working while Claude is rate-limited. NEVER for coding — coding stays Claude. Use when a skill or daemon needs a cheap always-on AI call, when the user says "use codex", "ask codex", "codex as backup", or when building a background summarizer/classifier into a listener or loop. Reads auth from ~/.codex/auth.json (ChatGPT account, no API key).
research
Turn a warranty rejection, repair quote, or RMA email into a cited decision brief — legal read (NL/EU consumer law), is the part user-serviceable, live part and new-unit prices, repair-vs-DIY-vs-new economics, before-you-send-it checklist, deadlines. Use when the user pastes or screenshots a repair quote, warranty rejection, "not covered" email, onderzoekskosten fee, or asks "should I repair or replace this".