Verified conversions across 205 color spaces: CSS strings, gamut checks, .cube LUTs
FilmLab is installed from its publisher's own source and answers where it runs, so this marketplace is not in the path of a single call. There is no address here to send one to, and a panel that pretended otherwise would be showing you an answer we made up. Install it and call it from your own client — the Installation tab has the entry for each one.
What it does
AI film lab for filmmakers: generate and review images/clips with input provenance, cost preflight
Quickstart
# 1 — add it to Claude Code
claude mcp add --scope user --transport http filmlab-mcp https://mcp-lab.thefilmradar.com/mcp
# 2 — ask your agent for something these tools do
# lab_list_projects, lab_wissen, lab_widerruf and 114 more
FilmLab costs nothing on mcprush: there is no plan to choose here, no cap to set and nothing mcprush can bill you for.
Collected from a public index. Nobody has claimed this account, so nothing here was written by its author — claim it if it is yours.
Where are you running it?
Every route below installs the same thing and ends at the same approval screen. Nothing here runs on your machine and nothing runs on ours: this server answers at its publisher’s own address, and what you install is the connection straight to it.
This is a public server: it answers at its publisher’s own address and this marketplace is not in the path. Claude Code registers it in one command; --scope user makes it available in every project. The transport below is http, as the publisher's own manifest declares it.
claude mcp add --scope user --transport http filmlab-mcp https://mcp-lab.thefilmradar.com/mcpReconnect, or start a new session, and the tools appear in the model’s tool list.
One config entry pointing straight at the publisher’s own address — this marketplace is not in the path, and nothing from this listing executes on your machine.
117 tools, with what each one reads, writes and reaches shown before you agree — the same list on every route above. Read the tool surface.
Tool surface
What the model actually sees. Descriptions are diffed on every release — see version history.
List FilmLab projects (id, title, current pipeline stage). Call this first to find a project_id for the other tools. Shows up to 20 items; total counts your active projects (up to 200) and truncated: true means the list is cut off — sorted by last change, so older projects drop out of the shown window first.
No parameter schema on file.
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 knowledge from vetted sources, with the KNOWN CORRECTIONS first: documented false assumptions plus what is actually true. Call this before asser
| Parameter | Type | Required | Notes |
|---|---|---|---|
| frage | string | yes | The question, in the language the sources are written in |
| anzahl | integer | no | How many knowledge hits at most (default 8). Corrections come on top. |
| mindest_autoritaet | number | no | Authority floor. Defaults to 0.85 — expert voices only. Below that the corpus holds forum members: useful as context, not as the ground for a craft claim. Lower it only deliberately, and say so in the |
Record a correction in the FilmOS knowledge layer when the user contradicts something you asserted from it. Use this the moment a contradiction is stated — not at the end of the session, and not instead of accepting the correction in your answer. It stores the claim AND what is actually true, owned by the user who said it, so lab_wissen surfaces it first next time. It does not delete anything: a d
| Parameter | Type | Required | Notes |
|---|---|---|---|
| quelle | string | yes | The source_slug the wrong claim came from — take it from a lab_wissen hit. A source that does not exist is refused, not silently stored. |
| thema | string | yes | Short topic, so the correction is findable later |
| behauptung | string | yes | The claim that is wrong, as it was stated |
| korrektur | string | yes | What is actually true — the user's wording where possible |
| url | string | no | Source URL of the claim, if a hit carried one |
The rules of one working surface, generated from the code: what the surface is, what an agent can trigger itself, what exists but only by hand, and what does not exist at all. Call this BEFORE answering what is possible on a surface — the three lists come from a table with a code reference per entry, checked in every PR, not from memory. Saying "that does not exist" about something the editor can
| Parameter | Type | Required | Notes |
|---|---|---|---|
| flaeche | string | yes | The working surface |
The model catalog: what every video or image model can do — resolutions, durations, aspect ratios, audio, reference limits, price per second or per image — grouped by capability class with a one-line explanation per group. Read this before choosing a tool for lab_generate/lab_animate/lab_propose; copy ids verbatim. Cached briefly; stand says how fresh. Without klasse the answer is COMPACT (o
| Parameter | Type | Required | Notes |
|---|---|---|---|
| kind | string | yes | Which catalog |
| klasse | string | no | Only one capability class — the valid names are listed under klassen in every answer |
| aufloesung | string | no | Only models offering this resolution, e.g. 540p |
| dauer_s | number | no | Only models that can render this duration in seconds |
| ton | string | no | ohne = can run without sound (audio nie or schaltbar); mit = can make sound |
| voll | boolean | no | Every field of every model even without klasse — large, use a filter with it |
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, movement and lighting, each with the emotional effect it creates (wirkung), when to use it (zweck_de), when it backfires (vermeiden_de) and a
| Parameter | Type | Required | Notes |
|---|---|---|---|
| gruppe | string | no | Only one group |
| wirkung | string | no | Only techniques with this effect key — the answer lists all keys under wirkungen |
| handwerk | boolean | no | Also return the camera craft (rules, look-alike pairs, focal lengths, frame boundaries) |
Who is connected: the FilmLab account (email, user id, name, tier, credits) 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 else's — two clients signed in with two accounts see different projects. Works without an account. R
No parameter schema on file.
One call, the whole picture: account (tier, credits, reset), default models with price, jobs in flight, catalog freshness, project count. Pass project_id for that project's sequences, assets and review-queue length. Read-only, free.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | no | Add a project view |
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 stage state. Needs the project_id (from lab_list_projects).
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | The FilmLab project id |
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 photo
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) |
| zielgruppe | string | no | Audience of the project: 'kinder', 'jugendliche' or 'erwachsene'; an empty string clears it. Omit to leave it unchanged |
| zielmaerkte | array | no | Target markets as ISO country codes plus 'EU', e.g. ['DE', 'AT', 'CH']. Replaces the whole list; an empty list clears it. Omit to leave it unchanged |
Read the accumulated context/output for one pipeline module of a project (e.g. the IDEE, STORYBOARD or SHOTS stage). Needs project_id and module name.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | The FilmLab project id |
| module | string | yes | Pipeline module/stage id, e.g. 'idee', 'storyboard', 'shots' |
Get the status of a background job by job_id (status is queued|processing|done|failed). Poll this after starting a long-running generate/export. Returns the job record; its payload and result are objects (for 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. Pa
| Parameter | Type | Required | Notes |
|---|---|---|---|
| job_id | string | yes | The job id returned by a generate/export tool |
| wait_s | integer | no | Wait up to this many seconds (max 80) for done/failed; the answer says gewartet_s |
Search the FilmLab universe catalog of AI tools, news and companies. Query must be at least 2 characters. Returns up to 20 matches with a total count.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| q | string | yes | Search query, min 2 characters |
Create a new FilmLab project. Returns the new project id. Optionally set a title.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| title | string | no | Project title (optional) |
Run ONE pipeline module for a project (context is injected from upstream modules + crew agents). SYNCHRONOUS and LLM-heavy: light modules return in seconds; heavy ones can exceed ~55s and then time out (504) — run those in the FilmLab web app instead. Pass an invalid module name to get the list of valid module keys. Returns the module output.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) |
| module | string | yes | Pipeline module/stage key, e.g. mod_concept, mod_storyboard, mod_shotlist, mod_script |
| message | string | yes | Your instruction/prompt for this module (the user turn in the module chat) |
Generate an image on the production pipeline (fal.ai, quota-tracked, persisted to the project's gallery). Waits up to wait_s seconds (default 45) for the image and then answers with the finished rows — image_url set, inline previews attached, so the picture is in the answer like lab_job_status with preview. Pass wait_s: 0 to return right away with rows in status 'pending' (poll lab_job_status
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) — generation is always project-scoped |
| prompt | string | yes | What to generate (required) |
| tool | string | no | Image model id — copy it verbatim from lab_list_models (kind: image). Omit to use the default. Every model has its own resolutions, aspect handling and price; the catalog is the only place those live, |
| resolution | string | no | Resolution tier, exactly as listed for the model in lab_list_models. Omit for the model's default; the aspect ratio still comes from the project's pose_state — this only sets the area. Some models hav |
| variants | integer | no | How many variants to generate (default 1, max 5) |
| seed_image_url | string | no | Optional: run img-to-img guided by this existing image URL (e.g. a prior generation's url). For a PERSON who must look the same across several images, use character_refs instead — this URL binds one c |
| seed | integer | no | 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 bac |
| anker_id | string | no | Look anchor id (positive integer string) whose CHOSEN image guides this generation as img-to-img. An anchor is a look imported from Midjourney: a handful of images plus the grammar of the old `--profi |
| get_cost | boolean | no | 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 u |
| location_id | string | no | Location board id (from lab_list_locations). Anchors the shot: the board's prompt_prefix_en is appended to your prompt as 'Location: …' before generation, so every image of the same place stays in t |
| character_refs | array | no | Character ids (positive integer strings) whose reference images lock the cast's identity. Routes the call to img-to-img and sends EVERY listed character's reference image, in the order given, up to th |
| costume_refs | array | no | The costume plate of these characters goes along as an extra reference image — the outfit on an invisible mannequin, NO person, so it carries the costume, never the face. Every id must also be in char |
| character_states | object | no | Which STATE each character is in for this image, as { characterId: stateKey } — e.g. { "12": "wet" }. A state is its own asset with its own full descriptor (clean / soaked / bloodied are three assets, |
| scene_ref | string | no | Scene label (e.g. 'SZ 04'). Stored on the row, so results can be matched back to a shot list and reviewed per scene with lab_review_queue. Omit it and the image is an orphan. |
| apply_lens | boolean | no | 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. |
| aspect | array | no | Frame as [width, height], e.g. [9, 16]. Overrides the project's pose_state — pass it when the Pose-Director's blockout is set but not yet saved. Measured 2026-07-31: without it a 9:16 blockout came ba |
| aspect_ratio | string | no | Aspect ratio as W:H (e.g. 16:9, 9:16). Must be one of the model's aspect_ratios where the model has an enum; models without an enum accept any W:H. Omit to use the project's camera aspect. |
| metadata | object | no | Free-form JSON stored alongside the image (e.g. { parent_id, note }). Not interpreted by the pipeline. |
| wait_s | number | no | Seconds to wait for the finished image before answering (default 45, max 80). 0 = answer immediately with pending rows. |
Animate a completed image into a clip with a video model. Pick the model from lab_list_models; check the price with get_cost or let the user confirm a card via lab_propose. Costs credits when called without get_cost.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) |
| prompt | string | yes | Motion/camera instruction for the animation |
| source_image_id | string | no | id of a completed image (from lab_generate/lab_job_status) to animate — positive integer as string. Required unless get_cost is true. Imported Midjourney images work directly: use an image_id from lab |
| seed | integer | no | 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 bac |
| source_video_id | string | no | 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 |
| in_sec | number | no | 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. |
| out_sec | number | no | 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. |
| tool | string | no | 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 i |
| duration_seconds | number | no | 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 len |
| shots | array | no | 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 |
| shot_type | string | no | 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 |
| end_image_id | string | no | 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. |
| camera_motion | string | no | 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. |
| character_voices | object | no | 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 c |
| resolution | string | no | 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. |
| familie | string | no | 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; |
| intent | string | no | 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, 'he |
| ohne_keyframe | boolean | no | 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 c |
| get_cost | boolean | no | 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 u |
| abdruck_startframe | boolean | no | 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 stu |
Animate MANY images into videos in ONE call (max 25 jobs). Prefer this over looping lab_animate: it validates every job BEFORE spending any quota, so an invalid job 12 of 15 does not leave 11 paid-for generations running. Quota is spent once, collectively (one ledger row); refunds stay per-clip, so a partial failure refunds only that clip. Returns a batch_id — poll lab_batch_status with it instead
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) |
| jobs | array | yes | One entry per clip, max 25. All jobs are validated before any quota is spent |
| ohne_keyframe | boolean | no | 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 c |
| get_cost | boolean | no | Preflight: return the summed price in credits for the WHOLE batch and your balance WITHOUT generating, reading the same catalog as lab_list_models. For a card the user confirms, use lab_propose instea |
Propose a generation for the user to confirm: validates the parameters against the catalog, computes the price, and shows a card (widget hosts) or returns the same object as text. NOTHING runs until lab_run_proposal is called with the returned vorschlag_id — by the card's button, or by you after the user said yes. Without a measured price there is no vorschlag_id and no button: the answer then say
| Parameter | Type | Required | Notes |
|---|---|---|---|
| kind | string | yes | Which kind of generation to propose |
| project_id | string | yes | Project id (from lab_list_projects) |
| prompt | string | yes | What to generate. The user can edit it on the card; lab_run_proposal takes the edited text as prompt_override without a new proposal. |
| tool | string | no | Model id, copied verbatim from lab_list_models. Omit to use the default for this kind — the card names it and prices it either way. |
| intent | string | no | Video intent from the routing rules. Used to choose a model when tool is omitted and retained for Plan B; an explicit tool wins. |
| familie | string | no | 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 |
| source_image_id | string | no | Video: the completed image to animate (positive integer as string). Required for a video proposal — unless source_video_id proposes a clip instead. |
| source_video_id | string | no | Video: propose a run FROM A CLIP instead of a still — a generated video id (lab_animate/lab_job_status) or an asset key (lab_list_assets). Mutually exclusive with source_image_id; only for models that |
| in_sec | number | no | Video: start of the excerpt cut out of the reference clip, in seconds. Only together with out_sec and source_video_id. |
| out_sec | number | no | Video: end of the excerpt in the reference clip, in seconds. Must lie behind in_sec. |
| end_image_id | string | no | Video: the completed image to land the clip on (last frame). Only where lab_list_models says supports_end_frame. |
| camera_motion | string | no | Video: 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. |
| resolution | string | no | Resolution tier, exactly as listed for the model in lab_list_models. Omit for the model's default. |
| duration_seconds | number | no | Video: clip length in seconds, inside the model's duration grid from lab_list_models. The card shows the DELIVERED seconds and says so when the provider snaps. |
| generate_audio | boolean | no | Video: ask for the model's native audio. Only meaningful where lab_list_models says audio: schaltbar. |
| aspect_ratio | string | no | Image: aspect ratio as W:H, from the model's aspect_ratios in lab_list_models. |
| variants | integer | no | Image: how many variants (default 1). Multiplies the price — the card shows the multiplication. |
| seed_image_url | string | no | Image: run img-to-img guided by this existing image URL. Shown on the card as the 'before'. |
| character_refs | array | no | Character ids (from lab_list_characters) whose reference image locks the cast's identity. Counted against the model's max_references and shown on the card by name. |
| costume_refs | array | no | 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_referen |
Run a proposal exactly as shown — same model, same parameters, same price. Called by the card's button, or by you after the user confirmed. Single use: the proposal is consumed BEFORE the run, so a second call is refused instead of paying twice. Valid 15 minutes, for the account that created it. Costs credits. The run is checked against what you confirmed only when it FINISHES; poll lab_job_status
| Parameter | Type | Required | Notes |
|---|---|---|---|
| vorschlag_id | string | yes | The id from lab_propose or plan_b in lab_job_status. Do not construct one — an unknown id answers 'vorschlag_abgelaufen', not an error you can work around. |
| ohne_keyframe | boolean | no | 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 c |
| prompt_override | string | no | Replace ONLY the prompt text of the stored proposal. Every other parameter — model, resolution, duration, references — and the price stay exactly as shown. This is the path for a prompt the user edite |
List location boards, newest first — START HERE to find a location_id for lab_generate / lab_animate. Each entry carries its prompt_prefix_en: that is the exact text appended to your prompt as 'Location: …', so you can judge whether the board fits BEFORE spending quota. A board with an EMPTY prefix anchors nothing — it will silently do nothing. Fix it with lab_enrich_location_prefix or pick an
| Parameter | Type | Required | Notes |
|---|---|---|---|
| search | string | no | Filter by board name or project name (substring, case-insensitive) |
| preview | boolean | no | Attach each board's reference picture, downscaled to 512px. A location board is a PLACE — its prefix text says what was written down, the picture says what the board actually anchors, and those two di |
Get ONE location board in full — all descriptive fields plus its reference images and prompt_prefix_en. Use it to check what a board actually anchors before generating with it.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| loc_id | string | yes | Location board id (from lab_list_locations) — positive integer as string |
| preview | boolean | no | Attach the board's reference images themselves, downscaled to 512px — the fastest way to check whether a board anchors the place you mean before spending quota on it. |
Location boards bound to ONE project. Narrower and more correct than lab_list_locations when you already know the project: it cannot leak boards from a different project with the same title. Boards created before the project binding existed (project_id NULL) deliberately do NOT appear here — use lab_list_locations for those.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) |
Create a location board. The backend derives an English prompt_prefix_en from the fields you give — that prefix is what later anchors every image and clip shot there, so the richer the description, the more consistent the place. Pass project_id to bind the board to a project (recommended: unbound boards are invisible to lab_list_project_locations).
| Parameter | Type | Required | Notes |
|---|---|---|---|
| name | string | yes | Board name, e.g. 'Wohnung Hanna — Balkon' |
| location_type | string | no | e.g. 'interior', 'exterior', 'apartment', 'street' |
| time_of_day | string | no | e.g. 'morning', 'blue hour', 'night' |
| description | string | no | What the place is, in prose |
| architecture | string | no | Building style, era, materials |
| colors | string | no | Dominant palette |
| props | string | no | Objects that must be present |
| atmosphere | string | no | Mood, weather, sound of the place |
| lighting_notes | string | no | Light direction, quality, sources |
| project_name | string | no | Free-text project label shown in listings |
| project_id | string | no | Bind the board to this project (from lab_list_projects) — positive integer as string |
Generate time-of-day reference images for a location board (costs credits per variant — check the price with get_cost first). Without variants the backend renders all four. The images are what makes a board usable as a visual reference.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| loc_id | string | yes | Location board id (from lab_list_locations) |
| variants | array | no | Which time-of-day variants to render. Allowed: day, night, golden_hour, rain. Omit for all of them. Fewer variants = fewer credits. |
| get_cost | boolean | no | Free: the exact price of this run (per variant and total) — nothing is rendered or charged. Name it to the person before the real run. |
Append context to a board's prompt_prefix_en (plain string concatenation server-side — no AI call, no quota). Idempotent: context already present in the prefix is not duplicated. This does NOT rewrite or regenerate the prefix — for a board whose prefix is empty, too thin or a raw field dump, use lab_restyle_location (it rewrites prompt_prefix_en with an AI call, costs credits — exact price via g
| Parameter | Type | Required | Notes |
|---|---|---|---|
| loc_id | string | yes | Location board id (from lab_list_locations) |
| context | string | yes | What to add or sharpen, e.g. 'late 1970s West Berlin, nicotine-stained walls' |
Restyle an existing board towards a wish (costs credits — exact price via get_cost: true) — same place, different look, e.g. 'the same flat, twenty years later'. Changes the board itself, so images generated afterwards follow the new style. Also the repair path for a board whose prompt_prefix_en is a raw field dump (lab_create_location returned prefix_generated: false): restyle it with a wish like
| Parameter | Type | Required | Notes |
|---|---|---|---|
| get_cost | boolean | no | Free: the exact price of this operation; nothing is rendered or charged. Name it to the person before the real run. |
| loc_id | string | yes | Location board id (from lab_list_locations) |
| wish | string | no | The desired change, in prose |
Generate a 360° equirectangular HDRI panorama of a place (costs credits — exact price via get_cost: true). Pass loc_id to persist it on that board, so the viewer finds it again; without loc_id it is a one-off.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| get_cost | boolean | no | Free: the exact price of this operation; nothing is rendered or charged. Name it to the person before the real run. |
| intent | string | no | What the place is — the panorama prompt |
| camera_height | number | no | Camera height in metres (default 1.6, roughly eye level) |
| mood | string | no | Mood/atmosphere (default 'neutral') |
| loc_id | string | no | Persist the panorama on this location board (from lab_list_locations) |
Read a photo and extract location fields from it (Gemini Vision, costs credits — exact price via get_cost: true). Returns the fields — it does NOT create a board; feed the result into lab_create_location yourself. Note the payload: the image travels as base64 inside the call, so keep it small (a downscaled JPEG, not a full-resolution capture).
| Parameter | Type | Required | Notes |
|---|---|---|---|
| get_cost | boolean | no | Free: the exact price of this operation; nothing is rendered or charged. Name it to the person before the real run. |
| image_base64 | string | no | The image as base64. A data-URL prefix ('data:image/jpeg;base64,…') is stripped by the backend |
| mime_type | string | no | Defaults to 'image/jpeg' |
DELETE a location board permanently. There is no undo and no soft-archive — the row is removed. Images and clips that were generated with this location_id keep their already-rendered prompt, but the board they point at is gone: nothing can be re-anchored to it, and lab_get_location will 404. Confirm with the user before calling this. Use lab_restyle_location if you only want the place to look di
| Parameter | Type | Required | Notes |
|---|---|---|---|
| loc_id | string | yes | Location board id to delete permanently (from lab_list_locations) |
List the character sheets in the FilmLab cast register (id, name, age, gender, project_name, prompt_prefix_en). Call this BEFORE lab_generate whenever a person must look the same across several images: pass the id you find here as character_refs instead of re-describing the person in every prompt. Optional search matches name or project name (substring, case-insensitive). It shows YOUR OWN cha
| Parameter | Type | Required | Notes |
|---|---|---|---|
| search | string | no | Substring of the character name or project name (case-insensitive) |
| preview | boolean | no | Attach each sheet's reference portrait, downscaled to 512px. A cast list read as text is a list of names; seen as faces it is a cast. At most 4 per call. A sheet WITHOUT a reference image shows none — |
Get ONE character sheet in full — every descriptive field plus the three that decide what you can do with it. prompt_prefix_en is the text block describing this person; it is what the backend prepends wherever the sheet is used. reference_images decides whether the sheet is usable at all: lab_generate REJECTS a character_refs entry without one, before any quota is spent — if it is empty, run l
| Parameter | Type | Required | Notes |
|---|---|---|---|
| character_id | string | yes | Character sheet id (from lab_list_characters) — positive integer as string |
| preview | boolean | no | Attach the reference images themselves, downscaled to 512px. reference_images decides whether the sheet is usable at all — seeing them is the check, counting them is not: a sheet can carry a URL to |
Create a character sheet for a human, animal or creature in the cast register. The backend derives an English prompt_prefix_en from the fields you give — that prefix is what later describes this character in every image, so the richer the description, the more stable the identity. This is step 1 of 2: a fresh sheet has NO reference image and is therefore not yet usable as character_refs. Run l
| Parameter | Type | Required | Notes |
|---|---|---|---|
| name | string | yes | Character name, e.g. 'Maren' — the only required field |
| gattung | string | no | Character kind: human, animal or creature. Omitted or empty means mensch. For tier/kreatur, begin the description with the species and its distinctive features. |
| project_id | string | no | Bind the sheet to this project (from lab_list_projects) — positive integer as string. PASS THIS whenever the character belongs to a project. Without it the sheet stays an orphan: lab_cast_gaps will no |
| project_name | string | no | Free-text project label shown in listings (does NOT bind the sheet — that is project_id) |
| gender | string | no | e.g. 'female', 'male', 'non-binary' |
| age | integer | no | Age in years, as a number |
| build | string | no | Body build and posture |
| hair | string | no | Hair colour, length, cut |
| eyes | string | no | Eye colour and expression |
| skin | string | no | Skin tone and texture |
| facial_features | string | no | Face shape, nose, mouth, jaw — what makes this face recognisable |
| clothing | string | no | Default costume the character is seen in |
| distinctive_features | string | no | Scars, tattoos, glasses, anything that must appear in every image |
| demeanor | string | no | How the character moves and behaves, in prose |
Generate the reference sheet for a character — six core views rendered from the sheet's prompt_prefix_en: detail (three-quarter close-up, the identity anchor), frontal (frontal close-up), profile, fullbody (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
| Parameter | Type | Required | Notes |
|---|---|---|---|
| character_id | string | yes | Character sheet id (from lab_list_characters or lab_create_character) — positive integer as string |
| views | array | no | Which views to render. Omit for the core views (six for humans, five without costume for tier/kreatur). Allowed: detail, frontal, profile, fullbody, fullbody_back, costume, pose_sitting, pose_walking, |
| get_cost | boolean | no | Free: the exact price of this run (per view and total, anchor and edit rate included) — nothing is rendered or charged. Name it to the person before the real run. |
The character sheet PREPARED FOR PROMPTING: base prefix, the state sheets by name, which reference views exist, and the ready-made sentence to paste into a lab_generate prompt. Same source as lab_get_character, different shape — use this one when you are about to generate, and lab_get_character when you want the raw record. State sheets exist against character drift: one sheet per costume, light o
| Parameter | Type | Required | Notes |
|---|---|---|---|
| character_id | string | yes | Character sheet id (from lab_list_characters) — positive integer as string |
| state | string | no | Render the snippet for THIS state key (from states[].key) instead of the base state |
| preview | boolean | no | Attach the reference views themselves, downscaled to 512px. usable_as_character_ref only says a URL exists — the picture says whether it is the right person, in the right view. That check is the who |
Find people who appear in a project's material (script / cast module) but have NO character sheet yet. Returns up to 6 missing entries, each with a name and a short hint from the text. It creates nothing — lab_cast_autopopulate does that. Costs an LLM run, so it is credit-gated. Fail-open by design: no script, no AI key, or an unparseable answer all come back as an EMPTY list (with a note sayi
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) — positive integer as string |
Create character sheets for the people found in a project's material — the writing counterpart to lab_cast_gaps. Creates at most 6 per call and binds each to the project. Costs an LLM run per call. Run lab_cast_gaps first if you want to see what it would create. The sheets it creates have NO reference image: each one still needs lab_generate_character_reference before lab_generate accepts it as `c
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) — positive integer as string |
Create a sequence (Stage 9 timeline) inside a project — START HERE to turn generated shots into something the continuity pass can read. The new sequence is EMPTY: add shots with lab_add_clip before anything else works. lab_continuity_check rejects an empty timeline with 400. Returns the sequence record including its id.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) — positive integer as string |
| title | string | no | Sequence title. Defaults to 'Main Sequence' on the backend |
List a project's sequences, newest first. Use it to find a seq_id instead of creating a second sequence for the same cut.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) — positive integer as string |
Get ONE sequence in full — timeline (the shots in order), audio_tracks, transitions, duration_seconds and render status. Check timeline here before starting a continuity pass: an empty one is the single most common reason the pass refuses.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| seq_id | string | yes | Sequence id (from lab_create_sequence/lab_list_sequences) — positive integer as string |
Read the SHOT layer of a sequence — which clips form one shot, which scene it plays in, who is in it, and what the continuity pass found. This is the layer above the timeline: lab_get_sequence gives you clips in a row, this one gives you the cut. Costs nothing, writes nothing. Use it before changing a cut: a shot binds clip_ids, so the times come out of the timeline and a shot whose clips you shor
| Parameter | Type | Required | Notes |
|---|---|---|---|
| seq_id | string | yes | Sequence id (from lab_create_sequence/lab_list_sequences) — positive integer as string |
| rung | string | no | Which level to read. 'shot' (the default) is one take; 'movement' groups shots into arcs. They are independent layers over the same clips — reading one never shows the other |
Derive the shot layer from what the clips already say about themselves — consecutive clips of the same scene become one shot, and a scene that returns later becomes a second one (one location cut into twice is two shots). Costs nothing: it groups rows and reads titles, it generates nothing. Titles come from the project's shotlist where the scene is in there, so this is more than a regrouping — it
| Parameter | Type | Required | Notes |
|---|---|---|---|
| seq_id | string | yes | Sequence id (from lab_create_sequence/lab_list_sequences) — positive integer as string |
Break one scene down into a STRUCTURED shot list of 2, 4 or 6 shots — each with shot size, camera angle, purpose and its own ready prompt, plus one shared floor plan (anchor, axis, light) so the shots cut together. Two families: an 'aufloesung' shows ONE moment from several angles (coverage, dialog, orbit, pov, zwischenschnitte for cutaways …); a 'montage' lets time pass between shots (ursache_wir
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | integer | yes | The project the scene belongs to |
| prompt | string | yes | The scene or the master prompt to break down |
| art | string | no | Which breakdown. Default coverage. Known: coverage, dialog, winkel, hoehen, orbit, pov, naehe, gesicht, haende, reaktionen, zwischenschnitte (aufloesung); ursache_wirkung, entdeckung, zeitverlauf, gef |
| laenge | integer | no | Number of shots: 2, 4 or 6. Default 4. Never odd — a breakdown runs in pairs. |
| scene_ref | string | no | Optional scene reference the shots are filed under when uebernehmen=true |
| uebernehmen | boolean | no | Default false. true appends the shots to the project's shot list — ask first. |
State the shot cut yourself: which clips form one shot, what it is called, which scene it plays in. This is the counterpart to lab_shots_ableiten — that one groups by the scene the clips already name, this one is for the judgement no field carries. Costs nothing. Use it where derivation cannot reach: ingested footage has no shotlist by nature, and a sequence whose clips name no scene would come ou
| Parameter | Type | Required | Notes |
|---|---|---|---|
| seq_id | string | yes | Sequence id (from lab_create_sequence/lab_list_sequences) — positive integer as string |
| rung | string | no | Which level to replace. 'shot' (the default) is one take; 'movement' groups shots into arcs. Independent layers over the same clips — writing one never touches the other |
| shots | array | yes | The whole level, in order. The order here IS the order of the shots |
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 (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 wo
| Parameter | Type | Required | Notes |
|---|---|---|---|
| seq_id | string | yes | Sequence id (from lab_list_sequences) — positive integer as string |
| aktion | string | no | What to do. Default 'liste' |
| checkpoint_id | integer | no | The state (id from 'liste'). Needed for markieren, vergleichen, zurueckholen; optional for abzweigen (without: the current cut) |
| marke | string | no | markieren: the name. Empty removes it |
| gegen | integer | no | vergleichen: a second state instead of the current cut |
| titel | string | no | abzweigen: the name of the new version |
Append a shot to a sequence's timeline. Call it once per shot, in cutting order — start_time is computed from the clips already there, so appending in order is enough. The continuity pass reads exactly this timeline: a shot missing here is a shot nobody checks. Returns the new clip's index and the sequence's total duration.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| seq_id | string | yes | Sequence id (from lab_create_sequence/lab_list_sequences) — positive integer as string |
| type | string | yes | What this clip is. 'image' references a generated image via source_id; 'title', 'credits' and 'lower_third' carry text instead. 'lower_third' is an OVERLAY: appended without start_time it is laid ov |
| source_id | string | no | For type 'image': the id of a generated image (from lab_generate). For type 'video': source_id is IGNORED by the continuity pass (a video id used to be misread as an unrelated image, see vault/followu |
| duration_seconds | number | no | Clip duration in seconds. Backend default is 5.0 — pass the clip's REAL length, otherwise the sequence duration and the render drift apart |
| start_time | number | no | Absolute start on the timeline. Omit to append after the last clip (the normal case); set it only to place a clip deliberately |
| text | string | no | Text content for type 'title', 'credits' or 'lower_third' |
| metadata | object | no | JSON stored alongside the clip. The continuity pass reads video_id (a generated video's id — it checks the start image), image_url (a frame URL), location_id and scene_num from here; for a 'lower_thir |
Write a WHOLE cut into a sequence in one call — clips in order with their lengths, an optional dissolve between them, an optional bed underneath. This is the counterpart to lab_get_sequence: that one reads the timeline, this one writes it. Prefer it over a chain of lab_add_clip calls whenever you already know the whole cut: a chain that breaks in the middle leaves half a sequence behind, this eith
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) — positive integer as string |
| sequence_id | string | no | Sequence to write into (from lab_create_sequence/lab_list_sequences). Omit to create a new one. Given WITHOUT a manifest, the stored manifest is read back instead of written |
| title | string | no | Title for the sequence created when sequence_id is omitted |
| erwartete_revision | string | no | The revision you read (from lab_get_sequence or this tool's read-back). The cut is written only if the sequence still has exactly that content — otherwise nothing is written and you get `revision_ve |
| manifest | object | no | The cut as one object. Omit it only together with a sequence_id, to read back what is stored |
Start the continuity pass over a sequence — every shot is compared against its PREDECESSOR and, with check_references, against the character and location reference boards. This is the pass that catches drift (the flat that changed between two shots, the cardigan that turned into a coat), which is the actual enemy in AI film, not the cut. Runs in the BACKGROUND: returns a job_id with HTTP 202 — p
| Parameter | Type | Required | Notes |
|---|---|---|---|
| seq_id | string | yes | Sequence id (from lab_create_sequence/lab_list_sequences) — positive integer as string |
| model | string | no | Vision model for the comparison. Omit it — the backend resolves its default through the model catalogue, so it follows a model retirement on its own. A literal passed here does not, and that is how a |
| check_references | boolean | no | Also check every shot against the character and location reference boards, not just against its predecessor. Backend default is true; pass false for a cheaper neighbour-only pass |
Build a contact sheet for a generated clip — N frames spread evenly over its runtime, tiled into ONE image — and show it. This is how a clip gets judged at all: MCP has no video content type, so without a sheet a clip is just a URL and a promise. It is also the fastest way to SEE camera drift: measured 2026-08-04, the wander in one clip was a PSNR number until frames sat side by side. The sheet is
| Parameter | Type | Required | Notes |
|---|---|---|---|
| video_id | string | yes | Generated video id (from lab_animate/lab_job_status) — positive integer as string |
| cols | integer | no | Grid columns (default 3) |
| rows | integer | no | Grid rows (default 3). cols x rows = number of frames |
| width | integer | no | Total sheet width in px (default 1280) |
| force | boolean | no | Re-render even if a sheet already exists |
| preview | boolean | no | Attach the sheet itself, downscaled to 512px, instead of only its URL. Default true — showing it is the whole point; pass false to get just the URL. |
See a clip at EXACT seconds: up to 12 frames, in the order you list them, tiled into one image and shown. Use it to check what is on screen where you plan a cut, whether a motion has ended, or whether a face drifted between two moments — lab_contact_sheet spreads frames evenly and cannot answer 'what is at 3.2 s'. A second past the clip's end is rejected by name, not clamped. Works on generated cl
| Parameter | Type | Required | Notes |
|---|---|---|---|
| video_id | string | no | Generated video id (from lab_animate/lab_job_status) — positive integer as string. Give this OR asset_key |
| asset_key | string | no | Storage key of uploaded footage (from lab_add_media / lab_list_assets). Needs project_id |
| project_id | string | no | Project the asset_key belongs to — required with asset_key |
| sekunden | array | yes | Seconds into the clip, e.g. [0.5, 3.2, 3.24]. Order is kept: left to right, then the next row (4 per row) |
| kachel_breite | integer | no | Width of one frame in px (default 480) |
| preview | boolean | no | Show the image inline (default true) |
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; th
| Parameter | Type | Required | Notes |
|---|---|---|---|
| seq_id | string | yes | Sequence id — positive integer as string |
| sekunden | array | yes | Seconds into the finished film, e.g. [0.5, 4.9, 5.1]. Order is kept: left to right, then the next row (4 per row) |
| kachel_breite | integer | no | Width of one frame in px (default 480) |
| profile | string | no | Export profile key (default 'web'); a 9:16 profile gives portrait frames — see lab_export_profiles |
| preview | boolean | no | Show the image inline (default true) |
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 BEF
| Parameter | Type | Required | Notes |
|---|---|---|---|
| job_id | string | yes | Export job id from lab_start_export / lab_list_exports — positive integer as string |
| sekunden | array | no | Seconds into the exported film, e.g. [0.5, 7.0]. Order is kept (4 per row) |
| verteilt | integer | no | Instead of sekunden: this many frames spread evenly over the film |
| kachel_breite | integer | no | Width of one frame in px (default 480) |
| preview | boolean | no | Show the image inline (default true) |
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 (
| Parameter | Type | Required | Notes |
|---|---|---|---|
| art | string | yes | fehler = something is broken; wunsch = something is missing |
| titel | string | yes | One line, e.g. 'lab_capture: black frame for an image clip' |
| text | string | yes | What you called, what you expected, what happened — in a few sentences |
| werkzeug | string | no | The tool it is about, e.g. 'lab_timeline_apply' |
| project_id | string | no | Your project it happened in (only your own projects are accepted) |
| kontext | object | no | Machine-readable details: ids, arguments, error text. Max ~8000 characters as JSON |
Read the sound of a clip (video_id), 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, 16 values per second, up to 60 s per page. Use it to find where music or speech starts, where silence is (below stille_unter), and whether a cut lands on a beat or mid-word — before you move cut points. Continue with `weiter_von_s
| Parameter | Type | Required | Notes |
|---|---|---|---|
| video_id | string | no | Generated video id — its own soundtrack. Give this OR audio_id |
| audio_id | string | no | Audio track id (from lab_list_audio). Give exactly one of video_id, audio_id, asset_key |
| asset_key | string | no | Storage key of an uploaded sound or video file (from lab_add_media). Needs project_id |
| project_id | string | no | Project the asset_key belongs to — required with asset_key |
| von_s | number | no | Start of the page in seconds (default 0) |
| bis_s | number | no | End of the page; at most 60 s after von_s |
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
| Parameter | Type | Required | Notes |
|---|---|---|---|
| video_id | string | no | Generated video id — its own soundtrack. Give exactly one of video_id, audio_id, asset_key |
| audio_id | string | no | Audio track id (from lab_list_audio) |
| asset_key | string | no | Storage key of an uploaded sound or video file (from lab_add_media). Needs project_id |
| project_id | string | no | Project the asset_key belongs to — required with asset_key |
| sprache | string | no | Spoken language (default de) — the same list the backend accepts |
| von_s | number | no | Start of the page in seconds (default 0) |
| bis_s | number | no | End of the page; at most 300 s after von_s |
Review generated assets: set verdict (accepted|rejected|pending) and/or selected. Pass ONE id, or ids for a bulk review — after a generation run there are usually dozens to sort, and clicking through them one by one is why the review fields went unused. Rejected assets drop out of the default listings and become prunable. Note: single-id calls make selected exclusive per scene (one chosen vari
| Parameter | Type | Required | Notes |
|---|---|---|---|
| reference_type | string | yes | What kind of asset these ids refer to |
| id | string | no | Single asset id (positive integer as string). Use this for the per-scene selection |
| ids | array | no | Many asset ids for a bulk review (max 200). Mutually exclusive with id |
| verdict | string | no | Acceptance verdict. Feeds the acceptance telemetry (which provider/mode/price actually produced usable shots) |
| selected | boolean | no | Mark as the chosen variant |
| reason | string | no | Why — stored as verdict_reason, useful when reviewing a rejection later |
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, E
| Parameter | Type | Required | Notes |
|---|---|---|---|
| aktion | string | yes | What to do |
| project_id | string | yes | Project id (from lab_list_projects) |
| deckel_credits | integer | no | anlegen only: the cap in credits. Name it to the person in credits AND in the price list's terms before freigeben |
| lauf_id | string | no | freigeben / stand / beenden: the id from anlegen |
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, preis_hoechstens_credits (with every allowed retry) and reicht against balance, project cap and an active auto run, pl
| Parameter | Type | Required | Notes |
|---|---|---|---|
| aktion | string | yes | plan and preis are free; starten costs credits |
| project_id | string | yes | Project id (from lab_list_projects) |
| jobs | array | yes | One entry per clip, IN ORDER — the same fields as lab_animate (prompt, scene_ref, tool, duration_seconds, resolution, character_refs, location_id, source_image_id …). scene_ref decides the chains: con |
| modus | string | no | hybrid (default): chain within scenes; parallel: every clip alone; sequenziell: one chain over everything |
| uebergang | string | no | Transition at each cut inside a chain; default schnitt |
| ohne_keyframe | boolean | no | 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 c |
| neuversuche | integer | no | Retries per clip after a failed continuity check: 1 (default) or 0 (stop at the first deviation). Name preis_hoechstens_credits to the person before starten. |
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.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| video_id | string | yes | A finished clip (positive integer as string) |
| scene_ref | string | no | Scene for the new image; default: the clip's |
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
| Parameter | Type | Required | Notes |
|---|---|---|---|
| reference_type | string | yes | What kind of asset |
| id | string | yes | Asset id (positive integer as string) |
| neu | boolean | no | Discard an existing result and check again (ignored within 60 s of the last check) |
Browse GENERATED rows (images or videos) — newest first, each with the INPUTS it ran on. Every row carries inputs[] (start/reference images, reference videos, character refs — role + url) and params (model, mode, resolution, seed…). Read those before comparing two runs: a run without its inputs is a claim with a picture attached, and a comparison described as one-variable has more than once tu
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | no | Project id (from lab_list_projects). Omit to search across all projects |
| type | string | no | Which generated rows. Required per project; across projects, omit for both |
| verdict | string | no | PER PROJECT ONLY. Exact verdict filter. Omit to get everything except rejected |
| selected_only | boolean | no | PER PROJECT ONLY. Only the chosen variants |
| include_rejected | boolean | no | PER PROJECT ONLY. Include rejected in the default listing |
| scene_ref | string | no | PER PROJECT ONLY. Only this scene |
| since | string | no | ACROSS PROJECTS. created_at >= this ISO-8601 timestamp (e.g. 2026-08-03T00:00:00Z) |
| until | string | no | ACROSS PROJECTS. created_at <= this ISO-8601 timestamp |
| tool_used | string | no | ACROSS PROJECTS. Exact tool/provider name, e.g. seedance-2.5 |
| cursor | string | no | ACROSS PROJECTS. The next_cursor of the previous page. Opaque — do not build one by hand |
| limit | integer | no | Max rows (per project default 50). Across projects the page is capped at 20 so next_cursor stays exact |
| preview | boolean | no | Attach the pictures themselves, downscaled to 512px, so a generation run can be SORTED by looking instead of by reading prompts. At most 4 per call — narrow the list with scene_ref/limit rather than e |
Aggregated progress of a video batch started by lab_animate_batch. Returns {total, completed, failed, pending, done, items[]} — poll this ONCE per batch instead of calling lab_job_status per clip. done: true means nothing is pending any more (some items may still have failed). Each item carries retry_count (an automatic second attempt happened) and fallback_from (the provider was swapped after a
| Parameter | Type | Required | Notes |
|---|---|---|---|
| batch_id | string | yes | The batch_id returned by lab_animate_batch (format: vb_<hex>) |
Are any FilmLab generations running RIGHT NOW, across ALL projects? Use this before anything that restarts the backend (a deploy recreates the container and kills running jobs, losing paid credits), or to answer 'is the lab busy?'. Unlike lab_job_status/lab_batch_status this needs no id — it lists every job in queued/processing PLUS every direct image/video/audio/vfx generation currently within it
| Parameter | Type | Required | Notes |
|---|---|---|---|
| job_type | string | no | Only this job type, e.g. 'video_generate', from the JOB QUEUE. Omit to see everything, including direct generations — for a pre-deploy check, omitting is usually right. |
| stale_after_seconds | integer | no | How long without progress before a job counts as a zombie rather than running. Default 1800, same threshold as the deploy guard in scripts/deploy_backend.sh. |
Poll the status of an image or video generation started by lab_generate/lab_animate. There is no single-item status endpoint on the backend — this fetches the project's full image/video list and filters by id, so it needs BOTH project_id and id (the id alone is not enough). status inside the returned item's metadata is 'pending'|'completed'|'failed'; when completed, image_url/video_url is populate
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id — required, since there is no global id lookup |
| type | string | yes | Whether the id refers to a generated image or a generated video |
| id | string | yes | The id returned by lab_generate (image) or lab_animate (video) |
| preview | boolean | no | Attach the image itself, downscaled to 512px, so it can be LOOKED at instead of described. Costs one extra fetch and adds roughly 15-25 KB to the answer. Videos carry no still and return no picture — |
| wait_s | integer | no | Wait up to this many seconds (max 80) until the result is rendered AND its prompt check (abgleich) is in, or it failed — instead of polling in quick succession. The answer says gewartet_s. tool_id is |
Suggest independent visual gags for a character and theme. Free text generation, no images or credits spent. Returns anzahl entries with titel, bild_en and bewegung_en: one moment and one strong action each, no story sequence or references between entries. figur accepts a character-sheet id (uses its prompt_prefix_en) or a free-text character description. Select 8–16 suggestions for lab_auto_story
| Parameter | Type | Required | Notes |
|---|---|---|---|
| figur | yes | Existing character-sheet id or free-text character description | |
| thema | string | yes | Theme or setting for the independent gags |
| anzahl | integer | no | Number of suggestions, default 20 |
Auto-generate a storyboard from either script OR situationen (mutually exclusive). An LLM splits script into scenes; situationen bypasses that LLM entirely and generates exactly one frame per entry, ignoring max_scenes. situationen requires figur_id of an existing character sheet with a reference image: every frame uses that character on seedream_5_pro, without creating a new sheet. format selects
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id |
| script | string | no | Screenplay or scene description; provide either script or situationen. The backend splits script into scenes; each scene becomes one image. |
| situationen | array | no | Independent situations, each exactly one frame. Requires figur_id; excludes script and figuren_raten. |
| figur_id | integer | no | Existing character-sheet id with a reference image; required for situationen, only used with situationen |
| format | string | no | Frame aspect ratio for every model, default 16:9 |
| max_scenes | integer | no | Upper limit for the number of scenes, and therefore images charged. Backend default when omitted. |
| model | string | no | Image model for the frames. Default krea_2_medium. Prices per model: lab_list_models. |
| creativity | string | no | Krea 2 creativity setting; ignored by flux_pro. Default medium. |
| style_reference_url | string | no | Shared moodboard image applied to ALL frames for one consistent look. Used by Krea 2 and by the Seedream character-reference path (one additional reference, included in pricing). Must be an asset of t |
| figuren_raten | boolean | no | 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 |
List the available export delivery profiles (web, social_vertical, social_youtube, streaming_hdr, cinema, master, alpha_prores4444, alpha_png_sequence) and quality presets (draft, standard, high). Call this before lab_start_export to pick a valid profile/quality. The two alpha profiles keep transparency (ProRes 4444, or one RGBA PNG per frame delivered as a zip) and are REFUSED unless the sequence
No parameter schema on file.
Start an ASYNC export render of a project sequence. Returns a job_id immediately (status 'queued') — does NOT block. Then poll lab_get_export with that job_id until status is done|failed. Needs the sequence_id to render (an integer from the project's sequences). derivatives asks for extra cut-downs of the SAME render (portrait for social) alongside the main file — their URLs come back in the fin
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) |
| sequence_id | string | yes | Sequence id to render (positive integer as string, e.g. '27') |
| profile | string | no | Delivery profile (default 'web'). See lab_export_profiles. 'alpha_prores4444' and 'alpha_png_sequence' keep transparency and are refused with an explanation unless a clip in the sequence really carrie |
| quality | string | no | Quality preset (default 'standard') |
| include_stems | boolean | no | Also export audio stems separately (default false) |
| ohne_clipton | boolean | no | Leave the clips' OWN audio out of the export (e.g. a video model whose sound is always on) — the film then sounds only from the bound stems and the mixdown (music bed, narrator). Default false: the cl |
| derivatives | array | no | Extra cut-downs rendered from the FINISHED export, on top of the main file. '9x16' is a deterministic crop of the wide render into portrait — what falls outside the portrait frame is gone, not filled |
| derivative_region | string | no | Which part of the wide frame the portrait crop keeps. Default 'center' — pick 'left' or 'right' when the subject stands off to one side, otherwise the crop cuts it in half. |
| ki_kennzeichnung | string | no | How the visible AI disclosure (EU AI Act Art. 50(4)) appears when the sequence contains AI material. Default 'minimal': a small 'KI' mark in the corner for the whole film. 'durchgehend': the larger 'K |
| werk_kuenstlerisch | boolean | no | Confirm the work is artistic, fictional or satirical — only then may the disclosure be limited to the opening or the end card. Set it only when that is true; the choice is recorded with the export. |
| kennzeichnung_umfang | string | no | 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 sc |
Turn a loose idea into a production-ready image or video prompt — the same Dreamer engine the FilmLab web UI uses (modes: beautify, storyboard, polish, format, shorten, expand, simplify, custom, stiluebernahme). beautify GENERATES (a 50-character thought comes back as a full prompt); polish/format/shorten/expand/simplify PRESERVE what is there. medium=video plus depth=skeleton yields the 15-block
| Parameter | Type | Required | Notes |
|---|---|---|---|
| prompt | string | yes | The text to work on — a loose thought is enough for beautify |
| tool | string | no | Optional: the model you will render with, as the registry key from lab_list_models. Decides which family skeleton lays out camera, lens and light — and whether it is a measured rule or the plain appen |
| familie | string | no | Optional, instead of tool: the model family by name when no registry key is at hand. Medium decides whether the image or the video skeleton applies. |
| project_id | integer | no | Optional, only with tool or familie: the project whose Lens Lab optics, Pose Director framing and gaffer light should be laid into the prompt. |
| location_id | integer | no | Optional, only with tool or familie: the location board whose prompt prefix becomes the place block — the same board you will hand to lab_animate/lab_generate. |
| mode | string | no | Default beautify (generates). beautify: Aus der Idee einen vollständigen Prompt bauen — ergänzt Licht, Optik, Kamera, Stimmung | storyboard: Szene in 4–8 nummerierte Panels zerlegen — je Panel ein eig |
| medium | string | no | photo (default) or video — decides the section layout |
| depth | string | no | video only: sketch (5 blocks, default) or skeleton (15 blocks) |
| anlass | string | no | beautify only: what the image is FOR. Default frei |
| duration_seconds | integer | no | video only: the clip length in seconds the ACTION TIMING beats are written to. Default 5 (what lab_animate renders without an explicit duration). Rejected for medium=photo. |
| instruction | string | no | Required for custom (an order, e.g. 'make it darker') and stiluebernahme (a style description) |
| groesse | string | no | Optional: change the shot size of the EXISTING prompt, keeping subject, light and place — a key such as ews, ws, mws, ms, mcu, cu, ecu, macro. Implies mode=custom and needs no instruction. An unknown |
| winkel | string | no | Optional: change the camera angle of the EXISTING prompt — a key such as augen, unter, auf, vogel, frosch, schraeg, ots, pov, profil. Implies mode=custom and needs no instruction; combinable with groe |
| techniken | array | no | Up to three directing technique keys from lab_regie_techniken. Their prompt fragments are appended verbatim after the transform, ordered angle, framing, composition, movement. One angle and one moveme |
| referenzen | array | no | The references the prompt may point at, IN THE ORDER you will pass them to lab_animate/lab_propose. Write @bild1, @video1, @ton1 in your prompt and they come back as the markers the model actually rea |
Run a VFX operation on an image already in the project gallery — the same pipeline the Resolve bridge uses. inpaint (clean plate: what is inside the box disappears, the surroundings close over it) · replace (same path, other intent: something new goes into the box) · relight (no box — the light changes across the whole frame; by default the scene stays exactly as it is, licht_weg 'iclight' instead
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) |
| image_id | string | yes | Id of the source image in the project gallery (from lab_list_assets / lab_generate) |
| operation | string | yes | inpaint: Die rote Werkzeugkiste wird durch eine Holzkiste auf der Werkbank ersetzt. | replace: Derselbe Weg, andere Absicht: in die Box kommt etwas Neues. | relight: Keine Box: die Lichtrichtung wande |
| prompt | string | no | inpaint/replace: what should be seen there instead — required. mask: what should be cut out (e.g. 'the red toolbox') — required. relight: optional, replaces the preset |
| light_preset | string | no | relight only. There is no 'bottom' — the server does not carry one |
| licht_weg | string | no | 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 |
| box_x | number | no | Box left edge as a fraction of image width (0..1) |
| box_y | number | no | Box top edge as a fraction of image height (0..1) |
| box_breite | number | no | Box width as a fraction of image width |
| box_hoehe | number | no | Box height as a fraction of image height |
Poll a VFX operation started with lab_vfx. status is pending|processing|done|failed; when done, result_url carries the finished image. Call repeatedly until done|failed — an image run usually takes under 30 seconds.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| operation_id | string | yes | The operation_id returned by lab_vfx |
Run a video VFX preset on a whole clip. Today only 'gesichter_verpixeln' (pixelate every face) is live. Costs credits per frame — call with dry_run=true first to see the price. With rerender_from (a finished job_id) it re-renders for free with other settings, e.g. exceptions: object ids that stay sharp. Tell the person: "Automatisch verpixelt, ohne Garantie — vor Veröffentlichung prüfen." Poll lab
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id |
| video_url | string | no | HTTPS URL of the clip (project asset) |
| preset | string | no | — |
| effekt | string | no | — |
| ausnahmen | array | no | Object ids to leave unpixelated (rerender only) |
| rerender_from | string | no | job_id of a finished run to re-render for free |
| dry_run | boolean | no | Only return the price |
Poll a video VFX preset job. status is queued|proxy|spur|render|done|failed; progress shows frames done. When done: result_url is the finished clip (give it to the person as karte_ansehen), kontakt_url is the review contact sheet, spur.objekte lists detected faces with ids usable as exceptions in lab_vfx_preset(rerender_from, ausnahmen).
| Parameter | Type | Required | Notes |
|---|---|---|---|
| job_id | string | yes | job_id returned by lab_vfx_preset |
Apply a deterministic colour grade to an image already in the project gallery — no re-generation, no provider, no credits. The look is computed pixel-exact (exposure, saturation, hue, lightness, contrast, film grain) and lands as a new 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 gra
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) |
| image_id | string | yes | Id of the source image in the project gallery (from lab_list_assets / lab_generate) |
| exposure | number | no | Exposure in stops; positive brightens, zero is neutral |
| saturation | number | no | Colour saturation; minimum is greyscale, zero neutral |
| hue | number | no | Hue rotation in degrees; zero neutral |
| lightness | number | no | Lightness; negative darkens, zero neutral |
| contrast | string | no | Contrast curve: high is an S-curve, low flattens it |
| grain | number | no | Film grain amount; zero is none, monochrome |
| from_colorist | boolean | no | Start from the project's colorist crew brief (look/contrast/grain), then apply the sliders on top |
| look | string | no | Named look from the bundle catalogue (e.g. filmlab-neutral, filmlab-warm, filmlab-cool, filmlab-soft, filmlab-punch) — a hand-authored LUT, applied on top of the sliders. The server resolves the name; |
| look_opacity | number | no | Blend of the named look, 0..1 (default 1) |
| exposure_offset | number | no | Exposure offset added after the stops (lifts or crushes blacks); zero neutral |
| exposure_gamma | number | no | Exposure gamma; 1 neutral, above 1 brightens midtones |
| levels | object | no | 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" |
| curves | object | no | 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]]}. N |
| gradient_map | object | no | 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} |
| grain_mono | boolean | no | Grain in black and white (default true); false gives colour grain |
| grain_seed | integer | no | Seed of the grain pattern (default 0) — same seed, same grain |
Suggest a grade look for a project — read-only, no cost. With image_id, includes the image prompt; without it, uses only the colorist crew brief. Returns a recommended look name with a reason and alternatives; apply it with lab_grade(look: …) once the user agrees.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) |
| image_id | integer | no | Generated image id belonging to the project; includes its prompt in the suggestion |
Suggest a FilmLab grade look from a Resolve LUT name or path — read-only, no cost. First call resolve_node_graph_lesen on the local FilmLab bridge (filmlab_bruecke_mcp.py), a SEPARATE MCP server, and pass its lut field here. The agent connects these two calls: this Cloudflare Worker cannot reach the bridge at 127.0.0.1 on the user's computer or fetch the name itself. Only the name is matched; the
| Parameter | Type | Required | Notes |
|---|---|---|---|
| lut | string | yes | LUT name or path from the lut field returned by resolve_node_graph_lesen on the local FilmLab bridge |
Create or read a depth map for a project video in FilmLab: use it for fog, depth of field, relighting or occlusion. Near is white, like Resolve's Depth Map. Free on our own CPU, no credits; processing takes minutes. 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,
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) |
| video_id | integer | yes | Completed video id belonging to this project |
| neu | boolean | no | Start a new depth job instead of reusing the existing map or running job (default false) |
| wait_s | number | no | Wait up to this many seconds for completion (default 0, maximum 15) |
| nur_lesen | boolean | no | Only read: never create a job. Without an existing job the answer is status 'keine' (default false) |
| modell | string | no | Depth engine: v2 (default, sharpest) or vda (steady over time, 16:9 or 9:16 only) |
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 (
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id |
| modus | string | no | kunde (default) or intern |
| auswahl | string | no | gewaehlt (default): the selected take per scene, plus every take without a scene (e.g. a series) that is not rejected; alle: every take that is not rejected. Stars/favourites do not count as a selecti |
| bild_ids | array | no | Exactly these image ids (overrides auswahl) |
| video_ids | array | no | Exactly these video ids (overrides auswahl) |
| schalter | object | no | Switches: prompt, referenzen, aufloesung_dauer, datum, modell, seed, kosten, audio, mini_proxies (480p video proxies). Unknown keys are ignored. |
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.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| job_id | string | yes | The dossier job id returned by lab_dossier |
Poll an export render job by job_id (from lab_start_export). status is queued|processing|done|failed; when done, the result (output url) is included. Call repeatedly until done|failed. NB: this is the EXPORT poll — different from lab_get_generation. Where the address sits depends on the profile: a rendered film is in video_url, but profile alpha_png_sequence delivers a ZIP of RGBA PNGs and therefo
| Parameter | Type | Required | Notes |
|---|---|---|---|
| job_id | string | yes | The export job id returned by lab_start_export |
List past export jobs for a project (each with job_id, status, profile). 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).
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) |
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
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) — positive integer as string |
| art | string | yes | What the file is |
| herkunft | string | yes | Required, no default: 'eigen' = shot, recorded or made by people (no AI generation); 'ki' = generated or altered with AI. Decides the EU AI Act Art. 50 disclosure of every export that uses this file. |
| media_url | string | no | Public http(s) URL of the file. Give this OR file_name |
| file_name | string | no | Name of a local file to upload, with extension. Give this OR media_url |
| content_type | string | no | Media type of the upload, e.g. video/mp4, audio/mpeg — required with file_name |
| abschluss_key | string | no | 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 |
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_
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) — positive integer as string |
| dateien | array | no | Local files to upload: ZIP archives or single PNG/JPG/WEBP |
| quellen | array | no | After the PUT: exactly the quellen from the previous answer's weiter.argumente |
| prompts | string | no | Pasted Midjourney prompts, one per line |
| anker | object | no | Build a look anchor from imported images |
| bilder | boolean | no | true: list the project's imported images |
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
| Parameter | Type | Required | Notes |
|---|---|---|---|
| ziel | string | yes | — |
| ziel_id | string | yes | Character id or location id |
| image_id | string | yes | Image id from lab_umzug {bilder}, lab_get_job result.bildzeilen or lab_generate |
| view | string | no | — |
| personenbezug | string | no | Character only, REQUIRED there: does the image show a real person? |
| likeness_ref | string | no | Character + reale_person only: Likeness Register id |
| beschreibung_ableiten | boolean | no | Location only |
| ersetzen | boolean | no | — |
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 effec
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id — positive integer as string |
| asset_key | string | no | Storage key of the file (from lab_add_media or lab_list_assets). Omit to list |
| herkunft | string | no | Required together with asset_key |
List a project's media assets (image/video/audio) with their URLs. Optionally filter by asset_type. Returns up to 20 with a total count. Each row carries its 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
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) |
| asset_type | string | no | Filter by asset type (optional) |
| preview | boolean | no | Attach the pictures themselves, downscaled to 512px, so you can look at them without fetching anything (older media.andresmarder.com addresses answer a non-browser User-Agent with 403). The worker fet |
Generate a MUSIC track for a project (Stable Audio via fal.ai) — the first step of the rhythm chain, and the only one that costs credits. ASYNCHRONOUS: the call returns immediately with a row whose audio_url is null and metadata.status is 'pending'. Nothing is playable and nothing can be bound yet. Poll lab_list_audio (audio_type 'music') until that row's status is 'completed' and audio_url is
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) — positive integer as string |
| prompt | string | yes | What the music should be. Name genre, instrumentation, mood AND the tempo in bpm if the cut is supposed to sit on the beat — e.g. 'driving techno, four-on-the-floor kick, 128 bpm, no vocals'. A prompt |
| duration_seconds | number | no | Track length in seconds (default 30, Stable Audio's ceiling is 190). Make it at least as long as the sequence you want to cut — lab_apply_rhythm computes durations for the clips that exist and neither |
| scene_ref | string | no | Optional scene label, stored on the row. Useful to tell several tracks of one project apart |
| get_cost | boolean | no | true preflights the credit price and your balance WITHOUT generating anything and without spending quota. |
Generate or CLEAN UP a SOUND track other than music — sound effects, ambience/atmosphere, dialog, a voiceover, FOLEY scored to an existing clip, or the repair kinds that take an EXISTING recording apart instead of inventing one: denoise (take the noise out), split (separate it into stems), isolation (keep the voice, drop the rest). All of it goes through the same audio pipeline as lab_generate_mus
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) — positive integer as string |
| prompt | string | no | What the sound should be. For sfx/ambience: name the source and character of the sound. For dialog/voiceover: the line or text to speak. Required for every art EXCEPT foley — foley watches the clip, s |
| art | string | yes | Kind of track — sfx (a single sound effect), ambience (a continuous atmosphere/soundscape), dialog (a spoken line), voiceover (narration), foley (sound derived FROM an existing clip and synced to what |
| video_id | string | no | The clip to work from. For FOLEY it is required to RUN one; for the repair kinds it is one of the three ways to name a source, and the backend extracts the audio track from it. From lab_list_assets or |
| audio_id | string | no | REPAIR KINDS ONLY, and the best of the three ways to name a source: an existing audio row of this project (from lab_list_audio), which has an owner and an address that belongs to us. Chain it — denois |
| audio_url | string | no | REPAIR KINDS ONLY, and the last resort: a bare address of a sound file. It carries no owner, so nothing can be checked against the project — prefer audio_id or video_id. A provider address is copi |
| stems | array | no | SPLIT ONLY: which parts to separate out. Left out, you get the voice and the rest of the recording, each part as its own audio row. Asking for a subset drops what you leave out — there is no combined |
| duration_seconds | number | no | Desired length in seconds. The backend clamps this to what the chosen provider actually supports for this art — dialog/voiceover ignore it entirely, the length follows the text, and foley ignores it |
| scene_ref | string | no | Optional scene label, stored on the row. Useful to tell several tracks of one project apart |
| get_cost | boolean | no | true reports the price and your balance WITHOUT generating anything and without spending quota. Not drawn from the lab_list_models catalog (that covers image/video models only) — audio pricing follo |
List a project's generated audio rows, newest first — this is the POLL for lab_generate_music. Read two fields: metadata.status ('pending' | 'completed' | 'failed') and audio_url. A pending row has no url, and nothing downstream works with it: lab_bind_audio silently leaves the track empty (resolve-stems only takes rows that carry a url) and lab_beatgrid has no file to open. A failed row carri
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) — positive integer as string |
| audio_type | string | no | Filter by kind. Pass 'music' when polling a lab_generate_music call — that is the kind the music track binds. The repair kinds (denoise, split, isolation) come from lab_sfx and hold cleaned-up version |
| scene_ref | string | no | Filter by the scene label passed at generation time |
| limit | integer | no | How many rows to FETCH from the backend (default 50). At most 20 are SHOWN; total is what the fetch found, so a total of exactly limit means there may be more |
Bind the project's generated audio to a sequence's tracks — ONE call that does both halves of the job, because doing only the first half silently produces a silent film. Half one (POST …/soundmix) creates the four empty tracks (dialog, music, sfx, atmo); half two (POST …/soundmix/resolve-stems) is what actually attaches the audio rows to them. On 2026-08-28 that split cost a complete silent ex
| Parameter | Type | Required | Notes |
|---|---|---|---|
| seq_id | string | yes | Sequence id (from lab_create_sequence/lab_list_sequences) — positive integer as string |
| audio_ids | object | no | Bind EXACTLY these rows instead of the newest/selected one per track, as { music: '12', dialog: '13' }. Named tracks are pinned to these rows, tracks you leave out are pinned empty. Each row must belo |
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 trac
| Parameter | Type | Required | Notes |
|---|---|---|---|
| seq_id | string | yes | Sequence id — positive integer as string |
| tracks | array | no | Tracks to change — only the given fields are written |
| katalog | boolean | no | Return the effect catalogue instead of changing anything |
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. E
| Parameter | Type | Required | Notes |
|---|---|---|---|
| seq_id | string | yes | Sequence id — positive integer as string |
| target | string | no | Loudness target, default broadcast |
| auto_preset | string | no | Run the auto-mix with this preset instead of rendering the mix as set |
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
| Parameter | Type | Required | Notes |
|---|---|---|---|
| seq_id | string | yes | Sequence id — positive integer as string |
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, saturatio
| Parameter | Type | Required | Notes |
|---|---|---|---|
| seq_id | string | yes | Sequence id — positive integer as string (lab_list_sequences) |
| clip_id | string | no | The clip to grade (from the listing); omit with programm:true |
| programm | boolean | no | Grade the whole programme instead of one clip |
| grade | object | no | Fields to set — see description; omit to list clips and grades |
| zuruecksetzen | boolean | no | Start from a neutral grade before applying grade |
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
| Parameter | Type | Required | Notes |
|---|---|---|---|
| seq_id | string | yes | Sequence id — positive integer as string |
| clip_id | string | no | Clip to measure |
| zeit_s | number | no | Timeline position in seconds (picks the clip there; within a clip_id: the frame) |
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)
| Parameter | Type | Required | Notes |
|---|---|---|---|
| seq_id | string | yes | Sequence id — positive integer as string |
| szene | string | no | Only this scene (scene_ref from lab_shots); default: every scene with two or more shots |
| clip_ids | array | no | Compare exactly these shots instead of the scenes from lab_shots |
| referenz_clip_id | string | no | The shot the others are matched to; default the first of the scene |
Generate SOUND EFFECTS for a whole sequence, shot by shot — Simon Meyer's pass: every shot is muted, padded with black frames up to the model's minimum length, re-rendered by Seedance 2.5 in editing mode at its low resolution with sound on, and only the generated sound is kept, stretched back to the original timing (the black padding is the sync marker) and laid at the shot's position. The result
| Parameter | Type | Required | Notes |
|---|---|---|---|
| seq_id | string | yes | Sequence id (from lab_create_sequence/lab_list_sequences) — positive integer as string |
| get_cost | boolean | no | Return the price in credits WITHOUT starting anything — per shot over the seconds actually sent, at the rate lab_list_models lists for the model. Do this first; long sequences add up. |
| hinweis | string | no | One line about the setting that applies to every shot, e.g. 'kitchen, wooden floor, rain on the window'. Helps the model pick the right room sound. Leave it out if the shots differ too much. |
Measure the TEMPO of the sequence's bound music track and store the beat grid — opens the real file with ffmpeg and analyses it, no guessing and no provider, so it costs nothing but a few seconds. Writes bpm and metadata.beat_grid on the audio row; it does NOT touch the timeline (timeline_geaendert: false). Deterministic and cached: a second call returns the same numbers without downloading
| Parameter | Type | Required | Notes |
|---|---|---|---|
| seq_id | string | yes | Sequence id (from lab_create_sequence/lab_list_sequences) — positive integer as string |
| neu_messen | boolean | no | Measure again even though a result for this exact file already exists. Default false. The measurement is deterministic — the same file gives the same number, so this only helps after the track behind |
| takt | integer | no | Beats per bar (default 4). INPUT, not detection — time-signature detection is explicitly out of scope. It only affects where the downbeats fall, which is what the rhythm 'auf die Songstruktur' snaps t |
Compute the sequence's clip durations from the project's cutting preset and — when the tempo allows it — pull the cut points onto the measured beat grid. WRITES the timeline; costs nothing. The old duration of every changed clip is kept in clip.metadata.dauer_vorher, so one undo step exists (a second differing run overwrites it — there is no history). Clip count is never changed: no clip is adde
| Parameter | Type | Required | Notes |
|---|---|---|---|
| seq_id | string | yes | Sequence id (from lab_create_sequence/lab_list_sequences) — positive integer as string |
| toleranz_s | number | no | How far a cut point may travel to land on a beat, in seconds (default 0.12 — three frames at 25 fps). 0 disables snapping entirely and only recomputes the durations |
| trotz_unsicherem_tempo | boolean | no | Snap onto a grid whose own measurement reports verlaesslich: false. Default false, and that default is the honest one: below the threshold the detector has not confirmed it found the pulse. Set it o |
Ask what clip durations the project's cutting preset WOULD give a sequence — and change nothing (angewendet: false). Use it to see the consequence before lab_apply_rhythm writes it, or to size a sequence that has no clips yet (pass anzahl). It knows nothing about the measured beat grid: the tempo it uses is the text from the preset's music brief ('mittel bis schnell, 100–128'), which is a prom
| Parameter | Type | Required | Notes |
|---|---|---|---|
| seq_id | string | yes | Sequence id (from lab_create_sequence/lab_list_sequences) — positive integer as string |
| anzahl | integer | no | How many shots to distribute. Omit to use the sequence's existing clip count — required if the timeline is still empty, which otherwise answers 400 |
Dub a sequence into another language: either a ready audio track (en_audio_url — e.g. the one lab_dub_tts just produced) OR a cloned voice reading a line of text (voice_id + dub_text), then a controlled visual lipsync runs over the sequence's own footage (ROI-crop + composite for a long static talking-head shot, or the full-frame veed_v2 path for multi-shot sequences and shots where the mouth is p
| Parameter | Type | Required | Notes |
|---|---|---|---|
| seq_id | string | yes | Sequence id (from lab_create_sequence/lab_list_sequences) — positive integer as string |
| language | string | yes | Target language for the dub, e.g. 'de', 'fr', 'es' — drives the cloned voice's TTS. Required: there is no silent default here. |
| backend | string | no | Lipsync engine. Omit to use the backend default (replicate — ROI-crop, best for one long static talking-head shot). veed_v2 renders the full frame instead and is the pick for multi-shot sequences or a |
| en_audio_url | string | no | URL of a READY dub track to lay under the sequence — typically the audio_url lab_dub_tts just returned. Mutually exclusive with voice_id+dub_text: a dub has exactly one audio source, and picking one s |
| voice_id | string | no | A cloned voice's id (lab_cloned_voices.id, from lab_voice_clone or lab_list_voices) — positive integer as string. Required together with dub_text, and mutually exclusive with en_audio_url. |
| dub_text | string | no | The line(s) this cloned voice should read, in the target language. Required together with voice_id. |
| enable_lipsync | boolean | no | Whether to run the visual lipsync pass at all. Omit to use the backend default (on). Off only swaps the audio track and skips the mouth-sync render entirely. |
| likeness_ref | string | no | A Likeness Register consent id (likeness.thefilmradar.com) for the person whose mouth this dub re-syncs. Checked live against the register before anything is spent; a revoked or unknown id refuses the |
| einwilligung | boolean | no | Consent of the person whose mouth this dub re-syncs, when there is no Likeness Register id for them yet. Required together with einwilligung_notiz if likeness_ref is not given — a dub always alters a |
| einwilligung_notiz | string | no | Free text: who consented, when, and for what — required together with einwilligung. Goes on record with the generated clip. |
| get_cost | boolean | no | true reports the price and your balance WITHOUT starting a dub and without spending quota. The number is computed by the same function that later charges you, from THIS sequence: a sound rate per vi |
List the ElevenLabs TTS voices available for lab_dub_tts's voice_id — this is the EN-dub-track text-to-speech voice list, NOT a project's cloned voices (those are lab_list_voices). Reads only — no state changes, no credits. If ELEVENLABS_API_KEY isn't configured on the backend the list comes back empty and configured is false.
No parameter schema on file.
Generate the EN-dub audio track for a sequence via ElevenLabs TTS — SYNCHRONOUS, returns a ready audio_url immediately, no job_id and nothing to poll. Optionally pads the track with silence up to the sequence's own length so a shorter reading doesn't shorten the final cut. Feed the resulting audio_url into lab_dub's en_audio_url to lipsync the sequence to this track.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| seq_id | string | yes | Sequence id (from lab_create_sequence/lab_list_sequences) — positive integer as string |
| text | string | yes | The line(s) to speak. Kept short — very long text is rejected by the backend before anything is spent. |
| voice_id | string | no | An ElevenLabs voice id, from lab_dub_voices. Omit to use the backend's configured default voice — NOT a lab_cloned_voices id. |
| pad_to_video | boolean | no | Pad the generated track with silence up to the sequence's own duration if the reading comes out shorter. Omit to use the backend default (on). |
| get_cost | boolean | no | true reports the price and your balance WITHOUT generating anything and without spending quota. This one is billed flat, one sound rate per run — the length of your text does not change it. Not draw |
Clone a voice from real audio or video material into a project (fal.ai minimax voice-clone) — the source for lab_voice_tts and for lab_dub's voice_id+dub_text path. SYNCHRONOUS: the clone runs inside the request and can take a while to return; there is no job_id to poll. The source needs a clean speech track of workable length — too short or silent material is rejected before anything is spent. Vo
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) — positive integer as string |
| name | string | yes | A label for this cloned voice, shown in lab_list_voices — needed to tell several clones of one project apart later. |
| sample_audio_url | string | yes | URL of the source audio or video the voice is cloned from. Needs a real, sufficiently long speech track — material without one is rejected before anything is spent. |
| get_cost | boolean | no | true reports the price and your balance WITHOUT cloning anything and without spending quota. A clone is billed per clone (a MiniMax clone costs far more than a Fish clone — ask with get_cost) — the |
| provider | string | no | Which voice house clones it. Omit to stay on the default path — an existing workflow does not change vendor just because another one exists. The choice sticks to the voice: whichever house made it is |
| einwilligung | boolean | no | Consent of the person whose voice is being uploaded. Required on the fish_audio path, which refuses without it before anything is charged. This is not the moderation gate: that one reads the label for |
| likeness_ref | string | no | 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 mar |
Speak text in a project's cloned voice (via lab_voice_clone) — SYNCHRONOUS, returns a ready audio_url, no job_id. The voice house is whichever one cloned this voice; you do not pick it here. Consent-sensitive like the clone itself: only speak text you have the right to put in that voice's mouth.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) — positive integer as string |
| voice_id | string | yes | A cloned voice's id (lab_cloned_voices.id, from lab_voice_clone or lab_list_voices) — positive integer as string, NOT the raw provider voice id. |
| text | string | yes | The line(s) to speak in this voice. |
| provider | string | no | Cross-check, not a choice: the house that cloned this voice is the one that speaks with it, because a voice id from one house means nothing to the other. Pass it only to assert what you believe the vo |
| get_cost | boolean | no | Price this call instead of running it: returns the estimate and the balance, charges nothing, produces no audio. Worth doing before a long passage, because both houses bill by the size of the text, no |
List a project's cloned voices (lab_voice_clone results) — id, label, voice house, sample and preview URLs. This is where a voice_id for lab_voice_tts or lab_dub comes from, and where you look up which house a voice belongs to before pricing it. Both houses are listed unless you narrow it. Reads only — no state changes, no credits.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) — positive integer as string |
| provider | string | no | Narrow the list to one voice house. Omit it and both come back, which is the normal case — a project can hold voices from either. An unknown value is refused rather than answered with an empty list: ' |
Render a new clip FROM the motion of an existing one: your reference clip leads (camera move, blocking, timing), the model restyles what happens in it. Pass the clip's URL directly — the one you already have from lab_list_assets (asset_type 'video'), lab_job_status or lab_review_queue; nothing is looked up. Reference images bind cast, place and look; in_sec/out_sec cut the reference server-side be
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) — positive integer as string. On this path it travels in the request BODY, not in the URL, but it is just as required: the new clip is filed under this project. |
| reference_video_url | string | no | URL of the clip whose motion is taken. Use the url/video_url a previous answer gave you (lab_list_assets with asset_type 'video', lab_job_status, lab_review_queue) — never a hand-built address: the bu |
| prompt | string | yes | What the new clip should show. Describe it — do NOT phrase it as an instruction to edit or extend the reference; some models classify the run by the verb and then reject the aspect ratio and duration |
| tool | string | no | Video model id — copy it verbatim from lab_list_models (kind: video), and only models the catalog marks v2v take a reference clip at all. Omit to let the backend use its own default for this path. Dur |
| duration_seconds | number | no | Length of the NEW clip. Must lie inside the chosen model's duration grid from lab_list_models — the per-model ceiling is enforced by the backend and rejected rather than silently clamped. |
| character_ref_urls | array | no | Ready image URLs that bind the cast's identity. The name says URLs on purpose: lab_animate's character_refs takes character sheet IDS, this path takes ADDRESSES, and the two are not interchangeable. |
| referenzen | array | no | The typed successor of character_ref_urls: each reference says WHAT it is, so a place or a look no longer has to travel disguised as a character. Since 2026-09-03 it carries all three channels, not ju |
| use_depth | boolean | no | Condition the run on a depth pass of the reference clip. Defaults to ON in the backend; pass false to opt out. Models that do not have a depth stage ignore it — the answer says so rather than pretendi |
| aspect_ratio | string | no | Output aspect ratio on this path, written as width:height or 'auto'. Only models whose lab_list_models entry takes it on the reference path accept it; for any other model the backend refuses it before |
| resolution | string | no | Render resolution on this path, copied verbatim from the model's resolutions in lab_list_models. The run is priced at the resolution you choose — the low tier costs a fraction of the default — so pass |
| generate_audio | boolean | no | Let the model generate sound with the clip — only models whose lab_list_models entry can output audio take it on this path. Omitted = no generated sound. Generated audio REPLACES any voice in the refe |
| ton | string | no | Which sound the result carries. quelle: the reference clip's own audio is laid back under the new picture after generation — the way to keep a spoken take, since models that regenerate audio replace t |
| task | string | no | reference (default): the references guide a new clip. editing: the picture of the reference clip stays and only what the prompt names changes — e.g. 'keep the picture, generate matching sound effects, |
| first_frame_url | string | no | Guiding frame for the START of the new clip (image URL). Only the wan_vace path binds guiding frames to the provider — with any other model the backend REJECTS this field instead of swallowing it, bec |
| last_frame_url | string | no | Guiding frame for the END of the new clip (image URL). Same rule as first_frame_url: wan_vace only, rejected elsewhere rather than dropped. |
| in_sec | number | no | 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. |
| out_sec | number | no | End of the excerpt in the reference clip, in seconds. Must lie behind in_sec; both are set together or neither. |
| get_cost | boolean | no | Preflight: return the price in credits and your balance WITHOUT generating and without spending anything, reading the same catalog as lab_list_models. Do this before a long take or when the user shoul |
| wechsel_von | string | no | The model id this call switches AWAY from (as listed in lab_list_models), with the same references as before. The answer then carries wechsel: which references the switch cuts off and why, and which |
| kamerapfad | object | no | 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 |
Relight and restyle an EXISTING clip while the performance stays untouched (Beeble Switch X): lighting, background and props change, the subject and its motion do not. The source is the clip of a generated-video row — or, with asset_id, an uploaded file that stands in for it. in_sec/out_sec cut the source server-side first, so a long take can be transformed in pieces. ASYNCHRONOUS: a new video row
| Parameter | Type | Required | Notes |
|---|---|---|---|
| video_id | string | yes | Generated-video id (from lab_animate/lab_job_status/lab_review_queue) — positive integer as string. ALWAYS required, also together with asset_id: this row anchors the run (project, scene, billing) and |
| asset_id | string | no | R2 asset key of an uploaded video (the key from lab_list_assets, asset_type 'video') to transform INSTEAD of the row's own clip. The row from video_id still supplies project and scene; only the pixe |
| transformation_prompt | string | yes | What the clip should look like afterwards — light, place, props. The subject and its performance are preserved by the model; describing them again does not help. |
| alpha_mode | string | no | How the subject is cut out from its background. Omit to let the backend decide ('auto'); the other modes fill, take a supplied matte, or work on a selection. |
| resolution | string | no | Output tier of the transform. This is Switch X's OWN tier list, not one of the video-model resolutions in lab_list_models — that catalog covers generation models and has no entry for this path. The ti |
| in_sec | number | no | Cut the source server-side before it reaches the provider: start of the excerpt, in seconds. Only together with out_sec. What is billed is the MEASURED length of the cut, not out_sec minus in_sec. |
| out_sec | number | no | End of the excerpt, in seconds. Must lie behind in_sec; both are set together or neither. |
| get_cost | boolean | no | true returns the published rate per unit and your balance WITHOUT transforming and without spending anything — NOT a total. Switch X charges by the MEASURED length of the source, which only the serv |
Enlarge an EXISTING clip (Topaz, passed through fal): same shot, same length, same sound — more pixels. There is no prompt here; nothing is re-imagined, the frames are scaled. The source is the clip of a generated-video row. Both the length and the source height are measured server-side before anything is charged, and a source too tall for the larger factor is refused rather than run. ASYNCHRONOUS
| Parameter | Type | Required | Notes |
|---|---|---|---|
| video_id | string | yes | Generated-video id (from lab_animate/lab_job_status/lab_review_queue) — positive integer as string. The row must already have its clip; a run still pending is refused, and nothing is charged for askin |
| faktor | string | no | How many times larger, per side. Omit for the smaller one. Whichever you pick, the RESULT has to stay inside the published rate tiers — a source too tall for the factor you asked for is refused by nam |
| get_cost | boolean | no | 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 out |
| max_credits | integer | no | The most you agree to pay — pass the amount from get_cost that the person confirmed. If the measured price is higher when the run starts, it is refused before anything is charged. |
Produce ONE element on a transparent background: generated, then cut out and stored as an alpha PNG in the project's gallery. This is the counter-move to the one-shot lottery — cast, props and foreground pieces are made SEPARATELY, arranged as a set afterwards and only then unified, so a wrong hand or a wrong lamp is re-made alone instead of re-rolling the whole frame. The element is deliberately
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) — positive integer as string. Travels in the URL; the element is filed in this project's gallery. |
| prompt | string | yes | What the element shows — the OBJECT or the PERSON, not the scene around them. The backend appends an isolation clause (single subject, plain seamless background, even light) so the cut-out has a clean |
| layer_type | string | no | Which kind of element this is — it picks the isolation clause: 'cast' full-body person, 'prop' single object, 'foreground' a foreground piece, 'background' a wide backdrop plate WITHOUT people, 'crowd |
| scene_ref | string | no | Scene label (e.g. 'SZ 04'). Stored on the row, so the element can be matched back to a shot list and reviewed per scene with lab_review_queue. Omit it and the element is an orphan in the gallery. |
| metadata | object | no | Free-form JSON stored alongside the element (e.g. { note, parent_id }). Merged into the row's metadata next to the fields the pipeline sets itself (kind, layer_type, status) — not interpreted. |
| get_cost | boolean | no | Preflight: return the price in credits and your balance WITHOUT generating and without spending anything. There is no model to pick on this path — the cut-out runs on the house image model and is bill |
Reconstruct a real place in 3D from a scan clip: keyframes are pulled from the clip server-side and turned into a point cloud / splat on the location board, so a scouted room can be looked at from angles nobody filmed. THE SCAN IS NOT MADE HERE — it is a walk-around clip uploaded by the FilmLab camera app together with the phone's lens data. This tool takes one that already exists; lab_list_locati
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) — positive integer as string. The scan must belong to it; a scan of another project is not found rather than borrowed. |
| image_id | string | yes | Id of the SCAN row (from lab_list_location_scans) — positive integer as string. It is a row in the image gallery whose tool is the location scanner; a normal generated image with that id is rejected, |
| engine | string | no | Which reconstruction path. Omit for the backend default. The second path is scene-scale and needs its model configured on the backend — where it is not, the answer says so instead of falling back sile |
| max_photos | integer | no | How many keyframes are pulled from the clip and handed to the reconstruction. Omit to let the engine use its own count — more frames mean a wider parallax baseline and a slower run. |
List a project's location scans with their reconstruction state — this is the POLL for lab_location_recon and the place the scan ids come from. Read status: 'pending' (clip uploaded, nothing reconstructed yet), 'reconstructing', 'done' (splat_url/glb_url/board_url are filled), 'failed' (error says why). Listing is what ADVANCES a running reconstruction from the outside world into the row, so cal
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) — positive integer as string |
Is everything wired? Backend reachability and latency, identity, credit check, catalog age, last error of this account, host widget support. Traffic light plus one sentence per point. Read-only, free.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| problem_report | boolean | no | Return the same findings as one block of text to paste into a bug report. This covers the MCP side only — server version, backend health, last failed job of this account. The Resolve bridge log lives |
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 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 Film
| Parameter | Type | Required | Notes |
|---|---|---|---|
| project_id | string | yes | Project id (from lab_list_projects) — every node runs in this project |
| workflow | object | yes | The Flow (Pipeline) as a FilmOS workflow object, schema_version "1" |
| inputs | object | no | Values for the workflow's inputs, referenced as {{name}} |
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 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
| Parameter | Type | Required | Notes |
|---|---|---|---|
| angebot_id | string | yes | From lab_flow_angebot |
| workflow | object | yes | Exactly the workflow that was quoted |
| inputs | object | no | Exactly the inputs that were quoted |
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 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
| Parameter | Type | Required | Notes |
|---|---|---|---|
| lauf_id | string | no | From lab_flow_starten |
| angebot_id | string | no | From lab_flow_angebot — finds the run started from this offer (when lab_flow_starten's answer was lost) |
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 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. A run
| Parameter | Type | Required | Notes |
|---|---|---|---|
| lauf_id | string | yes | From lab_flow_starten |
- Every tool — any call limit is its publisher’s, not ours
- No card, and mcprush charges nothing for it
- Runs at its publisher’s own address — this marketplace is not in the path
- Nothing to cap, because mcprush bills nothing
What counts against your monthly calls
| Tool | Unit | Calls used | Out of the allowance |
|---|
Nothing here is billable: mcprush charges nothing to install FilmLab or to call it, at any volume.
Two independent axes, because powerful and malicious are different questions. The grade is threat only. The capability level is blast radius, and it is never a penalty on the grade — it is priced as one subtract-only term in the score, where you can see it.
This listing is an address its publisher runs, and you connect to it directly — this marketplace is not in the path. The scanner reads packages and public source, and an address is neither. So there is no grade — not a withheld one, an unmeasured one.
Release history
This is an address its publisher runs: which release it serves is theirs to choose, so there is nothing here to pin. The history below is for reading; the current release on file is 1.1.1.
No release note was published with this version.
One review per account, from a signed-in account that does not publish this listing. Nothing else is asked — you can say what you think before you install it. Publishers can reply once per review, and a review can be edited or deleted by whoever wrote it.
Any signed-in account that does not publish FilmLab can review it, once — before installing it or after. A review from an account that has installed it is marked as one.
Nobody has reviewed this listing. The rating on the card is the mean of the reviews written here and nothing else, so there is no rating until somebody writes the first — which takes a signed-in account that does not publish it, and nothing else.