Every change Wellknown observed on this MCP server, newest first, with what it was before and what it became. Tool-surface changes carry the definition diff. Nothing here is edited after the fact.
Changed the definition of "lab_depth_map" and "lab_verkettung"
⟨31 unchanged words⟩ our own CPU, no credits; processing takesminutesminutes. modell: v2 (default) is Depth Anything V2, sharpest edges. vda is Video Depth Anything: steadier over time (no brightness pumping across the shot, slightly less flicker), softer edges, about0.52xsecondsslower than v2 (on our server ~0.5 s per frame for v2, ~1.1 s for vda), only for 16:9 landscape or 9:16 portrait videos (16:10 and 1.85:1 are fine, 4:3 and 2.39:1 are not). Each modell keeps its own map; always pass the same modell when reading again (engine in the answer says which one). Reuses the existing map or running job by ⟨45 unchanged words⟩ call this tool again with the same project_id, video_id andvideo_idmodell, neu: false. Once done, use resolve_ergebnis_an_timeline ⟨15 unchanged words⟩
{"$schema":"http://json-schema.org/draft-07/schema#","properties":{"modell":{"description":"Depth engine: v2 (default, sharpest) or vda (steady over time, 16:9 or 9:16 only)","enum":["v2","vda"],"type":"string"},"neu":{"description":"Start a new depth ⟨83 unchanged words⟩
⟨36 unchanged words⟩ same checks as a real start; returns preis_geschaetzt_credits, preis_hoechstens_credits (with every allowed retry) and `reicht` against balance, project cap and an active auto run, plus startbilder_offen when a chain's first start image is not approved yet — nothing is created) · starten (COSTS ⟨102 unchanged words⟩ and location come from each job's own character_refs/location_id. A schnitt follow-up clip is TEXT-TO-VIDEO: without character_refs/location_id the person and place hang on one sentence of text — give them for real continuity. CONTINUITY CHECK: in a chain with more than one clip every clip is checked against its prompt BEFORE the next one starts (status pruefen, wartet_auf: abgleich while the check runs — that is not a hung job). On mismatch the clip is re-rendered at most neuversuche times (default 1, prompt led by the failed claims, charged like the clip); if it still deviates the chain STOPS before the next clip is paid (chain status abgebrochen, clip status abweichung, issues and verworfen at the clip). The last clip of a chain gets its retry too but the chain then ends fertig with the verdict at the clip. Single clips are only checked in the background. durchgehend = the last frame becomes the start ⟨97 unchanged words⟩
⟨93 unchanged words⟩ ,"sequenziell"],"type":"string"},"
Added "lab_referenz_aus_bild" and "lab_umzug"; changed the definition of "lab_animate", "lab_generate" and "lab_get_job" (111 tools before, 113 now)
⟨1970 unchanged words⟩ positive integer as string. Required unless get_cost istruetrue. Imported Midjourney images work directly: use an image_id from lab_umzug.","type":"string"},"source_video_id":{ ⟨172 unchanged words⟩
⟨82 unchanged words⟩ still wins over both: identity beats look.ListBuildaone
Authorization not required, issuer https://mcp-lab.thefilmradar.com
Changed the definition of "lab_fassungen", "lab_flow_angebot", "lab_flow_fortsetzen" and 6 more
Use when the person asks about earlier states of a cut, wants to go back to a previous version, compare versions, name a version, or create a second cut (e.g. a short version next to the long one). The history and the versions of ONE cut ⟨212 unchanged words⟩
Use when the person wants a saved flow, pipeline or multi-step workflow priced, costed, calculated or checked against the balance BEFORE anything runs. Price a whole Flow (Pipeline) before running ⟨179 unchanged words⟩
Changed the definition of "lab_voice_clone"
⟨157 unchanged words⟩ pick here.","type":"boolean"},"likeness_ref":{"description":"Consent id from the Likeness Register (LK-XXXXX-XXXXX-XXXXX-XXXXX) for the person whose voice this is. When set, the register is checked live (active, purpose voice_synthesis, the project's target markets) and the clone is refused if the consent does not hold. Needed for a real person's voice in a project for children or young people.","type":"string"},"name":{"description":"A label for this ⟨148 unchanged words⟩
Changed the definition of "lab_grade_clip"
⟨116 unchanged words⟩ %), master ±1 ≈ ±2 stops there; schritte as a list (≤ 8) of further grades with the same fields (plus name), applied in series after this grade — serial nodes; creative and sek stay on the grade itself; hdr as {dark|shadow|light|highlight: {x, y, master ⟨239 unchanged words⟩
Authorization not required, issuer https://mcp-lab.thefilmradar.com
Changed the definition of "lab_add_media", "lab_grade" and "lab_grade_clip"
⟨90 unchanged words⟩ ].asset_key (video) or bett.asset_key (audio). Exception: in projects that check images, an uploaded image is not in the project after the PUT — the answer then carries `abschluss_noetig` and an `abschluss_key`; after the PUT call lab_add_media again with the same project_id, art, herkunft and `abschluss_key` only. That call checks the image and returns the `asset_key`, or says why it was refused. Free. Internal addresses are refused.
{"$schema":"http://json-schema.org/draft-07/schema#","properties":{"abschluss_key":{"description":"Only after an upload whose answer said `abschluss_noetig`: the `abschluss_key` from that answer, given AFTER the PUT returned 200. Give it instead of media_url and file_name","maxLength":300,"minLength":1,"type":"string"},"art":{"description":"What the file is ⟨148 unchanged words⟩
Added "lab_fassungen", "lab_letzter_frame" and "lab_verkettung"; changed the definition of "lab_get_job", "lab_grade_clip" and "lab_prompt_transform" (108 tools before, 111 now)
⟨15 unchanged words⟩ after starting a long-running generate/export. Returns the jobrecord.record; its payload and result are objects (for a clip chain: result.zusammenfassung, result.ketten, result.clips).
⟨139 unchanged words⟩ , hue}}; `sek: null` removes it. Any level also takes `warper` — the Color Warper: {huesat|chromalum: {res: 6|12|24, punkte: [[i, j, dx, dy], …]}}; node (row i, column j) sits at (j/res, i/res) and is moved by (dx, dy) in −1..1. huesat plane: x = 0.5 + 0.5·sat·cos(hue), y = 0.5 + 0.5·sat·sin(hue) (lightness kept); chromalum plane: x = sat, y = 1 − lightness (hue kept). Only moved nodes; `warper: null` removes it.
Added "lab_abgleich", "lab_auto_lauf", "lab_grade_clip" and 2 more; changed the definition of "lab_flow_angebot", "lab_flow_fortsetzen", "lab_flow_starten" and 1 more (103 tools before, 108 now)
⟨125 unchanged words⟩ the balance and what the cap still allows. A node whose price only exists once its input exists (lab_upscale fed by a clip from another node) is listed with `preis_folgt: true` and is NOT in the total: the run stops before it, names the exact price and continues only after lab_flow_fortsetzen — tell the person so when you name the total.
⟨40 unchanged words⟩ first (lab_review_asset, verdict accepted), then resume.TheAwaiting
Added "lab_zielgruppe"; changed the definition of "lab_get_export" and "lab_start_export" (102 tools before, 103 now)
⟨140 unchanged words⟩ short session-bound form for the web app only. A finished result also carries zielmarkt_checkliste: per target market of the project (see lab_zielgruppe) what the customer must observe when delivering there — empty without markets. Pass it on to the person with the download; it is not legal advice.
⟨59 unchanged words⟩ URLs come back in the finished job's `derivatives`. The finished job also carries `zielmarkt_checkliste` (delivery checklist per target market, set with lab_zielgruppe).
Added "lab_flow_fortsetzen" (101 tools before, 102 now)
Resume Flow Run — Resume a Flow (Pipeline) run that stopped and waits (status 'wartet' with a reason like 'Wartet auf Freigabe'). A run stops when a clip node needs a start image the person has not approved yet — approve the image first (lab_review_asset, verdict accepted), then resume. The waiting nodes are tried again; nothing that already ran is repeated and nothing beyond the original quote is charged for it.
Added "lab_mix", "lab_mix_messen", "lab_mix_render" and 1 more; changed the definition of "lab_list_assets" (97 tools before, 101 now)
⟨13 unchanged words⟩ Returns up to 20 with a total count.NOTE:EachassetrowURLscarriesareits address as `url` (with `type` and `key`). Project assets come back as SIGNED addresses on https://thefilmradar.com/api/lab/assets/abruf/… — valid for 24 h, loadable without a session and with any User-Agent. Only older rows may still point at media.andresmarder.com, whose CDN WAFblocksanswers some non-browser User-Agents (e.g. curl's default)→with
Added "lab_flow_angebot", "lab_flow_starten", "lab_flow_status" and 1 more (93 tools before, 97 now)
Quote Flow (Pipeline) — Price a whole Flow (Pipeline) before running it: one quote over every node, checked against the credit balance and the project's cost cap. `workflow` is a FilmOS workflow in schema v1 (vault/workflows/_schema.md): nodes of type `lab.tool` call FilmLab tools by name, `{{node_id.field}}` passes one node's result into the next, `parallel` and `condition` are supported, `foreach` and `workflow.invoke` not yet. Every node whose tool costs money is priced with that tool's own get_cost preflight; a paid tool without a preflight, or a price that cannot be determined, rejects the whole quote by name —…
Run Flow (Pipeline) — Run a Flow (Pipeline) that was quoted with lab_flow_angebot. Pass the SAME workflow and inputs plus the angebot_id — a changed workflow, an expired quote (24 h) or a quote that was already used is refused; get a new quote then. Only after the person confirmed the price. Returns right away with `lauf_id`; the run continues on the server without anyone watching. Follow it with lab_flow_status. Each node calls its FilmLab tool under your account; every tool's own gates still apply (approved keyframe before a paid clip, cost cap of the project). If the cost cap is hit, the whole run stops and not…
Flow Run Status — State of a Flow (Pipeline) run started with lab_flow_starten: the run's status (wartet, laeuft, fertig, fehlgeschlagen, abgebrochen) and, per node, its status, attempts, result and error. A node's result is exactly what its tool returned — ids from there go into the next tools.
Changed the definition of "lab_generate", "lab_list_characters", "lab_propose" and 1 more
⟨251 unchanged words⟩ in the order given, up to themodel'smax_references (lab_list_models).Aof the model that actually runs. WITH A CHARACTER, flux_pro — the default — RUNS AS flux_2_pro (FLUX.2 [pro] edit), which takesaupsingletoreference9getsreferences: the answer names the switch in `umgeschaltet` (von/nach), and get_cost prices flux_2_pro. flux_pro's own img-to-img variant (redux) only
Authorization not required, issuer https://mcp-lab.thefilmradar.com
Changed the definition of "lab_auto_storyboard" and "lab_dossier"
⟨40 unchanged words⟩ is split into (at most max_scenes).TheAskper-imagethepricehumandependsbefore running it. CHARACTERS ARE NOT GUESSED: every character who appears in more than one frame first gets a reference image (an existing project character with a reference is reused for free; a new one is created and its reference sheet is charged separately as character_sheet_generate), and every frame showing such a character is generated WITH those references on`model`;seedream_5_proseeinstead of `model`. Frames without a recurring character use `model`. The answer lists `figuren` (name, status, scenes), `figuren_kosten_geschaetzt` and `kosten_je_bild`; prices per model come from
Changed the definition of "lab_whoami"
⟨12 unchanged words⟩ and how this connection signed in (oauth, oauth_geraet, bridge_key, legacy service user, or anonym). For a device sign-in it also lists the device limits (projects, credits, end date). Call it when results look like someone ⟨18 unchanged words⟩
Added "lab_dossier" and "lab_get_dossier"; changed the definition of "lab_auto_storyboard" and "lab_generate_character_reference" (91 tools before, 93 now)
Auto-generate a storyboardforfrom aproject.script:SYNCHRONOUSanandLLMLLM-heavysplits the script into scenes, then one storyboard frame is generated per scene. COSTS CREDITS — every scene is one generated image, charged up front for the number of scenes the script is split into (at most max_scenes). The per-image price depends on `model`; see lab_list_models. Ask the human before running it. The scene split is SYNCHRONOUS and can take up to ~55s and then time out (504) forlargelongprojects;
Authorization required → not required, issuer https://mcp-lab.thefilmradar.com
Added "lab_capture" and "lab_feedback"; changed the definition of "lab_animate", "lab_animate_batch", "lab_bilder" and 9 more (89 tools before, 91 now)
⟨548 unchanged words⟩ Only kling_3_pro.","type":"string"},"familie":{"description":"Pick the MODEL, not the access route: 'seedance-2.0' or 'seedance-2.5'. The server takes the cheapest route that this account may use and that can do the job (OpenRouter only with the user's consent; references, 1080p for 2.5, or audio switched off go to fal) and falls back to fal if a cheaper route fails — the fallback can cost more than the preflight price. Mutually exclusive with tool and intent.","enum":["seedance-2.0","seedance-2.5"],"type":"string"},"generate_audio":{"description":"Ask for the model's ⟨1519 unchanged words⟩
⟨271 unchanged words⟩ see lab_animate","type":"string"},"familie":{"description":"Pick the MODEL, not the access route: 'seedance-2.0' or 'seedance-2.5'. The server takes the cheapest route that this account may use and that can do the job (OpenRouter only with the user's consent; references, 1080p for 2.5, or audio switched off go to fal) and falls back to fal if a cheaper route fails — the fallback can cost more than the preflight price. Mutually exclusive with tool and intent.","enum":["seedance-2.0","seedance-2.5"],"type":"string"},"
Added "lab_add_media" and "lab_herkunft"; changed the definition of "lab_animate", "lab_start_export", "lab_timeline_apply" and 1 more (87 tools before, 89 now)
before
{"$schema":"http://json-schema.org/draft-07/schema#","properties":{"abdruck_startframe":{"description":"Generate frame one WITH the character's trained Figurenabdruck (LoRA) instead of taking the flat studio portrait from the character sheet — the clip then starts IN the scene rather than in a photo studio. Opt-in: it costs one extra image (5 credits). Needs EXACTLY ONE character_ref that has a finished Abdruck, and is rejected together with source_image_id (that one PICKS frame one, this one MAKES it). Refused before any quota is spent.","type":"boolean"},"apply_lens":{"description":"Defaults to TRUE on the backend: the project's lens_state UrPrompt is appended to the prompt. Pass false only to deliberately opt out for this one call.","type":"boolean"},"audio_url":{"description":"URL of an existing audio track to lay under the clip. Independent of generate_audio, which asks the PROVIDER to synthesise its own.","type":"string"},"camera_motion":{"description":"Structured camera move sent to the model itself — only models whose lab_list_models entry lists camera_motions. Prefer this over prose when a keyframe chain must MOVE rather than cross-fade.","enum":["dolly_in","dolly_out","dolly_left","dolly_right","jib_up","jib_down","static","focus_shift"],"type":"string"},"character_refs":{"description":"Character ids (positive integer strings) whose reference image locks the cast's identity for this clip. On most providers only the FIRST character's image is used, as the start frame — with two characters in frame the second is unbound. On kling_3_pro each character additionally becomes its own reference element (frontal view plus up to 3 further angles from its sheet), so all of them are bound. The response reports `elements_bound` and `characters_without_reference`.","items":{"type":"string"},"type":"array"},"character_states":{"additionalProperties":{"type":"string"},"description":"Which STATE each character is in for this clip, as { characterId: stateKey } — e.g. { \"12\": \"wet\" }. A state is its own asset with its own full descriptor (clean / soaked / bloodied are three assets, not one with a note), and it is the ONLY way that descriptor reaches a generation: the reference image always carries the BASE state, so without this field you get dry Cal in a scene where he just came out of the Thames — and the clip looks correct. Get the keys from lab_get_character_sheet. Every id here must also appear in character_refs (who is not in the frame is not described), and an unknown key is rejected before any quota is spent.","propertyNames":{"type":"string"},"type":"object"},"character_voices":{"additionalProperties":{"type":"string"},"description":"Bind a voice per character: character id -> fal voice id. Voice ids come from fal-ai/kling-video/create-voice — FilmLab keeps no voice registry of its own, the id is passed through unverified. Every character named here must also be in character_refs AND must have a generated reference image (no image → no element → nothing to bind the voice to; rejected before quota is spent). Only kling_3_pro.","propertyNames":{"type":"string"},"type":"object"},"duration_seconds":{"description":"Clip length in seconds. Must lie inside the model's duration grid from lab_list_models; inside the grid the provider may snap to its nearest step. IGNORED when `shots` is given — then the rendered length is the sum of the shot durations.","maximum":30,"minimum":1,"type":"number"},"end_image_id":{"description":"id of a completed image to land the clip on (last frame). REQUIRES a start frame (source_image_id or character_refs) — an end frame alone is rejected before quota is spent. Only kling_3_pro.","type":"string"},"generate_audio":{"description":"Ask for the model's native audio track. Only meaningful where lab_list_models says audio: schaltbar — models with audio: immer always have it, audio: nie never.","type":"boolean"},"get_cost":{"description":"Preflight: return the price in credits and your balance WITHOUT generating, reading the same catalog as lab_list_models. Do this before a batch or when the user wants to see the cost. For a card the user confirms, use lab_propose instead.","type":"boolean"},"in_sec":{"description":"Cut the reference clip server-side before it reaches the provider: start of the excerpt, in seconds from the clip's beginning. Only together with out_sec, and only with source_video_id.","type":"number"},"intent":{"description":"Say WHAT the shot is instead of picking a model — the router chooses by priority and a cost cap. 'draft' and 'ambient' route to the cheapest provider, 'dialog' to the one with the steadiest faces, 'hero' to the most expensive on purpose, 'atmo' for atmosphere. Prefer intent over tool: it also gives you an automatic fallback to the next provider if the first one hard-fails. An explicitly set `tool` always wins over intent.","type":"string"},"kamerapfad":{"additionalProperties":{},"description":"The camera move as INPUT instead of prose: an object following shared/kamerapfad/schema.json — poses over time (position, look-at or quaternion, metres, Y up) from the Kadrage terrain flight or drawn by hand, or motion phases as lab_kamerafahrt reads them from a clip (its answer carries a ready `kamerapfad`). The backend validates it, derives phases, and then writes the move into the prompt IN THE FORM THIS MODEL UNDERSTANDS: prose at the camera slot for most families, bracketed director commands inside the prompt string for the MiniMax/Hailuo family, which parses them. NO MODEL RECEIVES THE POSES TODAY — the answer says which form went out (kamerapfad.angewandt = als_text or als_regiebefehle), names the family rule and the source it rests on (kamerapfad.sprache), and lists what that form could not carry (kamerapfad.nicht_gesendet, kamerapfad.befehle_weggefallen next to kamerapfad.befehle_gesamt). IF YOUR OWN PROMPT ALREADY CARRIES BRACKETED COMMANDS and the model parses them, the path is NOT sent on top of them — two chains would contradict each other at the same parser; the answer then says angewandt = eigene_regie and names what it found in kamerapfad.eigene_regiebefehle, and your prompt goes out unchanged. A `zusammenfassung` inside the path is display only and is NEVER sent — the move is always rebuilt from the phases; if nothing can be built (phases without tempo/verlauf), the answer says angewandt = nicht_ableitbar with the reason, and nothing of the path is in the prompt. Mutually exclusive with kamerapfad_url.","propertyNames":{"type":"string"},"type":"object"},"kamerapfad_url":{"description":"Address of a kamerapfad JSON instead of the object — the url of a file in THIS project (lab_list_assets), e.g. the kamerapfad JSON that Kadrage writes next to its flight video. Fetched by the backend under the same ownership rule as every reference: a file of another project is a named rejection before anything is charged. Mutually exclusive with kamerapfad.","type":"string"},"location_id":{"description":"Location board id (from lab_list_locations). The board's `prompt_prefix_en` is appended to your prompt as 'Location: …', so a clip stays in the same place as the images shot there. A board WITHOUT a prefix anchors nothing and fails silently — check with lab_list_locations.","type":"string"},"metadata":{"additionalProperties":{},"description":"Free-form JSON stored alongside the video. Not interpreted by the pipeline.","propertyNames":{"type":"string"},"type":"object"},"ohne_keyframe":{"description":"Skip the keyframe checkpoint on purpose. By default a paid clip only starts from a start image the user has approved (lab_review_asset verdict: accepted) — look at the frame first, then spend on the clip. Set true only when the user explicitly asked to skip the frame check.","type":"boolean"},"out_sec":{"description":"End of the excerpt in the reference clip, in seconds. Must lie behind in_sec; both are set together or neither. Only with source_video_id.","type":"number"},"project_id":{"description":"Project id (from lab_list_projects)","type":"string"},"prompt":{"description":"Motion/camera instruction for the animation","minLength":1,"type":"string"},"referenzen":{"description":"Typed references for the clip path (source_video_id). The position IS the address: the first image is @Image1, the first extra clip is @Video2 (the reference clip itself is @Video1), the first sound is @Audio1. Write @bild1/@video1/@ton1 in the prompt and they are resolved to exactly these positions HERE, before anything is sent — no detour through lab_prompt_transform needed (it resolves them too when it rewrites a prompt). Every image reference is MEASURED before it is sent and scaled up to the model's minimum if it is below it; nothing is ever rejected for being small.","items":{"properties":{"art":{"description":"Which channel this reference goes into: bild an image, video a clip, ton a sound. The channel is not the same as the role — an image can be a character, a place or a look, and only you know which; say it in `rolle`. How many of each a model takes is in lab_list_models (referenz_grenzen); a channel the model has no slot for is rejected before anything is charged.","enum":["bild","video","ton"],"type":"string"},"id":{"description":"The reference as an ID instead of an address, looked up in this project: an image id (lab_generate/lab_job_status), a video id (lab_animate), an audio id (lab_list_audio), or an asset key (lab_list_assets). The URL is never built here — it comes from the backend's answer, because the bucket is not guessable and a hand-built address renders, bills, and then leads nowhere.","type":"string"},"rolle":{"description":"WHICH character or place this reference means. Free text, carried through — not derivable from `art`, and guessing it would be a claim about the cast nobody made.","type":"string"},"url":{"description":"Address of the reference. Exactly one of url or id — both together means two sources for one address, and one of them would silently lose.","type":"string"}},"required":["art"],"type":"object"},"type":"array"},"resolution":{"description":"Resolution tier, exactly as listed for the model in lab_list_models. Omit for the model's default. Some models have no resolution field at all — then leave it out.","type":"string"},"scene_ref":{"description":"Scene label (e.g. 'SZ 04'). Stored on the row, so clips can be matched back to a shot list and reviewed per scene with lab_review_queue.","type":"string"},"seed":{"description":"Seed for a repeatable run. Omit it and the project's stored seed applies (POST /api/lab/projects/{id}/einstellungen), and without that the provider picks one. The seed that actually rendered comes back in lab_job_status as `seed` with `seed_quelle` ('provider' = read from the provider's answer, 'gesetzt' = the one sent, null = the model tells no seed). Models whose endpoint has no seed field do not drop a given seed silently: the run proceeds and the row carries `seed_hinweis: seed_nicht_unterstuetzt` — some models tell their seed but take none, others take one but tell none.","maximum":4294967295,"minimum":0,"type":"integer"},"shot_type":{"description":"How to cut a multi-shot clip. 'customize' (default) renders exactly the shots you gave. 'intelligent' lets the model decide the cutting — your shot prompts become a suggestion, not a spec. Belongs to `shots`; alone it is rejected.","enum":["customize","intelligent"],"type":"string"},"shots":{"description":"Multi-shot: a sequence of shots rendered as ONE output, holding character, place and voice across the cuts. This is NOT the same as several clips stitched together — those you pay for individually and they do not hold the cast. PRICE: the billed length is the SUM of the shot durations, not duration_seconds. Three 5s shots cost the same as one 15s clip (100 credits), not the same as one 5s clip (40). The sum must fit the provider's 3-15s window — each shot may be legal on its own and the sum still too long. Only kling_3_pro. Requesting it elsewhere is rejected before quota is spent.","items":{"properties":{"duration_seconds":{"description":"Length of this shot (default 5)","maximum":15,"minimum":1,"type":"integer"},"prompt":{"description":"What happens in THIS shot","minLength":1,"type":"string"}},"required":["prompt"],"type":"object"},"type":"array"},"source_image_id":{"description":"id of a completed image (from lab_generate/lab_job_status) to animate — positive integer as string. Required unless get_cost is true","type":"string"},"source_video_id":{"description":"Animate FROM A CLIP instead of a still: the id of a generated video (from lab_animate/lab_job_status) or the asset key of an uploaded one (from lab_list_assets, asset_type 'video'). The run then goes to the reference-motion path — your clip leads, the model restyles it. Mutually exclusive with source_image_id, and only for models that take a video reference (lab_list_models says v2v); The picture-side fields (end frame, shots, audio, location) do not travel this path and are rejected rather than dropped; character references exist here under a different name (ready image URLs instead of sheet ids) and are rejected too, with that reason. An intent IS resolved before the run and travels as the chosen model.","type":"string"},"tool":{"description":"Video model id — copy it verbatim from lab_list_models (kind: video). Omit to let the intent router choose. Every model has its own resolutions, duration grid, audio behaviour and price; the catalog is the only place those live, this text deliberately names none.","type":"string"}},"required":["project_id","prompt"],"type":"object"}First tool surface recorded: 87 tools (server version 1.26.0)
Authorization required, Bearer, issuer https://mcp-lab.thefilmradar.com
Authorization required, Bearer, issuer https://mcp-lab.thefilmradar.com
Authorization required, Bearer, issuer https://mcp-lab.thefilmradar.com
Authorization required, Bearer, issuer https://mcp-lab.thefilmradar.com
Authorization required, Bearer, issuer https://mcp-lab.thefilmradar.com
Authorization required, Bearer, issuer https://mcp-lab.thefilmradar.com
Authorization required, Bearer, issuer https://mcp-lab.thefilmradar.com
Authorization required, Bearer, issuer https://mcp-lab.thefilmradar.com
Certificate recorded, valid to 2026-12-05
Authorization required, Bearer, issuer https://mcp-lab.thefilmradar.com
Showing the latest 33 events. The API returns up to 500 and filters by kind: ?kind=tool_surface_changed
⟨31 unchanged words⟩ a clip chain: result.zusammenfassung, result.ketten, result.clips). For an Umzug import (lab_umzug): result.bildzeilen (image_id, datei), result.gesperrt (datei, grund), result.ungeprueft.
Image as Reference — Attach an existing project image (an image_id from lab_umzug, lab_get_job result.bildzeilen or lab_generate) as reference: `ziel: 'figur'` makes it a view of a character (default view 'detail', the face anchor). `personenbezug` is REQUIRED for a character and has no default: 'keine_reale_person' or 'reale_person' — the latter needs a likeness_ref from the Likeness Register and turns the character into a digital double, checked before every later generation. `ziel: 'location'` stores it as the location's reference (viewer, continuity check). It does NOT steer generation — only the description …
Midjourney Import — Bring Midjourney exports into a project (FilmLab calls this 'Umzug'). Midjourney has no API, so the person downloads their images or ZIP and this tool carries them on. Give EXACTLY ONE of: `dateien` (names/types/sizes of local files → signed PUT addresses with a ready curl line; PUT the raw bytes, then call again with `quellen` from `weiter`), `quellen` (after the PUT: starts the import job → job_id; poll lab_get_job — result.bildzeilen lists image_id and datei per image (the prompt per image comes with `bilder: true`), result.gesperrt names refused images with the reason, result.ungeprueft i…
Use when a flow/pipeline run is waiting for approval or a price confirmation and the person gives the go-ahead to continue. Resume a Flow (Pipeline) run that stopped ⟨126 unchanged words⟩
Use when the person has seen the quote for a flow/pipeline and says to run, start or execute it. Run a Flow (Pipeline) that was quoted ⟨140 unchanged words⟩
Use when the person asks how far a flow/pipeline run is, whether it finished, why it stopped or hangs, or what a step returned. State of a Flow (Pipeline) run started ⟨37 unchanged words⟩
Use when the person asks where a project stands: its current stage, what is finished, what comes next, or wants the project's state before continuing. Get a single FilmLab project with its full ⟨8 unchanged words⟩
⟨21 unchanged words⟩ :{"additionalProperties":{"items":{"items":[{"maximum":255,"minimum":0,"type":"number"},{"maximum":255,"minimummaxItems":02,"typeminItems":"number"}]2,"type":"array"},"maxItems":16, ⟨175 unchanged words⟩ },"stops":{"items":{"items":{"anyOf":[{"maximum":1,"minimum":0,"type ⟨4 unchanged words⟩ ]{6}$","type":"string"}]},"maxItems":2,"minItems":2,"type":"array"},"maxItems":8, ⟨272 unchanged words⟩
Use when the person asks HOW to stage or shoot a feeling or effect (which angle, movement, framing or light makes a scene feel tense, tender, triumphant, uneasy) or wants directing options for a shot. Directing techniques: camera angle, framing, composition, ⟨74 unchanged words⟩
Use when the person asks a film-craft question: what a term means, which rule or convention applies, how something is usually done in camera, editing, sound or production — answer from here, not from memory. Ask the FilmOS knowledge layer — measured craft ⟨62 unchanged words⟩
⟨37 unchanged words⟩ gallery image the sequencer and export pick up. For full control the recipe fields are open too: levels and curves per channel (rgb, r, g, b — values 0..255), a gradient map (luminance → colour ramp), exposure offset/gamma and grain seed/colour. Fixed order, like a node stack: exposure → levels → curves → hue/saturation → look (LUT) → gradient map → grain. The same recipe on the same image always ⟨53 unchanged words⟩
⟨17 unchanged words⟩ ,"low"],"type":"string"},"curves":{"additionalProperties":{"items":{"items":[{"maximum":255,"minimum":0,"type":"number"},{"maximum":255,"minimum":0,"type":"number"}],"type":"array"},"maxItems":16,"minItems":2,"type":"array"},"description":"Curves per channel as [x, y] points 0..255, x strictly increasing (smooth monotone curve through them). Example warm highlights: {\"r\": [[0,0],[192,205],[255,255]], \"b\": [[0,0],[192,180],[255,255]]}. Not together with contrast on the rgb channel","propertyNames":{"enum":["rgb","r","g","b"],"type":"string"},"required":["rgb","r","g","b"],"type":"object"},"exposure":{"description":"Exposure in stops; positive ⟨6 unchanged words⟩ "minimum":-3,"type":"number"},"exposure_gamma":{"description":"Exposure gamma; 1 neutral, above 1 brightens midtones","maximum":10,"minimum":0.1,"type":"number"},"exposure_offset":{"description":"Exposure offset added after the stops (lifts or crushes blacks); zero neutral","maximum":0.5,"minimum":-0.5,"type":"number"},"from_colorist":{"description":"Start from the project's ⟨8 unchanged words⟩ on top","type":"boolean"},"gradient_map":{"description":"Gradient map: luminance 0..1 → colour ramp, blended with opacity (default 1). Example teal-orange: {\"stops\": [[0, \"#0b2a33\"], [0.5, \"#7a7a72\"], [1, \"#ffd9a8\"]], \"opacity\": 0.3}","properties":{"opacity":{"maximum":1,"minimum":0,"type":"number"},"stops":{"items":{"items":[{"maximum":1,"minimum":0,"type":"number"},{"pattern":"^#[0-9a-fA-F]{6}$","type":"string"}],"type":"array"},"maxItems":8,"minItems":2,"type":"array"}},"required":["stops"],"type":"object"},"grain":{"description":"Film grain amount; zero ⟨5 unchanged words⟩ "minimum":0,"type":"number"},"grain_mono":{"description":"Grain in black and white (default true); false gives colour grain","type":"boolean"},"grain_seed":{"description":"Seed of the grain pattern (default 0) — same seed, same grain","maximum":1000000,"minimum":0,"type":"integer"},"hue":{"description":"Hue rotation in degrees; ⟨19 unchanged words⟩ from lab_list_assets / lab_generate)","type":"string"},"levels":{"additionalProperties":{"properties":{"black":{"maximum":254,"minimum":0,"type":"number"},"gamma":{"maximum":10,"minimum":0.1,"type":"number"},"out_black":{"maximum":255,"minimum":0,"type":"number"},"out_white":{"maximum":255,"minimum":0,"type":"number"},"white":{"maximum":255,"minimum":1,"type":"number"}},"type":"object"},"description":"Levels per channel (rgb = all three, r/g/b single), values 0..255: input black/white point, gamma (above 1 brightens midtones), output black/white. Example: {\"rgb\": {\"black\": 12, \"white\": 240, \"gamma\": 1.1}}","propertyNames":{"enum":["rgb","r","g","b"],"type":"string"},"required":["rgb","r","g","b"],"type":"object"},"lightness":{"description":"Lightness; negative ⟨89 unchanged words⟩
⟨81 unchanged words⟩ −1..1 (x/y move the colour wheel); log as {shadow|midtone|highlight: {x, y, master}} — the Log wheels in ACEScct, each acting only on its range of brightness (shadows below ~4 % linear, highlights above ~50 %), master ±1 ≈ ±2 stops there; hdr as {dark|shadow|light|highlight: {x, y, master}} — HDR zone wheels centred −3/−1/+1/+3 stops around 18 % grey, master ±1 ≈ ±1.5 stops; curves as {master|r|g|b: [[x,y],… ⟨26 unchanged words⟩ softness, invert}, fenster: [{form:kreis|rechteck|verlaufkreis|rechteck|verlauf|polygon|bezier, cx, cy, rx, ry, winkel, weich, invert, modus: add|sub, punkte (polygon/bezier only: 3–16 resp. 3–12 [x, y] in the window's own unit space, scaled by rx/ry and turned by winkel — bezier draws a smooth closed curve through them)}], grade: {saturation, exposure, temperature, tint, hue, schutz}} — schutz 0..100 takes the clip's and the programme's grade back inside the selection (100 = ungraded there, e.g. to protect skin); `sek: null` removes it. Any level also ⟨110 unchanged words⟩
⟨18 unchanged words⟩ ,"szene","portrait","street","editorial","handy"],"type":"string"},"depth":{ ⟨566 unchanged words⟩
Versions of a Cut — The history and the versions of ONE cut (sequence). Every timeline write (lab_timeline_apply, the editor, the Resolve bridge) first saves the state it replaces; this tool reads those saved states and works with them. Costs nothing. aktion 'liste' (default): the saved states, newest first, with `marke` (a name a person gave a state), plus where this sequence was branched from (`ursprung`, with what changed since the branch point) and which versions were branched from it (`abgezweigt`). 'markieren': give a state a name (`marke`); a named state is never cleaned up — states without a name are cap…
Last Frame of a Clip — Extract the LAST frame of a finished clip as a new image (returns image_id, image_url, zu_dunkel). Use it as source_image_id to continue one unbroken take, or as a still. A frame that is too dark (zu_dunkel: true) makes a bad start image — say so instead of animating from black. Free (no credits). Chains (lab_verkettung) do this themselves for uebergang=durchgehend.
Render Clip Chains — Render several clips as CHAINS: within a scene one after another (continuity), across scenes in parallel (speed) — the plan follows scene_ref of each job in order. aktion: plan (free: shows the chains) · preis (free: same checks as a real start; returns preis_geschaetzt_credits and `reicht` against balance, project cap and an active auto run — nothing is created) · starten (COSTS CREDITS, ONLY after the person confirmed the price from aktion=preis). Each clip is charged when it starts; an active lab_auto_lauf cap applies. The FIRST clip of every chain needs an approved start image (keyframe c…
⟨100 unchanged words⟩ whole run stops and nothing after it starts. The quoted price is also the run's own hard cap (auto_lauf_id): every node reserves against it, failed nodes keep their share, and a run whose retries would cost more than the quote stops with budget_exceeded instead of spending more.
⟨77 unchanged words⟩ },"get_cost":{"description":"`true` returns what upscaling THIS clip costs (`cost_generations`, measured server-side from its length and the height of the RESULT, exactly what the run would charge) plus the published rate per output second per tier and your balance — WITHOUT scaling and without spendinganything —anything.NOTFor atotal. Twoclipthingsthatdecideisthestillamountpendingandtherebothisarenomeasuredtotalserver-sideyet:the lengththenof`cost_generations`theissource,null andthe height`preis_grund`ofsaysthewhy.RESULTWhich(sourcetiersheightaretimesmeasuredfactor)and whichpicksare catalog values is thetier.same distinction lab_list_models makes.","type":"boolean"},"max_credits":{"description":"Theanswermostalsoyousaysagreewhichtotierspayare—measuredpassandthewhichamountarefromcatalogget_costvaluesthat—the person confirmed. If thesamemeasureddistinctionpricelab_list_modelsismakes.higherThewhenrealtheamountruncomesstarts,backitwithistherefusedactualbeforecall.anything is charged.","maximum":9007199254740991,"minimum":0,"type":"booleaninteger"},"video_id":{"description":"Generated-video id ⟨32 unchanged words⟩
Prompt Check — Prompt check of ONE generated image or clip: does the result show what its prompt asked for? The backend first DESCRIBES the result without seeing the prompt, then splits the prompt into checkable claims (counts as digits, quoted text, identity, place, framing, style; for clips the motion) and scores each. verdict: pass | mismatch | unverified, plus `checks`, `issues` and the neutral `beschreibung`. Runs automatically after every generation (lab_job_status shows it as `abgleich`); call this to read it, or with neu=true to check again. On mismatch: offer at most ONE retry per original, lead th…
Auto Run (Spending Cap) — Auto run with a hard spending cap: the person approves ONE run with an upper limit in credits; inside it you may generate without asking per item, but never above the cap. aktion: anlegen (project_id + deckel_credits → status 'angelegt', nothing can be spent yet) · freigeben (ONLY after the person explicitly approved the cap) · stand (cap, reserved, free, items) · beenden. While a run is active, EVERY paid call in that project reserves its price against the cap — whichever tool makes it; reservations are never refunded (a failed item keeps its share, a retry reserves again), upscales and expo…
Grade a Clip in the Edit — Set the colour grade of ONE clip in the edit (Murnau), or of the whole programme with `programm: true`. It is the same grade a colourist sets in Murnau's colour workspace, and the export uses it: Murnau bakes the export LUTs when you set it. Only the fields you send change (`zuruecksetzen: true` starts from neutral). Fields and ranges, as the sliders: exposure in stops (−5..5); contrast, saturation, temperature, tint −100..100; hue −180..180; lift/gamma/gain/offset as {x, y, master}, each −1..1 (x/y move the colour wheel); curves as {master|r|g|b: [[x,y],…]} 0..1; boost, shadows, highlights −…
Match the Look of a Scene — Check the colour CONTINUITY of a scene in the edit (Murnau): every shot is compared with the scene's reference shot (the first, or `referenz_clip_id`) at the SAME scene points — found by feature matching (ORB + homography) between the two frames, each rendered through its export path. Image-wide statistics would measure the framing, not the grade (measured: up to 5000 K apart with no grade change). At those points: white point (Kelvin and mired), lightness (L*), colour distance (ΔE). Over the threshold (8 mired, L* 4, ΔE 3) a shot gets a `befund` with the number (e.g. '150 K wärmer als die Sz…
Measure a Clip (Scopes) — Measure ONE clip of the edit as numbers instead of a picture: a frame is rendered through the clip's export path (input profile, grade LUT, secondary correction) and measured — luma percentiles (P1/P50/P99, Rec.709), mean R/G/B, green excess (G minus the mean of R and B: >0 green cast, <0 magenta), vectorscope centroid (Cb, Cr), clipped highlights and crushed shadows. `befund` says what is off in words with the number; `vorschlag.grade` is a correction computed on a sample of the source through the clip's full grade (gamma wheel master first, then exposure, temperature, tint, gain wheel) towa…
Audience & Markets — Read or set a project's audience (zielgruppe) and target markets (zielmaerkte). With project_id only: read. Set zielgruppe 'kinder' or 'jugendliche' whenever the project is made for children, families or teenagers — do it BEFORE creating characters or generating. That switches on blocks for the whole project: the adult mode is off even for unlocked accounts, real people are refused (likeness photos, voice clones, lipsync with a consent id, digital doubles as characters), generation stops instead of running unchecked when the content check is down, and the export must mark the whole film as AI…
⟨19 unchanged words⟩ :"Attach the pictures themselves, downscaled to 512px— and note that this is,thesoONLYyouwaycantolookseeat themfrom here: the asset URLs sitwithoutbehindfetchingaanythingCDN(olderWAFmedia.andresmarder.comthataddressesanswersanswer a non-browser User-Agent with 403, so fetching them yourself fails.). The worker fetches with a browser UA. At ⟨30 unchanged words⟩
Set the Sound Mix — Set the sound mix of a sequence: per track `volume_db`, `pan`, `mute`, `solo` and `effects`. Every field you send is rendered — the backend rejects what it cannot render (422 with the reason), so a saved mix is the mix you hear. Tracks are the stems `dialog`, `music`, `sfx`, `atmo`, plus `master` (effects only: eq, compressor, limiter). Only the fields you send change; `effects` replaces that track's whole effect list. Effects: gate, eq, deesser, compressor, reverb, limiter — fixed order, one of each per track; give a `preset` (with its written reasoning), a one-knob `knopf` (0–1) or explicit…
Measure the Rendered Mix — Measure the RENDERED mix: integrated loudness (LUFS), true peak (dBTP) and loudness range (LU) of the master, measured on the mixdown file itself. Per stem the same values, speech-gated (under the dialog / in its pauses), and how many LU each stem sits under (or over) the dialog in dialog passages — exact. A stem's level inside the master is an estimate (stem plus the gain the master applied) and is labelled as such. Needs a current render whose stems are still the ones it was made from: any change with lab_mix discards it, and a newer audio file in a stem makes it stale (409 then — render fi…
Render the Sound Mix — Render the sequence's mixdown, normalised to a loudness target: `broadcast` (EBU R128), `web` or `youtube`. With `auto_preset` it runs the AUTO-MIX instead: it measures every stem speech-gated (under the dialog vs. in its pauses), sets faders, ducking and a master limiter by the preset (`spielfilm`: music clearly under the dialog; `doku_vo`: the narrator leads), renders, and measures the result. Every auto-mix decision comes back as one sentence with its number, plus missed lower loudness bounds — read them, they are the reasoning you can pass on. Runs as a BACKGROUND JOB: the answer is a job…
Frames of the Export — See the DELIVERED film: up to 12 frames from the finished export (lab_start_export → lab_get_export status done), tiled into one image and shown. This is the rendered picture WITH everything the render adds — lens/grade, lower thirds, title cards and the AI badge — so use it to check the result, e.g. 'is the lower third readable at 7 s, does the badge cover anything'. lab_capture shows the cut BEFORE rendering (computed from the timeline, without those layers); this tool shows what was actually delivered. Give `sekunden` (seconds into the exported film) or `verteilt` (n frames spread evenly; …
Spoken words — Every spoken word with its start and end time, for a clip (video_id), an audio track (audio_id) or an uploaded file (project_id + asset_key). Use it to cut pauses without cutting into a word, to time captions, or to land a graphic on an exact word — instead of guessing seconds from the waveform. Up to 20 min of sound per source; the first call transcribes (Fish Audio, about 0.36 USD per audio hour, booked to the operator, not your credits), every later call for the same sound is served from the cache for free. Returns at most 300 s of words per page; continue with `weiter_von_s`. Speech recog…
⟨49 unchanged words⟩ name or project name (substring, case-insensitive). It shows YOUR OWN characters plus the public catalog (sheets explicitly made public and bound to no project). Characters of other accounts' projects never appear — projects can be confidential. New characters are private. The register returns at most 50publicsheets, newest first, and offers NO paging ⟨29 unchanged words⟩ Nobody there yet? Create a sheet with lab_create_character.NOTE the asymmetry: this listing shows every public sheet, but lab_get_character only opens the ones you own — a listed id you cannot open belongs to somebody else. Build your own cast rather than borrowing entries you cannot read.
⟨109 unchanged words⟩ :"string"},"type":"array"},"costume_refs":{"description":"The costume plate of these characters goes along as an extra reference image — the outfit on an invisible mannequin, NO person. Every id must also be in character_refs. Needs a model whose max_references covers characters + plates. Each plate is one more reference and may cost credits.","items":{"type":"string"},"type":"array"},"duration_seconds":{"description":"Video: clip length ⟨607 unchanged words⟩
⟨46 unchanged words⟩ · relight (no box — the lightdirection moveschanges across the wholeframeframe; by default the scene stays exactly as it is, licht_weg 'iclight' instead repaints the background and may change the scenery) · mask (no box — you describe ⟨42 unchanged words⟩ not pixels — the worker builds the mask.inpaint/replace/relightinpaint/replace start at5-95 credits per run on the reference area (larger areas cost more); relight costs 4 flat per image (licht_weg 'iclight': from 9, by area); mask costs 1, flat per request. ⟨28 unchanged words⟩
⟨85 unchanged words⟩ / lab_generate)","type":"string"},"licht_weg":{"description":"relight only. kontext (default): only the light changes, scene, people and framing stay. iclight: the background is repainted from the light description — the scenery may change","enum":["kontext","iclight"],"type":"string"},"light_preset":{"description":"relight only. There is ⟨118 unchanged words⟩
⟨19 unchanged words⟩ ,"high"],"type":"string"},"figuren_raten":{"description":"Opt-out, off by default: true skips the character references and lets the image model invent every character from the text — a different face in every frame. Only set it when the human explicitly asks for that; it is recorded on every frame (figuren_geraten).","type":"boolean"},"max_scenes":{"description":"Upper limit for the ⟨117 unchanged words⟩
⟨6 unchanged words⟩ "gewaehlt (default): the selected take perscene;scene, plus every take without a scene (e.g. a series) that is not rejected; alle: every take that is notrejectedrejected. Stars/favourites do not count as a selection.","enum":["gewaehlt","alle"], ⟨89 unchanged words⟩
{"$schema":"http://json-schema.org/draft-07/schema#","properties":{"creativity":{"description":"Krea 2 creativity setting; ignored by flux_pro. Default medium.","enum":["raw","low","medium","high"],"type":"string"},"max_scenes":{"description":"Upper limit for the number of scenes, and therefore images charged. Backend default when omitted.","maximum":20,"minimum":1,"type":"integer"},"model":{"description":"Image model for the frames. Default krea_2_medium. Prices per model: lab_list_models.","enum":["krea_2_medium","krea_2_large","krea_2_turbo","flux_pro"],"type":"string"},"project_id":{"description":"Project id","type":"string"},"script":{"description":"Screenplay or scene description to storyboard. Required — the backend splits it into scenes; each scene becomes one image.","maxLength":80000,"minLength":20,"type":"string"},"style_reference_url":{"description":"Shared moodboard image applied to ALL frames for one consistent look. Used by the Krea 2 models only. Must be an asset of this project or an absolute URL — anything else is refused before credits are spent.","type":"string"}},"required":["project_id","script"],"type":"object"}
Generate the reference sheet for a character — six core views rendered from the sheet's `prompt_prefix_en`: detail (fullbodythree-quarter close-up, the identity anchor), frontal (frontal close-up), profile,detailfullbody (front), fullbody_back (back view: hair and the back of the costume) and costume (the outfit on an invisible mannequin, NO person — use it where the costume is meant, never as a face reference). Back view and costume are derived from fullbody, everything else from detail. The poses pose_sitting, pose_walking, pose_action)renderedarefromoptional extras for blocking — not part of thesheet'sdefault`prompt_prefix_en`.run and not used as references for image or video models. A seventh view, 'detail_smile', is NOT in ⟨163 unchanged words⟩ run is six. Pass `views` to render fewer. Takes about 25 s PER VIEW (the tool requests them one by one, anchor first), so a full run is 2–3 minutes. If a single request times out, the answer says `noch_in_arbeit` instead of failing: that view is still rendering and already paid for — check it with lab_get_character_sheet, do NOT re-run it. The sheet needs a `prompt_prefix_en`; the backend regenerates ⟨47 unchanged words⟩
⟨21 unchanged words⟩ description":"Which views to render. Omit forallthesix.six core views. Allowed:fullbodydetail, frontal, profile,detailfullbody, fullbody_back, costume, pose_sitting, pose_walking, pose_action. Fewer views = fewer credits;`fullbody``detail` and`profile``fullbody` alone are usually enough to lock an identity. ⟨9 unchanged words⟩
Build Dossier — Build a dossier of a project's takes: one ZIP with an offline index.html (no external resources) plus the media files, named Project_SceneNN_YYYYMMDD-Tnn.ext. modus 'kunde' is for a client and NEVER shows seed or costs, whatever the switches say; 'intern' shows everything that helps to rebuild a take. Both modes carry the AI disclosure (EU AI Act Art. 50) on the page and in the image files. Free (no credits). Runs as a job — poll lab_get_dossier.
Get Dossier — Poll a dossier job by job_id (from lab_dossier). status is queued|processing|done|failed. When done, result.archiv_url is a signed https link to the ZIP that loads WITHOUT a login and expires after 24 h — call again for a fresh one. result.fehlend lists takes that could not be loaded.
⟨66 unchanged words⟩ end is rejected by name, not clamped. Works on generated clips (video_id) AND on your own uploaded footage (project_id + asset_key from lab_add_media) — look at it before you cut it. Free (no credits).
{"$schema":"http://json-schema.org/draft-07/schema#","properties":{"asset_key":{"description":"Storage key of uploaded footage (from lab_add_media / lab_list_assets). Needs project_id","type":"string"},"kachel_breite":{"description":"Width of one frame ⟨16 unchanged words⟩ default true)","type":"boolean"},"project_id":{"description":"Project the asset_key belongs to — required with asset_key","type":"string"},"sekunden":{"description":"Seconds into the clip ⟨33 unchanged words⟩ id (from lab_animate/lab_job_status) — positive integer asstringstring. Give this OR asset_key","type":"string"}},"required":["video_id","sekunden"],"type":"object"}
⟨227 unchanged words⟩ Character ids (positive integer strings) whose referenceimageimageslockslock the cast's identity. Routes the call to img-to-imgusingandthesendsfirstEVERY listed character's referenceURLimage, in the order given, up to the model's max_references (lab_list_models). A model that takes a single reference gets only the first character: naming more with that tool explicitly is rejected before any quota is spent; without an explicit tool the image is made with the first one and the answer names the rest in `referenz_warnung` and `referenzen.nicht_gesendet` —sonothingthisis dropped silently. Each additional reference may cost credits; get_cost with character_refs prices exactly that. This OVERRIDES seed_image_url: theprovidercharacterstakesfillonlytheONEreferencesourceslots, and identity wins over composition. A character ⟨753 unchanged words⟩
⟨94 unchanged words⟩ the safe one to hand to a user. All result addresses — video_url, download_url, archiv_url and the provenance record herkunft.pdf_url / herkunft.json_url — are signed https links that load WITHOUT a login and expire after 24 h; call lab_get_export again for fresh ones. view_url is the short session-bound form for the web app only.
⟨131 unchanged words⟩ tool means the provider fallback chain degraded therun.Forrun; bild means a vision check found the result contradicting an explicit statement of the brief (free for the user, once per run; bild_review says why it was skipped). A failed or degraded proposal run may also carry plan_b: alternatives with checked prices and proposal IDs, offered once. Present them to the human; never start them yourself. Call lab_run_proposal only after the human confirms an alternative.For a run that carried a kamerapfad, metadata.kamerapfad ⟨135 unchanged words⟩
⟨13 unchanged words⟩ Returns up to 20 with a total count. Finished rows carry the same signed, login-free result addresses as lab_get_export (download_url, herkunft.pdf_url, …; valid 24 h).
⟨158 unchanged words⟩ says supports_end_frame.","type":"string"},"familie":{"description":"Video: pick the model ('seedance-2.0', 'seedance-2.5') instead of a route — the card then names and prices the route the server takes for this account, and the run is PINNED to it (a card promises one price, so no silent fallback). Mutually exclusive with tool and intent.","enum":["seedance-2.0","seedance-2.5"],"type":"string"},"generate_audio":{"description":"Video: ask for ⟨30 unchanged words⟩ with out_sec and source_video_id.","type":"number"},"intent":{"description":"Video intent from the routing rules. Used to choose a model when tool is omitted and retained for Plan B; an explicit tool wins.","type":"string"},"kind":{"description":"Which kind ⟨434 unchanged words⟩
Directing techniques: camera angle, framing, composition, movement andmovementlighting, each with the emotional effect it creates ⟨42 unchanged words⟩ fragments are appended verbatim, not rewritten. One angle, one movement and onemovementlighting setup per shot; framing and composition stack. Read-only, free.
⟨10 unchanged words⟩ ["winkel","kadrage","komposition","bewegung","licht"],"type":"string"},"wirkung":{ ⟨19 unchanged words⟩
⟨102 unchanged words⟩ the text, so no new proposal is needed. Standbild-Bewegung uses no model prompt; confirm that proposal unchanged.","minLength":1,"type":"string"},"vorschlag_id":{"description":"The id fromlab_propose.lab_propose or plan_b in lab_job_status. Do not construct one — an unknown id ⟨15 unchanged words⟩
⟨143 unchanged words⟩ Only with ki_kennzeichnung minimal, durchgehend or leitfaden. Audio counts too: an AI or undeclared sound track (bed, stems, mixdown) runs under the whole film, so the export then marks the whole film and reports umfang_bestellt. Declare own music or dialogue with lab_add_media(herkunft) or lab_herkunft. A film with no AI clip at all ⟨241 unchanged words⟩
Read the sound of a clip (video_id)or, an audio track (audio_id) or an uploaded file (project_id + asset_key from lab_add_media) as numbers: peak level 0..1 per channel ⟨49 unchanged words⟩
{"$schema":"http://json-schema.org/draft-07/schema#","properties":{"asset_key":{"description":"Storage key of an uploaded sound or video file (from lab_add_media). Needs project_id","type":"string"},"audio_id":{"description":"Audio track id (from lab_list_audio). GivethisexactlyORone of video_id, audio_id, asset_key","type":"string"},"bis_s":{ ⟨10 unchanged words⟩ von_s","minimum":0,"type":"number"},"project_id":{"description":"Project the asset_key belongs to — required with asset_key","type":"string"},"video_id":{"description":"Generated video ⟨27 unchanged words⟩
Frames of the Cut — See the CUT at exact seconds of the finished film: up to 12 frames, tiled into one image and shown. Each second is mapped like the export maps it — which clip is on screen, where in its source (src_in_s counts), the export's framing (scaled and letterboxed), title cards drawn. A video whose source is shorter than its clip duration ends early in the export, and everything after it moves forward; this tool follows that, so you see the film that will be rendered. The answer names per frame the clip (position, clip_id), clip start and offset; a clip that would render black says so ('schwarz'). NO…
Report a Bug or Wish — Tell the FilmLab team about a bug or a missing feature — it reaches the people who can fix it, the chat does not. Use art 'fehler' when a tool returned something wrong, failed without a clear reason, or contradicted its own description; 'wunsch' when a step you needed does not exist. Write what you called, what you expected and what came back; put ids, arguments and the error text into `kontext` (no secrets, no personal data of third parties). One report per problem. Do not report a refused request that was correct (e.g. 'Project not found' for someone else's project). Needs an account. Free.
after
{"$schema":"http://json-schema.org/draft-07/schema#","properties":{"abdruck_startframe":{"description":"Generate frame one WITH the character's trained Figurenabdruck (LoRA) instead of taking the flat studio portrait from the character sheet — the clip then starts IN the scene rather than in a photo studio. Opt-in: it costs one extra image (3 credits). Needs EXACTLY ONE character_ref that has a finished Abdruck, and is rejected together with source_image_id (that one PICKS frame one, this one MAKES it). Refused before any quota is spent.","type":"boolean"},"apply_lens":{"description":"Defaults to TRUE on the backend: the project's lens_state UrPrompt is appended to the prompt. Pass false only to deliberately opt out for this one call.","type":"boolean"},"audio_url":{"description":"URL of an existing audio track to lay under the clip. Independent of generate_audio, which asks the PROVIDER to synthesise its own.","type":"string"},"camera_motion":{"description":"Structured camera move sent to the model itself — only models whose lab_list_models entry lists camera_motions. Prefer this over prose when a keyframe chain must MOVE rather than cross-fade.","enum":["dolly_in","dolly_out","dolly_left","dolly_right","jib_up","jib_down","static","focus_shift"],"type":"string"},"character_refs":{"description":"Character ids (positive integer strings) whose reference image locks the cast's identity for this clip. On most providers only the FIRST character's image is used, as the start frame — with two characters in frame the second is unbound. On kling_3_pro each character additionally becomes its own reference element (frontal view plus up to 3 further angles from its sheet), so all of them are bound. The response reports `elements_bound` and `characters_without_reference`.","items":{"type":"string"},"type":"array"},"character_states":{"additionalProperties":{"type":"string"},"description":"Which STATE each character is in for this clip, as { characterId: stateKey } — e.g. { \"12\": \"wet\" }. A state is its own asset with its own full descriptor (clean / soaked / bloodied are three assets, not one with a note), and it is the ONLY way that descriptor reaches a generation: the reference image always carries the BASE state, so without this field you get dry Cal in a scene where he just came out of the Thames — and the clip looks correct. Get the keys from lab_get_character_sheet. Every id here must also appear in character_refs (who is not in the frame is not described), and an unknown key is rejected before any quota is spent.","propertyNames":{"type":"string"},"type":"object"},"character_voices":{"additionalProperties":{"type":"string"},"description":"Bind a voice per character: character id -> fal voice id. Voice ids come from fal-ai/kling-video/create-voice — FilmLab keeps no voice registry of its own, the id is passed through unverified. Every character named here must also be in character_refs AND must have a generated reference image (no image → no element → nothing to bind the voice to; rejected before quota is spent). Only kling_3_pro.","propertyNames":{"type":"string"},"type":"object"},"duration_seconds":{"description":"Clip length in seconds. Must lie inside the model's duration grid from lab_list_models; inside the grid the provider may snap to its nearest step. IGNORED when `shots` is given — then the rendered length is the sum of the shot durations.","maximum":30,"minimum":1,"type":"number"},"end_image_id":{"description":"id of a completed image to land the clip on (last frame). REQUIRES a start frame (source_image_id or character_refs) — an end frame alone is rejected before quota is spent. Only kling_3_pro.","type":"string"},"generate_audio":{"description":"Ask for the model's native audio track. Only meaningful where lab_list_models says audio: schaltbar — models with audio: immer always have it, audio: nie never.","type":"boolean"},"get_cost":{"description":"Preflight: return the price in credits and your balance WITHOUT generating, reading the same catalog as lab_list_models. Do this before a batch or when the user wants to see the cost. For a card the user confirms, use lab_propose instead.","type":"boolean"},"in_sec":{"description":"Cut the reference clip server-side before it reaches the provider: start of the excerpt, in seconds from the clip's beginning. Only together with out_sec, and only with source_video_id.","type":"number"},"intent":{"description":"Say WHAT the shot is instead of picking a model — the router chooses by priority and a cost cap. 'draft' and 'ambient' route to the cheapest provider, 'dialog' to the one with the steadiest faces, 'hero' to the most expensive on purpose, 'atmo' for atmosphere. Prefer intent over tool: it also gives you an automatic fallback to the next provider if the first one hard-fails. An explicitly set `tool` always wins over intent.","type":"string"},"kamerapfad":{"additionalProperties":{},"description":"The camera move as INPUT instead of prose: an object following shared/kamerapfad/schema.json — poses over time (position, look-at or quaternion, metres, Y up) from the Kadrage terrain flight or drawn by hand, or motion phases as lab_kamerafahrt reads them from a clip (its answer carries a ready `kamerapfad`). The backend validates it, derives phases, and then writes the move into the prompt IN THE FORM THIS MODEL UNDERSTANDS: prose at the camera slot for most families, bracketed director commands inside the prompt string for the MiniMax/Hailuo family, which parses them. NO MODEL RECEIVES THE POSES TODAY — the answer says which form went out (kamerapfad.angewandt = als_text or als_regiebefehle), names the family rule and the source it rests on (kamerapfad.sprache), and lists what that form could not carry (kamerapfad.nicht_gesendet, kamerapfad.befehle_weggefallen next to kamerapfad.befehle_gesamt). IF YOUR OWN PROMPT ALREADY CARRIES BRACKETED COMMANDS and the model parses them, the path is NOT sent on top of them — two chains would contradict each other at the same parser; the answer then says angewandt = eigene_regie and names what it found in kamerapfad.eigene_regiebefehle, and your prompt goes out unchanged. A `zusammenfassung` inside the path is display only and is NEVER sent — the move is always rebuilt from the phases; if nothing can be built (phases without tempo/verlauf), the answer says angewandt = nicht_ableitbar with the reason, and nothing of the path is in the prompt. Mutually exclusive with kamerapfad_url.","propertyNames":{"type":"string"},"type":"object"},"kamerapfad_url":{"description":"Address of a kamerapfad JSON instead of the object — the url of a file in THIS project (lab_list_assets), e.g. the kamerapfad JSON that Kadrage writes next to its flight video. Fetched by the backend under the same ownership rule as every reference: a file of another project is a named rejection before anything is charged. Mutually exclusive with kamerapfad.","type":"string"},"location_id":{"description":"Location board id (from lab_list_locations). The board's `prompt_prefix_en` is appended to your prompt as 'Location: …', so a clip stays in the same place as the images shot there. A board WITHOUT a prefix anchors nothing and fails silently — check with lab_list_locations.","type":"string"},"metadata":{"additionalProperties":{},"description":"Free-form JSON stored alongside the video. Not interpreted by the pipeline.","propertyNames":{"type":"string"},"type":"object"},"ohne_keyframe":{"description":"Skip the keyframe checkpoint on purpose. By default a paid clip only starts from a start image the user has approved (lab_review_asset verdict: accepted) — look at the frame first, then spend on the clip. Set true only when the user explicitly asked to skip the frame check.","type":"boolean"},"out_sec":{"description":"End of the excerpt in the reference clip, in seconds. Must lie behind in_sec; both are set together or neither. Only with source_video_id.","type":"number"},"project_id":{"description":"Project id (from lab_list_projects)","type":"string"},"prompt":{"description":"Motion/camera instruction for the animation","minLength":1,"type":"string"},"referenzen":{"description":"Typed references for the clip path (source_video_id). The position IS the address: the first image is @Image1, the first extra clip is @Video2 (the reference clip itself is @Video1), the first sound is @Audio1. Write @bild1/@video1/@ton1 in the prompt and they are resolved to exactly these positions HERE, before anything is sent — no detour through lab_prompt_transform needed (it resolves them too when it rewrites a prompt). Every image reference is MEASURED before it is sent and scaled up to the model's minimum if it is below it; nothing is ever rejected for being small.","items":{"properties":{"art":{"description":"Which channel this reference goes into: bild an image, video a clip, ton a sound. The channel is not the same as the role — an image can be a character, a place or a look, and only you know which; say it in `rolle`. How many of each a model takes is in lab_list_models (referenz_grenzen); a channel the model has no slot for is rejected before anything is charged.","enum":["bild","video","ton"],"type":"string"},"id":{"description":"The reference as an ID instead of an address, looked up in this project: an image id (lab_generate/lab_job_status), a video id (lab_animate), an audio id (lab_list_audio), or an asset key (lab_list_assets). The URL is never built here — it comes from the backend's answer, because the bucket is not guessable and a hand-built address renders, bills, and then leads nowhere.","type":"string"},"rolle":{"description":"WHICH character or place this reference means. Free text, carried through — not derivable from `art`, and guessing it would be a claim about the cast nobody made.","type":"string"},"url":{"description":"Address of the reference. Exactly one of url or id — both together means two sources for one address, and one of them would silently lose.","type":"string"}},"required":["art"],"type":"object"},"type":"array"},"resolution":{"description":"Resolution tier, exactly as listed for the model in lab_list_models. Omit for the model's default. Some models have no resolution field at all — then leave it out.","type":"string"},"scene_ref":{"description":"Scene label (e.g. 'SZ 04'). Stored on the row, so clips can be matched back to a shot list and reviewed per scene with lab_review_queue.","type":"string"},"seed":{"description":"Seed for a repeatable run. Omit it and the project's stored seed applies (POST /api/lab/projects/{id}/einstellungen), and without that the provider picks one. The seed that actually rendered comes back in lab_job_status as `seed` with `seed_quelle` ('provider' = read from the provider's answer, 'gesetzt' = the one sent, null = the model tells no seed). Models whose endpoint has no seed field do not drop a given seed silently: the run proceeds and the row carries `seed_hinweis: seed_nicht_unterstuetzt` — some models tell their seed but take none, others take one but tell none.","maximum":4294967295,"minimum":0,"type":"integer"},"shot_type":{"description":"How to cut a multi-shot clip. 'customize' (default) renders exactly the shots you gave. 'intelligent' lets the model decide the cutting — your shot prompts become a suggestion, not a spec. Belongs to `shots`; alone it is rejected.","enum":["customize","intelligent"],"type":"string"},"shots":{"description":"Multi-shot: a sequence of shots rendered as ONE output, holding character, place and voice across the cuts. This is NOT the same as several clips stitched together — those you pay for individually and they do not hold the cast. PRICE: the billed length is the SUM of the shot durations, not duration_seconds. Three 5s shots cost the same as one 15s clip (140 credits at the reference resolution), not the same as one 5s clip (47). The sum must fit the provider's 3-15s window — each shot may be legal on its own and the sum still too long. Only kling_3_pro. Requesting it elsewhere is rejected before quota is spent.","items":{"properties":{"duration_seconds":{"description":"Length of this shot (default 5)","maximum":15,"minimum":1,"type":"integer"},"prompt":{"description":"What happens in THIS shot","minLength":1,"type":"string"}},"required":["prompt"],"type":"object"},"type":"array"},"source_image_id":{"description":"id of a completed image (from lab_generate/lab_job_status) to animate — positive integer as string. Required unless get_cost is true","type":"string"},"source_video_id":{"description":"Animate FROM A CLIP instead of a still: the id of a generated video (from lab_animate/lab_job_status) or the asset key of an uploaded one (from lab_list_assets, asset_type 'video'). The run then goes to the reference-motion path — your clip leads, the model restyles it. Mutually exclusive with source_image_id, and only for models that take a video reference (lab_list_models says v2v); The picture-side fields (end frame, shots, audio, location) do not travel this path and are rejected rather than dropped; character references exist here under a different name (ready image URLs instead of sheet ids) and are rejected too, with that reason. An intent IS resolved before the run and travels as the chosen model.","type":"string"},"tool":{"description":"Video model id — copy it verbatim from lab_list_models (kind: video). Omit to let the intent router choose. Every model has its own resolutions, duration grid, audio behaviour and price; the catalog is the only place those live, this text deliberately names none.","type":"string"}},"required":["project_id","prompt"],"type":"object"}⟨104 unchanged words⟩ default false)","type":"boolean"},"kennzeichnung_umfang":{"description":"For a film that mixes people-made material ('eigen', see lab_herkunft) with AI material: 'film' (default) marks the whole film; 'abschnitte' shows the mark only while an AI or undeclared clip is on screen. Only with ki_kennzeichnung minimal, durchgehend or leitfaden. A film with no AI clip at all carries no mark either way. The choice and the clip-by-clip origin are recorded in the provenance record.","enum":["film","abschnitte"],"type":"string"},"ki_kennzeichnung":{"description":"How the visible AI ⟨213 unchanged words⟩
⟨237 unchanged words⟩ which orphans whatever pointed at the old one.OneTwo honestlimitlimits:DaVincitheResolve'sResolve bridge applies the clips but reports `uebergang` and the bed's level/fade as not applied (its scripting APIoffershas neither a transition call nor a clip volume property,).soThetheFilmLabResolvesequencebridgerender applies theclipsbedandwithreportsits`uebergang`level andthefade,bed'sbutlevel/fadeNOTas`uebergang`notyetapplied.—Bothdissolves are storedhereandarerenderhonouredasbyhardthecutssequence(checkedrender.2026-10-03).
⟨117 unchanged words⟩ neither level nor fade","properties":{"asset_key":{"description":"Storage key of an audio file in this project (from lab_add_media or lab_list_assets). Stable — prefer it over a URL: the URLs lab_list_assets hands out are signed and expire after 24 h","type":"string"},"audio_id":{"description":"Id of an audio row in this project (from lab_list_audio).EitherOnethisoforaudio_id, asset_key, url","type":"string"},"fade_s": ⟨29 unchanged words⟩ ":{"description":"Direct URL of thebed.bedEither(external).thisAorsignedaudio_idFilmLab asset URL is turned into its storage key, so it does not expire inside the sequence","type":"string"}},"required": ⟨213 unchanged words⟩ transition kind between ALL clips. Stored on thesequence;sequence — but neither
⟨109 unchanged words⟩ pixels — the worker builds the mask. inpaint/replace/relightcoststart7-14at 5-9 credits per run(byon the reference area (larger areas cost more); mask costs 1, flat per request. ⟨28 unchanged words⟩
Add Media — Bring your own video, audio or image into a project — not generated, yours. Two ways: `media_url` (a public http(s) address; the server fetches it, max 100 MB) or `file_name` + `content_type` (you get a signed `upload_url` and the `header` that are part of its signature: PUT the file's raw bytes there within the hour with EXACTLY those headers — the answer's `anleitung` has the ready curl line; a missing header is a 403). Either way the answer is the `asset_key` — use it in lab_timeline_apply as clips[].asset_key (video) or bett.asset_key (audio). Free. Internal addresses are refused.
Material Origin — Declare or list where a project's material comes from: 'eigen' (made by people) or 'ki' (AI-generated or AI-altered). Exports decide the EU AI Act Art. 50 disclosure per clip from this — undeclared material counts as AI. With asset_key + herkunft: declare (the file is checked for an AI mark; one found keeps it AI and the answer says why). With project_id only: list every declaration with its effect (`wirksam`).