What I was working on was cinematic hero footage for an outdoor structure, and the most important shot was taken from underneath it at sunset. That warm golden color was not a style choice I could swap out on a whim, it was where the entire value of the asset sat.
Before any of the filter trouble, there was one misunderstanding that cost me time up front. The generator is not an MCP, so looking for it in the /mcp list just sends you in circles. It is a local CLI called from the shell with the full path to its binary, and once that is clear the rest is a matter of memorizing a handful of commands.
The tool is a CLI, not an MCP
The first two commands I run each session only check state. One confirms the session is still logged in, the other reads the list of available models. The model list is split by output type through a flag.
C:\tmp\gencli\gencli.exe account status
# the logged-in account sits on the max plan
C:\tmp\gencli\gencli.exe model list --video
C:\tmp\gencli\gencli.exe model list --imageThe generation command itself looks like this, with two images acting as the first and last frame.
C:\tmp\gencli\gencli.exe generate create dualkey_v2 `
--prompt "..." `
--start-image start.png `
--end-image end.png `
--wait --wait-timeout 18mThe media flags accept either a UUID or a local file path, and local paths upload themselves with no separate upload step. The --wait flag holds the process until it finishes and then prints the result URL.
There is one small trap in that printing step. If the output goes through Tee-Object, the text is written as UTF-16 and the URL reaches me as spaced-out characters. Reassembling that by eye is work that does not need to exist, so I pull it with the regex https://\S+\.mp4 instead. For long generations I run the command with run_in_background: true so the result lands in the task output file and I am not babysitting a terminal.
The model roster and what it costs
The model list I work from is marked as verified for June 2026, and only one distinction matters for this job: which models accept two keyframes, and which accept a single image.
Two of them take a start frame and an end frame. dualkey_v2 costs 22.5 credits for 5 seconds, supports --duration 5|8|10|12, and scales up to 54 credits at 12 seconds. There is also dualkey_lite at a far cheaper 7.5 credits, but its quality is bad and I crossed it off during the early trials.
Those two price points get interesting when you divide them by duration. 22.5 divided by 5 is 4.5, and 54 divided by 12 is also 4.5. So across the recorded range the pricing is linear, 4.5 credits per second of output, with no discount for going long.
The rest accept a single image only: single_a, single_b, single_c, and single_turbo. For image editing there is edit_lite at 1.5 credits and edit_pro.
cost accepts a call shape that create rejects
The generate cost subcommand is free, so it is a natural first place to try out a call shape. The problem is that it is more permissive than the command that actually does the work.
# this passes and returns a credit estimate
C:\tmp\gencli\gencli.exe generate cost single_turbo --prompt "..." `
--start-image start.png --end-image end.png
# this is rejected, the model takes one image only
C:\tmp\gencli\gencli.exe generate create single_turbo --prompt "..." `
--start-image start.png --end-image end.pngFor single_turbo, the cost endpoint accepted a start plus end combination and quietly returned a number, while the real create rejected two images. Since then I flipped the rule: call shapes get validated through a real create, and cost is used only for what it actually promises, which is estimating credits.
The failure is attached to duration, not to content
This is the part I was really after when I started writing these notes down. For warm-palette content, 5-second generations pass, while 8, 10, and 12 seconds fail the NSFW moderation filter consistently. What makes the pattern legible is that the failures happen on the same content, not on different content. Same prompt, same start and end frames, only the --duration number changing.
The explanation I hold onto is still a guess, not something I can prove from the outside. The guess is that the moderation classifier works per frame, and that what trips it is warm or golden lighting combined with dark organic shapes on the underside, because shapes like that read as skin. An underside shot at sunset happens to be exactly that mixture.
If the check really is per frame, the rest becomes a question of how many dice you roll. The longer the duration, the more frames have to clear, and the higher the chance one of them gets caught. That matches what I saw, though matching is not the same as proven.
Two ways out
The obvious first route is changing the prompt. Asking for a cooler or daylight palette does clear moderation, and the longer generations get through. The price is that the mood changes, and for an asset whose entire value lives in dusk light, that is not a trade I wanted to make.
The second route, the one I ended up using, is to let the model work at a duration it is comfortable with and then lengthen the result myself. Generate at 5 seconds, then motion-interpolate to 10 seconds with ffmpeg.
ffmpeg -i clip-5s.mp4 \
-vf "minterpolate=fps=48:mi_mode=mci:...,setpts=2.0*PTS" \
clip-10s.mp4The command reads as arithmetic. The 5-second clip is first synthesized up to 48 frames per second, which gives 48 times 5, or 240 frames. Then setpts=2.0*PTS stretches the timestamps by a factor of two, so those same 240 frames now fill 10 seconds, or 24 frames per second. No frame is lost, only the playback speed changes, and the synthesized frames from mi_mode=mci fill in the motion gaps.
The warm mood survives intact because I never asked the model for a single pixel in a different palette. When I checked the result, the repeating linear detail on the structure stayed clean, which was the part I worried about most, since motion interpolation tends to smear on repeating patterns first.
Read through that per-second price, this route is also the cheapest. Five seconds is the shortest point recorded on the duration list, and at 4.5 credits per second it is the cheapest unit of output the filter actually lets through.
What I took away
- When moderation runs per frame, duration is the variable people are least likely to suspect. Raising the duration does not only add length, it adds checks that have to be cleared.
- Before blaming the prompt, hold every other variable still and move only the duration. The same content at 5 seconds and at 8 seconds separates the content question from the length question.
- A free estimation endpoint is under no obligation to run the same validation as the endpoint that executes. Validate call shapes with the real command.
- Motion interpolation in ffmpeg is a way to lengthen output without touching its palette, and that matters when the palette is the thing causing trouble.
- Linear per-second pricing means a long duration is never the cheaper option, so there is no economic argument for forcing a duration that fails easily anyway.