Reference
save_look
Persist a composed look on a project as a new version, so the next strip starts there.
What it does
- Writes
- Account required
Make a design reusable. Once the user is happy with how a strip looks, this stores the styling on a project as a new version — so their next render, here or in the web app, starts from what they approved instead of a default. Styling only: caption words are never stored, so pass those per render.
You can ask: “Save the Look I just approved as a new project version.”
Input
projectstringoptionalat least 1 characterWhich ShotOps project to target: its id (as returned by read_look/save_project), OR its NAME as the user says it — matched exactly, ignoring case and surrounding spaces. Omit = your most recently edited project. A name that matches none or several is refused with the account's projects listed, never resolved by guessing.
lookobjectrequiredThe look JSON to save (styling only — the shape read_look returns / describe_look documents). Caption text is NOT part of a look; pass it per render instead.
schemanumberoptionalLook schema version. The server stamps it on every save (save_look); read_look returns it. Any input value is ignored — never set it yourself.
panelPresetIdstringoptionalCanvas size preset, e.g. r69 = 1290×2796. Default r69.
bgModestringoptionalOne gradient across the strip, or a flat colour per panel. Default gradient.
one of
gradientperPanelgradientStopsarrayoptionalat least 1 itemCanonical gradient stops — { color (hex), at (0–1 position) } — wins over gradientFrom/gradientTo/gradientDir when present. Read this back for the full stop list a Studio-authored look may carry; the trio below is only ever a two-stop summary.
each item
object
colorstringrequiredatnumberrequiredmin 0max 1
gradientAnglenumberoptionalCanonical gradient angle in degrees, clockwise from "to top" (CSS convention: 90 = right, 180 = down, the gradientDir:"vertical" equivalent). Paired with gradientStops.
gradientFromstringoptionalGradient start (hex) — a DERIVED mirror of gradientStops[0], re-derived from the stops on every render and reload. Setting it ALONE changes nothing: set gradientStops to change the backdrop. Default #1b1b2e.
gradientTostringoptionalGradient end (hex) — a DERIVED mirror of the last gradientStops entry, re-derived from the stops on every render and reload. Setting it ALONE changes nothing: set gradientStops to change the backdrop. Default #0a0a14.
gradientDirstringoptionalA DERIVED mirror of gradientAngle (nearest axis), re-derived on every render and reload. Setting it ALONE changes nothing: set gradientAngle to turn the gradient. Default vertical.
one of
horizontalverticalpanelColorsobjectoptionalPer-panel flat colours (mode perPanel), keyed by panel id.
shadowbooleanoptionalDrop shadow under the phones. Default true.
floorReflectionbooleanoptionalFlipped, faded floor reflection under each phone. Default false.
panelBackgroundsobjectoptionalPer-frame background overrides keyed by panel id (web-authored; agents rarely set these).
captionStylesobjectoptionalPer-panel caption STYLE arrays keyed by panel id (styling only, no words — for caption text pass style.captions).
shotsarrayoptionalat most 60 itemsOne entry per SCREENSHOT/DEVICE, flattened in panel order. Each entry has its OWN
look. For screenshots:[[left,right]], pass two shots with the SAME panelId ("panel-1") to give the two devices different colours/materials/angles. This is how a look varies devices; style.shotLook cannot.each item
object
panelIdstringoptionalPanel containing this screenshot/device. Panels are panel-1…panel-N in slot order; REPEAT the same panelId for multiple devices in one panel. A saved look’s own ids are remapped by ordinal.
lookobjectoptionalThis individual screenshot/device’s styling — the SAME fields as style.shotLook.
anglestringoptionalCamera preset. Default front.
one of
frontleftrightcameraPosone of 2 shapesoptionalManual camera position override; null/omit = use the angle preset.
1
xxnumberrequiredynumberrequiredznumberrequired
2
nullrollstring or numberoptional-45–45° clock-hand tilt. Default 0.
phoneHeightstring or numberoptional-45–45° clock-hand tilt. Default 0.
hOffsetstring or numberoptional-45–45° clock-hand tilt. Default 0.
vOffsetstring or numberoptional-45–45° clock-hand tilt. Default 0.
materialstringoptionalDevice body. Default real.
one of
realclaycolorwaystringoptionalBody colour (material "real"). Default silver. These are finish SLOTS — each device binds its own real finish (silver = iPhone Silver / Pixel Moonstone). "green" is Pixel-only (Jade); other devices fall back to their first finish.
one of
orangebluesilvergreencustomcustomColorstringoptionalHex body colour when colorway is "custom".
finishstring or numberoptional-45–45° clock-hand tilt. Default 0.
clearcoatstring or numberoptional-45–45° clock-hand tilt. Default 0.
clayTonestringoptionalClay tone (material "clay"). Default grey.
one of
greywhitecharcoalcustomclayCustomstringoptionalHex clay colour when clayTone is "custom".
flatScreenbooleanoptionalRender the screen flat (no curvature). Default false.
glarebooleanoptionalScreen glare. Default false.
lightingbooleanoptionalScene lighting. Default true.
reflectionsbooleanoptionalBody reflections. Default false.
clipToFramebooleanoptionalClip this complete device composite to its owning frame. Default false (overflow allowed).
sourceNamestringoptionalat most 120 charactersWhere this styling came from (shown in the studio UI).
Result
okbooleanoptionalprojectobjectoptionalidstringrequirednamestringrequired
versionnumberoptionalmessagestringoptional
Example
That request maps to this call:
{
"name": "save_look",
"arguments": {
"project": "Tidebook 2.4 launch",
"look": {
"bgMode": "gradient",
"gradientStops": [
{
"color": "#0d2b3d",
"at": 0
},
{
"color": "#6aa9c9",
"at": 1
}
]
}
}
}The version number it was saved as. Earlier versions stay readable through read_look.
Access and cost
- Needs an account. Not available to an anonymous hosted caller.
- Free. Saving a look spends no cloud credits and renders nothing.
When it refuses
- A field is rejected as out of range.
- The reply names the field, its range and the fix in prose. This is the one door where an out-of-range pose would get persisted, which is why it is checked here rather than at render time.
- Nothing you render afterwards picks the new version up.
- Something is held. A held version is the project default until release_look clears it — saving a newer one does not override it.
Where this fits
What the agent is told
The title and description the server publishes on tools/list — this is the copy a model chooses between, reproduced verbatim.
Save look
Make a design the user liked reusable: persists a composed ShotOps look (styling only) on a project as a new version, so their next strip — rendered here or opened in the web app — starts from the design they just approved instead of a default. Offer it once they are happy with how a strip looks. Use describe_look for the field catalog; caption words are never stored, so pass those per render. No store credential is involved.