H3 Max Recast request rejected: every field Sume refuses
Sume refuses H3 Max Recast bodies with aspect_ratio, generate_audio, bitrate_mode, frame or audio references, or a duration outside 5-30 s. The full list.

If a Sume H3 Max Recast request fails before it starts, the cause is almost always one of the fields or values the model row refuses: a missing or non-public video_url, zero or more than four photos, resolution other than 768p or 1080p, a duration outside 5 to 30 seconds, a prompt over 2000 characters, or any of the frame, audio, aspect and bitrate fields that belong to other models.
The refusals come from Sume's request builder before the request goes to fal. That is the point of the narrow contract: Recast keeps the source video's framing, cuts and soundtrack, so there is nothing for an aspect ratio or an audio switch to control. fal's H3 Max Recast page (read 2026-10-02) lists a video, reference images and a 768p or 1080p output; Sume's Video Router docs add the 1 to 4 photo cap and the 5 to 30 second range.
Which fields are always refused?
The table groups what the request builder in the Sume API checks. The messages quoted are the ones the code raises, so you can match them in a client log.
A pattern worth noticing: most refusals are fields that are normal on other Sume video models. If you built a client around minimax-h3-max or seedance-2.5 and swapped only the model id, that is exactly how you will hit them.
| Field or value | Rule | Message theme |
|---|---|---|
| video_url missing, not https, localhost or with credentials | One public source URL required | requires one source video URL |
| reference_image_urls empty, more than 4, or a non-public URL | 1 to 4 photos, one per new person | requires 1-4 reference image URLs |
| resolution 480p, 720p, 2K | Only 768p (default) or 1080p | resolution must be 768p or 1080p |
| duration missing, under 5 or over 30 | Inspected source length, 5 to 30 s | requires the inspected source duration |
| prompt over 2000 characters | Optional, capped | prompt must be at most 2000 characters |
| aspect_ratio, generate_audio, bitrate_mode | Not supported | does not support <field> |
| image_url, first_frame_url, end_image_url, last_frame_url | Not supported | does not support <field> |
| reference_video_urls, reference_audio_urls | Not supported | does not support <field> |
Why is generate_audio refused instead of ignored?
Because the audio is the source's. Per fal's page the model preserves the source audio, and Sume's Video generation docs say h3-max-recast accepts video references but not audio. Silently accepting generate_audio: true would suggest a new soundtrack that never arrives, so the request fails instead.
The same logic covers aspect_ratio: the output follows the source frame. If you need a different shape, change the source first, then recast.
Why does duration trip people up?
On other models duration is what you want. On Recast it is a fact about the source, 5 to 30 seconds, used to price and reserve the job and never forwarded to fal. Sume's API reference also notes a shot rule: the person swap works on sources with no shot over 15 seconds, so a single unbroken 25 second take is within the duration range but outside that shot rule.
Probe the clip before you submit. Video inspect is unbilled for probe and stills, and it returns the facts that tell you the length and whether the clip has audio.
Can you check a body before you send it?
Yes, and it is cheap. This preflight mirrors the rules above and runs as is. It does not call Sume; it only tells you which rule a body would break, so a bad body never costs a round trip.
It cannot know whether your URLs are reachable or whether a clip has a shot over 15 seconds. Those need the inspect step.
BANNED = {"aspect_ratio", "generate_audio", "bitrate_mode", "image_url",
"first_frame_url", "end_image_url", "last_frame_url",
"reference_video_urls", "reference_audio_urls"}
def recast_problems(body):
out = [f"{k} is not supported" for k in BANNED if k in body]
if not str(body.get("video_url", "")).startswith("https://"):
out.append("video_url must be public https")
photos = body.get("reference_image_urls") or []
if not 1 <= len(photos) <= 4:
out.append("1 to 4 reference_image_urls")
if body.get("resolution", "768p") not in ("768p", "1080p"):
out.append("resolution must be 768p or 1080p")
d = body.get("duration")
if not isinstance(d, (int, float)) or not 5 <= d <= 30:
out.append("duration must be 5 to 30")
if len((body.get("prompt") or "").strip()) > 2000:
out.append("prompt over 2000 characters")
return out
print(recast_problems({"video_url": "https://a.test/v.mp4", "duration": 4,
"aspect_ratio": "16:9"}))How should a client guard against these?
Build the Recast body from a small allowlist rather than copying a generic video body. Keep exactly model, video_url, reference_image_urls, duration, resolution, optional prompt, plus the communication fields (mode, Idempotency-Key). Everything else goes through a different model row.
If a refusal still appears, read the message first: each one names the field. Do not retry the same body; a refused request will be refused again. Once the body is clean, submit async and follow the jobs flow in Jobs and results. The prompt post covers the one field that is optional.
Sources
Related posts
More in Developers
- Hedra legacy avatar API needs 4 calls; Sume avatar video needs 1 POST
Hedra's legacy avatar guide creates and uploads two assets, then generates and polls. Sume's talking-video route is one POST with a handle and a script.
- HeyGen bulk status for 100 videos at once vs Sume job webhooks
HeyGen added bulk status reads of up to 100 ids for videos, lipsyncs, translations and assets. Sume reads jobs one by one or pushes signed terminal webhooks.
- HeyGen POST /v3/templates makes a template from video; Sume has none
HeyGen's October API entry turns a video into a private template. Sume has no template object for avatar video: you keep the request JSON and avatar handle.
- HeyGen lipsync batches of 100 vs Sume Fabric one clip per job
HeyGen added POST /v3/lipsyncs/batches. Sume's talking-still route, VEED Fabric 1.0, has no batch route: you submit one job per clip with idempotency keys.
Written by Sume