Cinematic Presets
Layer a deliberate photographic "Cinema mode" treatment onto image generations and edits, and discover the generation preset catalog.
Cinematic Presets ("Cinema mode") let you compose a deliberate photographic look for an image by picking presets across independent dimensions — camera body, lens, focal length, aperture, angle, shot type, color grade, and lighting. The selected fragments are woven into your prompt before enhancement, so the result reads like an intentional camera setup rather than a list of gear names.
Cinema mode is entirely optional. Apply it only when the user wants a specific cinematic look —
omit it for an ordinary generation. It is available on
image generation and
image editing via the cinematic field.
Dimensions
Two different lists matter here, and they are not identical:
Dimension keys the cinematic object accepts (fixed server-side allow-list — anything else is a 400):
| Dimension | What it controls |
|---|---|
camera | Camera body / format (e.g. ARRI Alexa, 16mm film, smartphone) |
lens | Lens character (e.g. anamorphic, vintage prime, macro) |
focal_length | Focal length / field of view (e.g. 24mm wide, 85mm portrait) |
aperture | Aperture / depth of field (e.g. f/1.4 shallow, f/8 deep) |
angle | Camera angle (e.g. low angle, birds-eye, eye level) |
shot_type | Shot type / framing (e.g. close-up, wide shot, full shot) |
color_palette | Color grade (e.g. teal & orange, technicolor, classic B&W) |
lighting | Lighting technique (e.g. rim light, golden hour, low-key) |
genre | Genre treatment. The key is still on the server allow-list, but whether any genre presets exist is seed-dependent — if the list endpoint returns no genre group in your environment, there is no id you can put here. |
Groups the list endpoint returns are whatever is seeded and active, so the response may also
contain groups such as looks (bundle recipes that expand to a map of other dimensions) and
moveset.
The list endpoint is a catalog, not an input schema. A group it returns is not automatically a
valid cinematic key — looks and moveset ids are rejected with a 400 if you put them in the
cinematic object. Only the nine keys in the table above are accepted.
The catalog is data-driven — always fetch the live set from the endpoint below rather than hardcoding ids.
List Cinematic Presets
Returns all active presets grouped by dimension. Each preset carries id, name, description,
thumbnail_url, and sort_order; some also carry preview_url (a video/animated preview) and, for
looks entries, a bundle map of dimension → preset id.
Endpoint
GET /api/v1/cinematic-presetsTakes no parameters.
Example
curl https://api.kolbo.ai/api/v1/cinematic-presets \
-H "X-API-Key: kolbo_live_..."Response
The SDK route wraps the grouped catalog in a dimensions object:
{
"success": true,
"dimensions": {
"camera": [
{
"id": "6a40...aa01",
"name": "ARRI Alexa 35",
"description": "shot on an ARRI Alexa 35 digital cinema camera, wide dynamic range...",
"thumbnail_url": "https://kolbo-general-media.fra1.cdn.digitaloceanspaces.com/cinema-deck/camera/ARRI_Alexa_35.webp",
"sort_order": 1
}
],
"lens": [],
"color_palette": [],
"lighting": []
}
}If the cinematic-presets catalog is not deployed in the environment you are calling, this route
returns { "success": true, "dimensions": {} } rather than an error. Treat an empty dimensions
map as "Cinema mode unavailable here", not as a failure. This SDK route serves a fresh JSON body on
every call — it does not set an ETag, so If-None-Match has no effect. (The catalog itself is
cached server-side, so repeated calls are cheap.)
The matching @kolbo/mcp tool is list_cinematic_presets. It takes no arguments and accepts either
the SDK envelope or the raw grouped map, returning dimensions plus an available_dimensions list
of the group keys present in your environment.
Applying Cinema Mode
Pass a cinematic object on the generation request. Each key is a dimension; each value is a
preset id from the list endpoint. Include only the dimensions the user actually wants.
{
"prompt": "a lone traveler crossing a desert at dusk",
"cinematic": {
"camera": "6a40...aa01",
"color_palette": "6a40...cc07",
"lighting": "6a40...dd12"
}
}The "Auto" rule
- Any dimension you omit (or set to
null) is Auto. When at least one dimension is set, the prompt enhancer intelligently completes the unset dimensions in the spirit of the ones you chose (e.g. picking a smartphone camera steers toward a candid, deep-focus everyday look; picking a film camera steers toward a filmic treatment). - Omit the
cinematicobject entirely for a normal, non-cinematic generation — nothing is injected and the standard enhancement pipeline decides the look.
Validation
- The value must be a real JSON object, never an array. One preset per dimension (the shape enforces it — a key holds a single id).
- Each value must be a valid ObjectId string,
null, or"".nulland""mean "Auto" for that dimension. - Each
idmust resolve to an active preset in that exact dimension — an inactive preset, or alightingid in thecameraslot, returns a400naming the dimension and id. - Unknown dimension keys are rejected with a
400that names the allowed set. - A
cinematicobject whose every value isnull/""is treated as no selection at all — nothing is injected.
On the SDK routes, cinematic is forwarded only when it is an object that is not an array —
a JSON-encoded string is dropped silently before validation ever runs, so the request
succeeds with no cinematic treatment applied and no error. (The underlying validator would happily
parse a JSON string; the SDK layer just never hands it one.) Send it as a nested JSON object.
Applying cinematic also forces the prompt-enhancement pass on, even if you set
enhance_prompt: false — the selected descriptors are handed to the enhancer as a style directive
rather than concatenated onto your prompt.
Full Example
# 1. Discover presets
curl https://api.kolbo.ai/api/v1/cinematic-presets -H "X-API-Key: kolbo_live_..."
# 2. Generate with a cinematic look
curl https://api.kolbo.ai/api/v1/generate/image \
-H "X-API-Key: kolbo_live_..." \
-H "Content-Type: application/json" \
-d '{
"prompt": "a lone traveler crossing a desert at dusk",
"cinematic": {
"camera": "6a40...aa01",
"lens": "6a40...bb03",
"color_palette": "6a40...cc07",
"lighting": "6a40...dd12"
}
}'The same cinematic object works on POST /api/v1/generate/image-edit.
Generation Presets (GET /v1/presets)
A separate, unrelated catalog: curated prompt-template presets you apply to a whole generation with
the preset_id field. Cinematic presets are photographic dimensions; generation presets are whole
creative directions.
Endpoint
GET /api/v1/presetsQuery Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
type | string | No | One of image, video, music, text_to_video, shorts. Omit to return every catalog in one flat list. Any other value returns an empty presets array. |
text_to_video is an alias for the video catalog — the same entries come back, tagged type: "text_to_video".
Response
{
"success": true,
"presets": [
{
"id": "cinematic-portrait",
"name": "Cinematic Portrait",
"description": "…",
"thumbnail_url": "https://cdn.kolbo.ai/…",
"category": "portrait",
"type": "image"
}
],
"count": 1
}categoryis the grouping key forimage,video, andtext_to_video; alwaysnullformusic; and the preset's owncategoryfield (which may benull) forshorts.musicentries may also carryaudio_url(a preview) andprompt_text.shortsentries may also carrypreview_video_url,default_mode, anddefault_veed_preset, and theiridis the preset'sidentifierstring rather than an ObjectId.- If one underlying catalog fails to load, the response still returns
success: truewith the presets gathered so far plus awarningstring.
The MCP tool list_presets passes type through verbatim, so type: "shorts" works there too
even though the tool's own description only names image / video / music / text_to_video.
Example
curl "https://api.kolbo.ai/api/v1/presets?type=image" \
-H "X-API-Key: kolbo_live_..."Pass the returned id as preset_id on the matching generation endpoint. preset_id is read by
POST /v1/generate/image, /v1/generate/video, /v1/generate/music, and /v1/generate/elements.
It is not read by /v1/generate/image-edit — that route accepts cinematic but ignores
preset_id. Like a moodboard, a preset forces the prompt-enhancement pass on so its description is
synthesized with your prompt rather than concatenated.