Skip to main content
Glama
Hermoso

Hermoso

Official

Generate video

generate_video

Render a continuous MP4 video clip from a text description, image, or source video, with optional voiceover, music, and multi-shot output for ads, b-roll, or social content.

Instructions

Use this when the user asks for a video clip, b-roll or a shot from a description, or names a video model. For a finished video ad, Reel, TikTok ad or UGC video for their business, use render_ad. It renders one continuous clip on a real video model and returns its mp4 URL. A clip runs up to the model’s longest listed duration (the longest takes a multi-beat 30s spot in ONE take with native audio), so never assume an 8–10s cap or stitch what fits one clip; durationSeconds must be one of the model’s durations in hermoso_capabilities. NAME A MODEL in model to get it: an unnamed render uses a narrower auto-pool. 1–3 min. refImage anchors the first frame; ttsScript adds a voiceover. AUDIO IS NOT FREE BY DEFAULT: a clip with no audio of its own gets a music bed composed and CHARGED on top (see musicMood and audio), which can cost as much as a cheap draft clip. refVideo (a clip URL) EDITS that clip instead, keeping its canvas and length. RAW MODEL ACCESS: by default small guards are added (label safety with no reference image, a negative prompt where the model takes one, reference lines) and hex colours become names; raw:true dispatches your prompt to the model BYTE-IDENTICAL — no rewriting, no appended guidance, no negative prompt, no brand references attached on your behalf. Credits, the durable delivery of the finished asset and the per-model validation are unchanged. Spends credits (blocked on the Starter plan).

Input Schema

NameRequiredDescriptionDefault
rawNoSend the prompt to the model exactly as written, without the wording Hermoso usually adds (packaging and label guidance, reference lines, colour names for hex codes, quality hints). Use it when you want the model's own interpretation rather than Hermoso's render craft. Two vendor-required fixes still apply: extra @ImageN tokens are dropped and an over-long prompt is trimmed at a sentence (on Veo it is refused with the length and the cap instead). Billing, durable delivery and per-model validation are unchanged.
loopNotrue = a seamless loop whose last frame flows back into its first. Only models with loop true in hermoso_capabilities; needs refImage and cannot be combined with endImage.
audioNodefault true. false = render SILENT: no native model audio, no music bed, and no bed charge held or billed. This is the ONLY way to decline the automatic bed (see musicMood) — leave it alone for anything that should have sound, and do not combine it with ttsScript.
modelNovideo model id from hermoso_capabilities; a named model is never swapped without asking. Omit to let the router pick; its default per job (jobEngines in hermoso_capabilities, from watched side-by-side tests) is seedance-2.5 for product, lifestyle, a person talking to camera and 30s single takes (cheaper engines broke the product there). A model the user picks is kept; never switch it
shotsNoMULTI-SHOT: one clip cut into these shots, in order; the seconds add up to a length the model renders. Replaces `prompt`. Only models with multiShot true in hermoso_capabilities; a shot prompt over that model’s shotPromptMaxChars (Kling 3.0: 512) is refused free, never cut.
speakNoA PERSON SAYING THESE EXACT WORDS TO CAMERA — the default for any "make my photo talk" / spokesperson / talk-to-camera ask. Pass with `creator` or a portrait as `refImage`: the video model films them saying it in their own voice, matched to who they are, and the length follows the words (leave durationSeconds out). `prompt` is then the staging (e.g. "natural", "walking in a park"). Real footage, not an animated photo; generate_avatar is the animated-photo look, only when asked for by name
anglesNoOPTIONAL, OFF BY DEFAULT: with `creator`, also send the extra views that creator already has saved (their pose plates, up to 2) beside their portrait. A test showed no visible improvement over the portrait alone, and each extra view adds about 25 s before the render starts, so leave it off unless asked. Views are skipped when the face library is busy, and the render always goes ahead on the portrait.
dryRunNotrue = render NOTHING and return the credits this exact clip would hold (an estimate; the final charge is its actual cost). Free. Call this to price a clip before running it: without it the call renders and bills.
extendNotrue = EXTEND refVideo by durationSeconds (default 5) with what your prompt says happens next, as ONE clip. By default it CUTS to a NEW SHOT: new angle, same scene, room sound carried, no music at the cut. A named model (any i2v) renders it.
promptNothe video prompt / shot description (for a refVideo edit, this is the transformation instruction); optional with `shots`
creatorNoSTAR A SAVED CREATOR in this clip — their id from list_creators, or the name you know them by, or a PRESET AI creator from list_creators presets (exact name or id; free, no generation). Their saved portrait rides first among the references as the on-camera person, with their saved consent, exactly as render_ad casts them; a real person saved from a photo keeps their real face on camera. An unknown name is refused by name, nothing charged.
endImageNolocal path or URL of the LAST frame: the clip travels from refImage (required with it) to this image. Only models with endFrame true in hermoso_capabilities take it; any other named model is refused by name, nothing charged.
refImageNolocal path or URL to anchor the first frame. Using a real person’s face, likeness or voice confirms you are them or have their consent, take full, unlimited responsibility for its use and will cover any claim against Hermoso (hermoso.ai/terms). Paid plan only; recorded.
refVideoNoURL of an existing video to EDIT rather than generate from scratch — the clip is transformed per your prompt, keeping the SOURCE clip’s aspect ratio and, on models hermoso_capabilities marks `sourceLength`, its LENGTH (their `durations` are the per-second price ladder; a durationSeconds sent is reported as unused). Trim the source to change the length. Omit `model` for the default editor, or name a model whose videoEdit is true in hermoso_capabilities (a named model that cannot edit is refused, nothing charged); refImage rides along as the look of what the edit adds. With extend:true this is instead the clip to EXTEND. Omit to generate a fresh clip.
ttsVoiceNovoice name, e.g. Rachel / George
faceRouteNo'face_lane' records the user's statement "I own the rights to this face" for the real person in their reference (paid plans; the likeness terms apply). Set it only when the user picked that option after a render said it could not use that face, and send the same request again; it then renders through Hermoso's face library at the normal price. Never set it on your own. The other options are a different `model` or one of the user's saved `creator`s.
musicMoodNothe mood of the music bed (upbeat / calm / warm / epic / tense / playful / elegant / hype / chill / dramatic; default warm). It does not decide WHETHER there is one: a clip with no audio track (a "silent" model in hermoso_capabilities, or one that came back mute) gets a bed composed and CHARGED automatically at explainerMusicCredits. audio:false = silent, no bed, no charge.
refImagesNoSEVERAL reference images (paths or URLs: a person, products, a place) that must all appear. A model uses up to its `refs.max` in hermoso_capabilities (one-image models take the first); with `refs.promptAddressed`, name them Image 1, Image 2… in order. minimax-h3-max-ref takes 9 and keeps each as a reference, not a first frame.
ttsScriptNovoiceover script to speak
cameraMoveNoA named camera move around the still in refImage (orbit = a quarter turn, the default; orbit_half / orbit_full = a half turn / a turntable). Only minimax-h3-max-camera renders one: with model omitted it is picked; any other named model is refused, nothing charged. Needs refImage.
extendModeNowith extend: 'continue' = the SAME take past its last frame, only when asked seamless (models with extend in hermoso_capabilities).
musicModelNocompose the bed on minimax-music-3 or lyria-3.5, skipping the free library
resolutionNo'1080p' default; '480p'/'720p' cheaper drafts, '4k' premium (more credits). A model renders only the tiers in its own `resolutions` list in hermoso_capabilities; a tier it lacks renders at its best one without a word, so check before promising 1080p or 4k.
aspectRatioNodefault '9:16'
interactionIdNowith extend:true on an Omni model: the interactionId returned by an earlier render on that model — continues it from its own stored context instead of re-uploading refVideo.
durationSecondsNolength of THIS ONE clip in seconds: one of the CHOSEN model’s listed durations in hermoso_capabilities (they differ per model, 4–8s on the short ones up to 30s). One continuous generation, so a longer ask than the model’s longest clip is REFUSED, nothing charged (never quietly truncated). Past ~15s NAME a long-clip model in `model`. For a longer spot use plan_ad with durationSeconds then render_ad, which stitches acts (on a 15s model, 40s = 15+15+10).
cameraTrajectoryNoYour own ordered camera path, 2 to 12 keyframes, for the camera-controls model only (same rule as cameraMove; overrides it). The first pose is held until its time and the last pose is held to the end. A value outside these bounds is refused by name, nothing charged.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changedv0.1.489
    • addedInput schema / properties / musicModel
      Added value: +{
      +  "description": "compose the bed on minimax-music-3 or lyria-3.5, skipping the free library",
      +  "type": "string"
      +}
  2. Changed1 schema field changedv0.1.484
    • addedInput schema / properties / dryRun
      Added value: +{
      +  "description": "true = render NOTHING and return the credits this exact clip would hold (an estimate; the final charge is its actual cost). Free. Call this to price a clip before running it: without it the call renders and bills.",
      +  "type": "boolean"
      +}
  3. Changed10 schema fields changedv0.1.435
    • changedInput schema / properties / cameraMove / description
      Previous value: -"A named camera move around the still in refImage, spelled exactly as the enum gives it: an orbit (a quarter turn, the default), orbiting left, a half turn or a full turntable, a rise, a crane up, a push in, a pull back, or a reveal. Only the camera-controls model renders one (minimax-h3-max-camera, listed with its moves in hermoso_capabilities): pass it with model omitted and that model is picked, or with that model named; any other named model is refused by name with nothing charged. Needs refImage."New value: +"A named camera move around the still in refImage (orbit = a quarter turn, the default; orbit_half / orbit_full = a half turn / a turntable). Only minimax-h3-max-camera renders one: with model omitted it is picked; any other named model is refused, nothing charged. Needs refImage."
    • changedInput schema / properties / durationSeconds / description
      Previous value: -"length of THIS ONE clip in seconds — pick one of the CHOSEN model’s listed durations from hermoso_capabilities (never a generic guess: the lists differ per model, from 4–8s on the short models up to 30s on the longest-clip one). This is a single continuous generation, so it CANNOT exceed that model’s longest clip: a longer ask is REFUSED with nothing rendered and nothing charged (it is never quietly truncated). Past ~15s only the long-clip models qualify, and an unnamed render is routed by the narrower auto-pool — so NAME the model in `model` when you are asking for a long single take. For a spot longer than any one clip, use plan_ad with durationSeconds then render_ad, which stitches acts of at most one model clip each (on a 15s-clip model, 40s = 15+15+10)."New value: +"length of THIS ONE clip in seconds: one of the CHOSEN model’s listed durations in hermoso_capabilities (they differ per model, 4–8s on the short ones up to 30s). One continuous generation, so a longer ask than the model’s longest clip is REFUSED, nothing charged (never quietly truncated). Past ~15s NAME a long-clip model in `model`. For a longer spot use plan_ad with durationSeconds then render_ad, which stitches acts (on a 15s model, 40s = 15+15+10)."
    • changedInput schema / properties / extend / description
      Previous value: -"true = EXTEND refVideo: the same clip continues per your prompt for durationSeconds more (each model’s extend.minSeconds..maxSeconds in hermoso_capabilities), delivered as ONE clip, source then continuation. Needs model named (a model with extend in hermoso_capabilities)."New value: +"true = EXTEND refVideo by durationSeconds (default 5) with what your prompt says happens next, as ONE clip. By default it CUTS to a NEW SHOT: new angle, same scene, room sound carried, no music at the cut. A named model (any i2v) renders it."
    • addedInput schema / properties / extendMode
      Added value: +{
      +  "description": "with extend: 'continue' = the SAME take past its last frame, only when asked seamless (models with extend in hermoso_capabilities).",
      +  "enum": [
      +    "cut",
      +    "continue"
      +  ],
      +  "type": "string"
      +}
    • changedInput schema / properties / model / description
      Previous value: -"video model id from hermoso_capabilities; a named model is never swapped without asking. Omit to let the router pick"New value: +"video model id from hermoso_capabilities; a named model is never swapped without asking. Omit to let the router pick; its default per job (jobEngines in hermoso_capabilities, from watched side-by-side tests) is seedance-2.5 for product, lifestyle, a person talking to camera and 30s single takes (cheaper engines broke the product there). A model the user picks is kept; never switch it"
    • changedInput schema / properties / musicMood / description
      Previous value: -"WHICH mood the music bed is composed in (upbeat / calm / warm / epic / tense / playful / elegant / hype / chill / dramatic). It does NOT decide WHETHER there is one: a clip that comes back with no audio track — every model hermoso_capabilities lists as \"silent\", plus any audio model that returned mute — gets a bed composed and CHARGED automatically, at the flat per-track fee hermoso_capabilities reports as explainerMusicCredits, and omitting this field only means the mood defaults to \"warm\". Pass audio:false for a genuinely silent clip with no bed and no bed charge."New value: +"the mood of the music bed (upbeat / calm / warm / epic / tense / playful / elegant / hype / chill / dramatic; default warm). It does not decide WHETHER there is one: a clip with no audio track (a \"silent\" model in hermoso_capabilities, or one that came back mute) gets a bed composed and CHARGED automatically at explainerMusicCredits. audio:false = silent, no bed, no charge."
    • changedInput schema / properties / refImages / description
      Previous value: -"SEVERAL reference images (local paths or URLs) — a person, products, a place — that must all appear in the clip. Only models whose `refs.max` in hermoso_capabilities is above 1 use more than one, and each uses at most that many; with `refs.promptAddressed` true, name them in your prompt as Image 1, Image 2… in this order. minimax-h3-max-ref takes up to 9 and keeps each one as a reference rather than a first frame. On a model that takes one image, only the first is used."New value: +"SEVERAL reference images (paths or URLs: a person, products, a place) that must all appear. A model uses up to its `refs.max` in hermoso_capabilities (one-image models take the first); with `refs.promptAddressed`, name them Image 1, Image 2… in order. minimax-h3-max-ref takes 9 and keeps each as a reference, not a first frame."
    • changedInput schema / properties / refVideo / description
      Previous value: -"URL of an existing video to EDIT rather than generate from scratch — the clip is transformed per your prompt, inheriting the SOURCE clip’s canvas (aspect ratio) and, on every model hermoso_capabilities marks `sourceLength`, its LENGTH too: those endpoints have no duration parameter, their listed `durations` are the per-second price ladder, and a durationSeconds you send is reported back as unused rather than silently dropped. Trim the source to change the length. Omit `model` for the default editor, or name a model whose videoEdit is true in hermoso_capabilities (a named model that cannot edit is refused, nothing charged); refImage rides along as the look of what the edit adds. With extend:true this is instead the clip to EXTEND. Omit to generate a fresh clip."New value: +"URL of an existing video to EDIT rather than generate from scratch — the clip is transformed per your prompt, keeping the SOURCE clip’s aspect ratio and, on models hermoso_capabilities marks `sourceLength`, its LENGTH (their `durations` are the per-second price ladder; a durationSeconds sent is reported as unused). Trim the source to change the length. Omit `model` for the default editor, or name a model whose videoEdit is true in hermoso_capabilities (a named model that cannot edit is refused, nothing charged); refImage rides along as the look of what the edit adds. With extend:true this is instead the clip to EXTEND. Omit to generate a fresh clip."
    • changedInput schema / properties / resolution / description
      Previous value: -"'1080p' default (what we ship and bill for); '480p'/'720p' = cheaper draft passes, '4k' = premium final delivery (more credits). NOT EVERY MODEL OFFERS EVERY TIER — this enum is what the tool accepts, and each model's OWN `resolutions` list in hermoso_capabilities is what it can actually render. Ask for a tier the chosen model does not list and it is rendered at that model's best available tier instead, with nothing in the reply saying so — so check `resolutions` before promising anyone 1080p or 4k."New value: +"'1080p' default; '480p'/'720p' cheaper drafts, '4k' premium (more credits). A model renders only the tiers in its own `resolutions` list in hermoso_capabilities; a tier it lacks renders at its best one without a word, so check before promising 1080p or 4k."
    • changedInput schema / properties / shots / description
      Previous value: -"MULTI-SHOT: one clip cut into these shots, in order. The seconds must add up to a length the model renders; replaces `prompt` (send either). Only models with multiShot true in hermoso_capabilities. Each shot prompt is capped per model (shotPromptMaxChars there; Kling 3.0: 512 characters); a longer one is refused free, never cut."New value: +"MULTI-SHOT: one clip cut into these shots, in order; the seconds add up to a length the model renders. Replaces `prompt`. Only models with multiShot true in hermoso_capabilities; a shot prompt over that model’s shotPromptMaxChars (Kling 3.0: 512) is refused free, never cut."
  4. Changed2 schema fields changedv0.1.410
    • changedInput schema / properties / faceRoute / description
      Previous value: -"ONLY after a render came back saying the video model's safety check flagged a person's face: 'face_lane' is the user's choice \"I own the rights to this face\". Send the SAME request again with it and the same face is rendered on Seedance through the face library, at the normal price. Sending it is the user's confirmation that they have the rights to that face (paid plans, like every real face). Never set it on your own; the other choices that refusal names are a different model (`model`) or another creator (`creator`)."New value: +"'face_lane' records the user's statement \"I own the rights to this face\" for the real person in their reference (paid plans; the likeness terms apply). Set it only when the user picked that option after a render said it could not use that face, and send the same request again; it then renders through Hermoso's face library at the normal price. Never set it on your own. The other options are a different `model` or one of the user's saved `creator`s."
    • changedInput schema / properties / raw / description
      Previous value: -"RAW MODEL ACCESS: dispatch this prompt to the model BYTE-IDENTICAL — no appended packaging/label guidance, no negative prompt, no reference-binding lines, no hex-to-colour-name rewrite. Use it when you want the model itself rather than Hermoso's render craft. Two vendor-required fixes still apply: extra @ImageN tokens are dropped and an over-long prompt is trimmed at a sentence (on Veo it is refused with the length and the cap instead). Billing, durable delivery and per-model validation are unchanged."New value: +"Send the prompt to the model exactly as written, without the wording Hermoso usually adds (packaging and label guidance, reference lines, colour names for hex codes, quality hints). Use it when you want the model's own interpretation rather than Hermoso's render craft. Two vendor-required fixes still apply: extra @ImageN tokens are dropped and an over-long prompt is trimmed at a sentence (on Veo it is refused with the length and the cap instead). Billing, durable delivery and per-model validation are unchanged."
  5. Changed4 schema fields changedv0.1.398
    • changedInput schema / properties / prompt / description
      Previous value: -"the video prompt / shot description (for a refVideo edit, this is the transformation instruction)"New value: +"the video prompt / shot description (for a refVideo edit, this is the transformation instruction); optional with `shots`"
    • changedInput schema / properties / raw / description
      Previous value: -"RAW MODEL ACCESS: dispatch this prompt to the model BYTE-IDENTICAL — no appended packaging/label guidance, no negative prompt, no reference-binding lines, no hex-to-colour-name rewrite. Use it when you want the model itself rather than Hermoso's render craft. Two vendor-required fixes still apply: extra @ImageN tokens are dropped and an over-long prompt is trimmed at a sentence. Billing, durable delivery and per-model validation are unchanged."New value: +"RAW MODEL ACCESS: dispatch this prompt to the model BYTE-IDENTICAL — no appended packaging/label guidance, no negative prompt, no reference-binding lines, no hex-to-colour-name rewrite. Use it when you want the model itself rather than Hermoso's render craft. Two vendor-required fixes still apply: extra @ImageN tokens are dropped and an over-long prompt is trimmed at a sentence (on Veo it is refused with the length and the cap instead). Billing, durable delivery and per-model validation are unchanged."
    • changedInput schema / properties / shots / description
      Previous value: -"MULTI-SHOT: one clip cut into these shots, in order. The seconds must add up to a length the model renders; replaces `prompt` (send either). Only models with multiShot true in hermoso_capabilities."New value: +"MULTI-SHOT: one clip cut into these shots, in order. The seconds must add up to a length the model renders; replaces `prompt` (send either). Only models with multiShot true in hermoso_capabilities. Each shot prompt is capped per model (shotPromptMaxChars there; Kling 3.0: 512 characters); a longer one is refused free, never cut."
    • removedInput schema / required
      Removed value: -[
      -  "prompt"
      -]
  6. Changed5 schema fields changedv0.1.366
    • addedInput schema / properties / angles
      Added value: +{
      +  "description": "OPTIONAL, OFF BY DEFAULT: with `creator`, also send the extra views that creator already has saved (their pose plates, up to 2) beside their portrait. A test showed no visible improvement over the portrait alone, and each extra view adds about 25 s before the render starts, so leave it off unless asked. Views are skipped when the face library is busy, and the render always goes ahead on the portrait.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / creator
      Added value: +{
      +  "description": "STAR A SAVED CREATOR in this clip — their id from list_creators, or the name you know them by, or a PRESET AI creator from list_creators presets (exact name or id; free, no generation). Their saved portrait rides first among the references as the on-camera person, with their saved consent, exactly as render_ad casts them; a real person saved from a photo keeps their real face on camera. An unknown name is refused by name, nothing charged.",
      +  "type": "string"
      +}
    • addedInput schema / properties / faceRoute
      Added value: +{
      +  "description": "ONLY after a render came back saying the video model's safety check flagged a person's face: 'face_lane' is the user's choice \"I own the rights to this face\". Send the SAME request again with it and the same face is rendered on Seedance through the face library, at the normal price. Sending it is the user's confirmation that they have the rights to that face (paid plans, like every real face). Never set it on your own; the other choices that refusal names are a different model (`model`) or another creator (`creator`).",
      +  "enum": [
      +    "face_lane"
      +  ],
      +  "type": "string"
      +}
    • changedInput schema / properties / refImage / description
      Previous value: -"local path or URL to anchor the first frame; a real person’s photo here or in refImages confirms their likeness consent"New value: +"local path or URL to anchor the first frame. Using a real person’s face, likeness or voice confirms you are them or have their consent, take full, unlimited responsibility for its use and will cover any claim against Hermoso (hermoso.ai/terms). Paid plan only; recorded."
    • addedInput schema / properties / speak
      Added value: +{
      +  "description": "A PERSON SAYING THESE EXACT WORDS TO CAMERA — the default for any \"make my photo talk\" / spokesperson / talk-to-camera ask. Pass with `creator` or a portrait as `refImage`: the video model films them saying it in their own voice, matched to who they are, and the length follows the words (leave durationSeconds out). `prompt` is then the staging (e.g. \"natural\", \"walking in a park\"). Real footage, not an animated photo; generate_avatar is the animated-photo look, only when asked for by name",
      +  "type": "string"
      +}
  7. Changed1 schema field changedv0.1.285
    • changedInput schema / properties / refImage / description
      Previous value: -"local path or URL to anchor the first frame"New value: +"local path or URL to anchor the first frame; a real person’s photo here or in refImages confirms their likeness consent"
  8. Changed2 schema fields changedv0.1.256
    • addedInput schema / properties / refImages
      Added value: +{
      +  "description": "SEVERAL reference images (local paths or URLs) — a person, products, a place — that must all appear in the clip. Only models whose `refs.max` in hermoso_capabilities is above 1 use more than one, and each uses at most that many; with `refs.promptAddressed` true, name them in your prompt as Image 1, Image 2… in this order. minimax-h3-max-ref takes up to 9 and keeps each one as a reference rather than a first frame. On a model that takes one image, only the first is used.",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • changedInput schema / properties / refVideo / description
      Previous value: -"URL of an existing video to EDIT rather than generate from scratch — the clip is transformed per your prompt, inheriting the SOURCE clip’s canvas (aspect ratio) and length (aspectRatio/durationSeconds are ignored for an edit). Omit `model` for the default editor, or name a model whose videoEdit is true in hermoso_capabilities (a named model that cannot edit is refused, nothing charged); refImage rides along as the look of what the edit adds. With extend:true this is instead the clip to EXTEND. Omit to generate a fresh clip."New value: +"URL of an existing video to EDIT rather than generate from scratch — the clip is transformed per your prompt, inheriting the SOURCE clip’s canvas (aspect ratio) and, on every model hermoso_capabilities marks `sourceLength`, its LENGTH too: those endpoints have no duration parameter, their listed `durations` are the per-second price ladder, and a durationSeconds you send is reported back as unused rather than silently dropped. Trim the source to change the length. Omit `model` for the default editor, or name a model whose videoEdit is true in hermoso_capabilities (a named model that cannot edit is refused, nothing charged); refImage rides along as the look of what the edit adds. With extend:true this is instead the clip to EXTEND. Omit to generate a fresh clip."
  9. Changed7 schema fields changedv0.1.251
    • changedInput schema / properties / cameraMove / description
      Previous value: -"A named camera move around the still in refImage — orbit (quarter turn, the default), orbit_left, orbit_half, orbit_full (turntable), rise, crane_up, push_in, pull_back, reveal. Only the camera-controls model renders one (minimax-h3-max-camera, listed with its moves in hermoso_capabilities): pass it with model omitted and that model is picked, or with that model named; any other named model is refused by name with nothing charged. Needs refImage."New value: +"A named camera move around the still in refImage, spelled exactly as the enum gives it: an orbit (a quarter turn, the default), orbiting left, a half turn or a full turntable, a rise, a crane up, a push in, a pull back, or a reveal. Only the camera-controls model renders one (minimax-h3-max-camera, listed with its moves in hermoso_capabilities): pass it with model omitted and that model is picked, or with that model named; any other named model is refused by name with nothing charged. Needs refImage."
    • addedInput schema / properties / endImage
      Added value: +{
      +  "description": "local path or URL of the LAST frame: the clip travels from refImage (required with it) to this image. Only models with endFrame true in hermoso_capabilities take it; any other named model is refused by name, nothing charged.",
      +  "type": "string"
      +}
    • addedInput schema / properties / extend
      Added value: +{
      +  "description": "true = EXTEND refVideo: the same clip continues per your prompt for durationSeconds more (each model’s extend.minSeconds..maxSeconds in hermoso_capabilities), delivered as ONE clip, source then continuation. Needs model named (a model with extend in hermoso_capabilities).",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / interactionId
      Added value: +{
      +  "description": "with extend:true on an Omni model: the interactionId returned by an earlier render on that model — continues it from its own stored context instead of re-uploading refVideo.",
      +  "type": "string"
      +}
    • addedInput schema / properties / loop
      Added value: +{
      +  "description": "true = a seamless loop whose last frame flows back into its first. Only models with loop true in hermoso_capabilities; needs refImage and cannot be combined with endImage.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / refVideo / description
      Previous value: -"URL of an existing video to EDIT rather than generate from scratch — the omni engine accepts a raw clip and transforms it per your prompt, inheriting the SOURCE clip’s canvas (aspect ratio) and length (aspectRatio/durationSeconds are ignored for an edit). Omit to generate a fresh clip."New value: +"URL of an existing video to EDIT rather than generate from scratch — the clip is transformed per your prompt, inheriting the SOURCE clip’s canvas (aspect ratio) and length (aspectRatio/durationSeconds are ignored for an edit). Omit `model` for the default editor, or name a model whose videoEdit is true in hermoso_capabilities (a named model that cannot edit is refused, nothing charged); refImage rides along as the look of what the edit adds. With extend:true this is instead the clip to EXTEND. Omit to generate a fresh clip."
    • addedInput schema / properties / shots
      Added value: +{
      +  "description": "MULTI-SHOT: one clip cut into these shots, in order. The seconds must add up to a length the model renders; replaces `prompt` (send either). Only models with multiShot true in hermoso_capabilities.",
      +  "items": {
      +    "properties": {
      +      "prompt": {
      +        "description": "what happens in this shot",
      +        "type": "string"
      +      },
      +      "seconds": {
      +        "description": "this shot’s length in whole seconds",
      +        "maximum": 15,
      +        "minimum": 1,
      +        "type": "integer"
      +      }
      +    },
      +    "required": [
      +      "prompt",
      +      "seconds"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
  10. Changed3 schema fields changedv0.1.243
    • changedInput schema / properties / cameraMove / description
      Previous value: -"H3 Max Multi Angle only: camera move (default orbit)"New value: +"A named camera move around the still in refImage — orbit (quarter turn, the default), orbit_left, orbit_half, orbit_full (turntable), rise, crane_up, push_in, pull_back, reveal. Only the camera-controls model renders one (minimax-h3-max-camera, listed with its moves in hermoso_capabilities): pass it with model omitted and that model is picked, or with that model named; any other named model is refused by name with nothing charged. Needs refImage."
    • changedInput schema / properties / cameraMove / enum
      Previous value: -[
      -  "orbit",
      -  "orbit_half",
      -  "orbit_full",
      -  "rise",
      -  "push_in",
      -  "pull_back"
      -]New value: +[
      +  "orbit",
      +  "orbit_left",
      +  "orbit_half",
      +  "orbit_full",
      +  "rise",
      +  "crane_up",
      +  "push_in",
      +  "pull_back",
      +  "reveal"
      +]
    • addedInput schema / properties / cameraTrajectory
      Added value: +{
      +  "description": "Your own ordered camera path, 2 to 12 keyframes, for the camera-controls model only (same rule as cameraMove; overrides it). The first pose is held until its time and the last pose is held to the end. A value outside these bounds is refused by name, nothing charged.",
      +  "items": {
      +    "properties": {
      +      "azimuth": {
      +        "description": "horizontal angle around the subject in degrees (0 = where the still was taken; the sign turns the camera the other way; at most 32 full turns of total travel)",
      +        "type": "number"
      +      },
      +      "distance": {
      +        "description": "distance from the subject in scene units, 1 = the distance of the still; smaller is closer",
      +        "exclusiveMinimum": 0,
      +        "type": "number"
      +      },
      +      "elevation": {
      +        "description": "vertical angle in degrees, -90 (below) to 90 (straight above)",
      +        "maximum": 90,
      +        "minimum": -90,
      +        "type": "number"
      +      },
      +      "time": {
      +        "description": "when this pose is reached, 0 = start of the clip, 1 = end",
      +        "maximum": 1,
      +        "minimum": 0,
      +        "type": "number"
      +      }
      +    },
      +    "required": [
      +      "time",
      +      "azimuth",
      +      "elevation",
      +      "distance"
      +    ],
      +    "type": "object"
      +  },
      +  "maxItems": 12,
      +  "minItems": 2,
      +  "type": "array"
      +}
  11. Changed4 schema fields changedv0.1.230
    • addedInput schema / properties / cameraMove
      Added value: +{
      +  "description": "H3 Max Multi Angle only: camera move (default orbit)",
      +  "enum": [
      +    "orbit",
      +    "orbit_half",
      +    "orbit_full",
      +    "rise",
      +    "push_in",
      +    "pull_back"
      +  ],
      +  "type": "string"
      +}
    • changedInput schema / properties / model / description
      Previous value: -"video model id from hermoso_capabilities. Naming one is a DELIBERATE pick — the server asks before ever swapping it (no silent fallback); omit it to let the router pick"New value: +"video model id from hermoso_capabilities; a named model is never swapped without asking. Omit to let the router pick"
    • changedInput schema / properties / raw / description
      Previous value: -"RAW MODEL ACCESS: dispatch this prompt to the model BYTE-IDENTICAL — no appended packaging/label guidance, no negative prompt, no reference-binding lines, no hex-to-colour-name rewrite. Use it when you want the model itself rather than Hermoso's render craft. Two provider-mandated corrections still apply, because the vendor hard-fails without them: an @ImageN token that outnumbers the references actually shipped is dropped, and a prompt past the endpoint's published character cap is trimmed at a sentence boundary. Billing, durable delivery and per-model validation are unchanged."New value: +"RAW MODEL ACCESS: dispatch this prompt to the model BYTE-IDENTICAL — no appended packaging/label guidance, no negative prompt, no reference-binding lines, no hex-to-colour-name rewrite. Use it when you want the model itself rather than Hermoso's render craft. Two vendor-required fixes still apply: extra @ImageN tokens are dropped and an over-long prompt is trimmed at a sentence. Billing, durable delivery and per-model validation are unchanged."
    • changedInput schema / properties / resolution / description
      Previous value: -"'1080p' default (what we ship and bill for); '480p'/'720p' = cheaper draft passes, '4k' = premium final delivery (more credits). NOT EVERY MODEL OFFERS EVERY TIER — this enum is what the tool accepts, and each model's OWN `resolutions` list in hermoso_capabilities is what it can actually render (the longest-clip 30s model, for one, tops out at 720p). Ask for a tier the chosen model does not list and it is rendered at that model's best available tier instead, with nothing in the reply saying so — so check `resolutions` before promising anyone 1080p or 4k."New value: +"'1080p' default (what we ship and bill for); '480p'/'720p' = cheaper draft passes, '4k' = premium final delivery (more credits). NOT EVERY MODEL OFFERS EVERY TIER — this enum is what the tool accepts, and each model's OWN `resolutions` list in hermoso_capabilities is what it can actually render. Ask for a tier the chosen model does not list and it is rendered at that model's best available tier instead, with nothing in the reply saying so — so check `resolutions` before promising anyone 1080p or 4k."
  12. Changed6 schema fields changedv0.1.161
    • addedInput schema / properties / audio
      Added value: +{
      +  "description": "default true. false = render SILENT: no native model audio, no music bed, and no bed charge held or billed. This is the ONLY way to decline the automatic bed (see musicMood) — leave it alone for anything that should have sound, and do not combine it with ttsScript.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / durationSeconds / description
      Previous value: -"clip length in seconds"New value: +"length of THIS ONE clip in seconds — pick one of the CHOSEN model’s listed durations from hermoso_capabilities (never a generic guess: the lists differ per model, from 4–8s on the short models up to 30s on the longest-clip one). This is a single continuous generation, so it CANNOT exceed that model’s longest clip: a longer ask is REFUSED with nothing rendered and nothing charged (it is never quietly truncated). Past ~15s only the long-clip models qualify, and an unnamed render is routed by the narrower auto-pool — so NAME the model in `model` when you are asking for a long single take. For a spot longer than any one clip, use plan_ad with durationSeconds then render_ad, which stitches acts of at most one model clip each (on a 15s-clip model, 40s = 15+15+10)."
    • changedInput schema / properties / musicMood / description
      Previous value: -"licensed music-bed mood (e.g. upbeat / cinematic) — omit for no music bed"New value: +"WHICH mood the music bed is composed in (upbeat / calm / warm / epic / tense / playful / elegant / hype / chill / dramatic). It does NOT decide WHETHER there is one: a clip that comes back with no audio track — every model hermoso_capabilities lists as \"silent\", plus any audio model that returned mute — gets a bed composed and CHARGED automatically, at the flat per-track fee hermoso_capabilities reports as explainerMusicCredits, and omitting this field only means the mood defaults to \"warm\". Pass audio:false for a genuinely silent clip with no bed and no bed charge."
    • addedInput schema / properties / raw
      Added value: +{
      +  "description": "RAW MODEL ACCESS: dispatch this prompt to the model BYTE-IDENTICAL — no appended packaging/label guidance, no negative prompt, no reference-binding lines, no hex-to-colour-name rewrite. Use it when you want the model itself rather than Hermoso's render craft. Two provider-mandated corrections still apply, because the vendor hard-fails without them: an @ImageN token that outnumbers the references actually shipped is dropped, and a prompt past the endpoint's published character cap is trimmed at a sentence boundary. Billing, durable delivery and per-model validation are unchanged.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / resolution / description
      Previous value: -"'720p' default; '480p' = cheap fast draft pass, '1080p'/'4k' = premium final delivery (more credits)"New value: +"'1080p' default (what we ship and bill for); '480p'/'720p' = cheaper draft passes, '4k' = premium final delivery (more credits). NOT EVERY MODEL OFFERS EVERY TIER — this enum is what the tool accepts, and each model's OWN `resolutions` list in hermoso_capabilities is what it can actually render (the longest-clip 30s model, for one, tops out at 720p). Ask for a tier the chosen model does not list and it is rendered at that model's best available tier instead, with nothing in the reply saying so — so check `resolutions` before promising anyone 1080p or 4k."
    • changedOutput schema / (root)
      Previous value: -{
      -  "$schema": "http://json-schema.org/draft-07/schema#",
      -  "additionalProperties": false,
      -  "properties": {
      -    "jobId": {
      -      "description": "the render job id — poll get_job with this id to resume or inspect",
      -      "type": "string"
      -    },
      -    "model": {
      -      "anyOf": [
      -        {
      -          "type": "string"
      -        },
      -        {
      -          "type": "null"
      -        }
      -      ],
      -      "description": "the product-facing label of the model that rendered it"
      -    },
      -    "raw": {
      -      "description": "the raw job result payload (e.g. images[] for carousel template ads)"
      -    },
      -    "stillRendering": {
      -      "description": "true when the render is still in progress — keep polling get_job with jobId",
      -      "type": "boolean"
      -    },
      -    "url": {
      -      "anyOf": [
      -        {
      -          "type": "string"
      -        },
      -        {
      -          "type": "null"
      -        }
      -      ],
      -      "description": "the served URL of the finished media (absent/null while still rendering)"
      -    }
      -  },
      -  "type": "object"
      -}New value: +null
  13. Addedv0.1.15

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare readOnlyHint=false and openWorldHint=true; the description supplies the costly details annotations cannot: it spends credits, is blocked on the Starter plan, takes 1–3 minutes, and — critically — that audio is not free by default because a music bed gets composed and charged, roughly the cost of a cheap draft clip. It also discloses that many failure paths are refused free with nothing charged, which materially changes an agent's willingness to retry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Roughly 350 words, but for a 27-parameter tool with no output schema that length is largely earned and it is front-loaded with the routing decision before any implementation detail. It loses a point for duplicating the audio/music-bed billing rule that the `audio` and `musicMood` schema descriptions already state at nearly equal length.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a high-complexity generative tool with no output schema, the description covers the return value ('its mp4 URL'), the latency band, the credit cost and plan gate, the per-model capability dependency via hermoso_capabilities, and the refusal-without-charge semantics. Nothing an agent needs in order to call this correctly or set user expectations is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3 and the schema already carries per-parameter detail. The description still adds cross-parameter meaning rather than restating fields: that refImage anchors the first frame while refVideo instead EDITS the source clip keeping its canvas and length, and that raw:true dispatches byte-identical with no rewriting, no negative prompt and no brand references. Handing first-frame semantics to the prose is useful because it is a routing decision, not a field description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('renders one continuous clip on a real video model and returns its mp4 URL') and explicitly names the sibling it is not ('For a finished video ad, Reel, TikTok ad or UGC video for their business, use render_ad'). An agent can route between generate_video, render_ad and generate_avatar (named in the schema) without opening any other definition.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Front-loads the trigger conditions ('user asks for a video clip, b-roll or a shot from a description, or names a video model') and pairs them with an explicit exclusion routed to render_ad. It also states operative preconditions an agent must satisfy before calling: durationSeconds must be one of the model's listed durations in hermoso_capabilities, and unnamed renders use a narrower auto-pool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Deploy Server

Other Tools