assign_library_character
ChatGPTAdd a character from the user's character library to their Atlabs story (library_character_id from list_library_characters), like the cast's "Add from library". It keeps its library name unless name is given; the name must be new for this story. When its portrait is not in the story's style yet, Atlabs redraws it in that style in the background, charged like the web app's redraw. If the user has this story open in the Atlabs editor, tell them to reload it to see the change.
assign_library_location
ChatGPTAdd a location from the user's location library to their Atlabs story (library_location_id from list_library_locations), like the location form's Library tab. Its image is copied as is, nothing is drawn: free. It keeps its library name unless name is given; the name must be new for this story. If the user has this story open in the Atlabs editor, tell them to reload it to see the change.
assign_library_product
ChatGPTAdd a product (object) from the user's library to their Atlabs story (library_product_id from list_library_products), like the cast's "Add from library". It keeps its library name unless name is given; the name must be new for this story. When its portrait is not in the story's style yet, Atlabs redraws it in that style in the background, charged like the web app's redraw. If the user has this story open in the Atlabs editor, tell them to reload it to see the change.
create_blank_story
ChatGPTStart a new, empty Atlabs story for the user - the web app's "Start from scratch": one empty scene, in language (default English), the image_style_id you chose (every portrait and scene image is drawn in it, and it can't be changed later) and aspect_ratio. Only for users on a paid plan. Free. Call it at the end of step 1 below. Build the whole story yourself in these steps, in this order, without stopping for the user's yes: decide every choice for them and keep going. Ask only for data you can't infer (e.g. no story idea at all yet). If the user later wants to change an earlier step, go back to it and redo it from there. 1. Settings - choose them from the request: language (the user's, else English); the look (list_image_styles: pick the style that fits the idea); aspect ratio (9:16 for Reels/Shorts/TikTok, 16:9 for YouTube, else 9:16). Don't pick a voice: the story has a default one. Then create_blank_story. 2. Script - write the story and split it into scenes: for each, the line it says and what it shows. Save it: scene 1 exists already, add the others in order with create_scene, and save each scene's line with set_scene_text. 3. Cast - for every recurring character, location and product, write its name and look and create it (create_character / _location / _product). Their portraits are drawn in the story's style and show in get_story's cast once ready. 4. Voiceovers - for each scene in order: scene_edit_voiceover with its line. 5. Scene images - one scene at a time, from scene 1: write the image prompt, tagging the cast by their mention (@Name) so they look the same in every scene, and run scene_edit_image. 6. Check each image - get_result shows it. Then go to the next scene (step 5). Animate (scene_edit_motion) or lip sync (scene_edit_lipsync, always last) a scene only if the user asked for a video or lip sync. 7. Final touches - captions on (set_captions_shown) and background music that fits (list_music, then set_background_music). Then show the result (get_story_assets) and say in a few lines what you made and the credits spent. Change a voice (set_narrator_voice, set_character_voice) or export (export_story) only if the user asks.
create_character
ChatGPTAdd a character to the user's Atlabs story, and draw its portrait. visual_appearance is what the portrait shows; the other fields describe who they are. voice_code (from list_voices) is the voice they speak with. Use the name and look the user gave; otherwise write them yourself to fit the story. The name must be new for this story. Free: no price. Atlabs draws its portrait in the background; once drawn it shows in get_story's cast with the mention a scene_edit_* prompt tags it by. If the user has this story open in the Atlabs editor, tell them to reload it to see the change.
create_location
ChatGPTAdd a location to the user's Atlabs story, and draw its portrait. description is what the place looks like (required). Use the name and look the user gave; otherwise write them yourself to fit the story. The name must be new for this story. Free: no price. Atlabs draws its portrait in the background; once drawn it shows in get_story's cast with the mention a scene_edit_* prompt tags it by. If the user has this story open in the Atlabs editor, tell them to reload it to see the change.
create_product
ChatGPTAdd a product to the user's Atlabs story, and draw its portrait. visual_appearance is what the portrait shows. Use the name and look the user gave; otherwise write them yourself to fit the story. The name must be new for this story. Free: no price. Atlabs draws its portrait in the background; once drawn it shows in get_story's cast with the mention a scene_edit_* prompt tags it by. If the user has this story open in the Atlabs editor, tell them to reload it to see the change.
create_scene
ChatGPTAdd an empty scene to the user's Atlabs story: no text, and one empty shot. It speaks with the narrator's voice. Ask the user where it goes; with no position it is added last. position is 1-based. Free. Fill it with scene_edit_voiceover (its words) and scene_edit_image or set_shot_media (its picture). If the user has this story open in the Atlabs editor, tell them to reload it to see the change.
create_shot
ChatGPTAdd an empty shot to a scene of the user's Atlabs story (a scene can show several shots one after another). Ask the user where it goes; with no position it is added last. position is 1-based. Free. Fill it with scene_edit_image or set_shot_media. If the user has this story open in the Atlabs editor, tell them to reload it to see the change.
create_story
ChatGPTCreate a story from the ready plan made with plan_story, like a MiniTool: pass its session_id (plan_mode_session_id) and the chosen ai_output_mode: STORYBOARD (images), VIDEO_PREVIEW (preview video), or VIDEO (full video). Call it only after the user clicks Start in the plan panel ("Start my <mode> for <N> credits."), with approved_credits=N: the call prices the plan as saved now and starts it at once, charging credits. If the price is now above N it is refused and nothing starts: tell the user the new price and let them click Start again. Once started, reply with one short status line and story_url as a clickable full-domain link; do not recap the plan or the panel choices. Then call get_story_generation_status once: its panel shows live progress. Then call wait_for_story again and again (up to 45 seconds per call) and write nothing in between. When it is done, failed or paused, reply with story_url as a clickable full-domain link. After 10 minutes it says to stop: say in one line that it is still generating and ask whether to check again; on a yes, call wait_for_story again. Never infer completion from the clock. Use get_story to read the story and get_story_assets to inspect generated assets. Export is a separate action with export_story; do not promise an exported video here. If starting failed after submission, call create_story again with the same arguments: it finds the existing story at zero additional start credits and retries dispatching it, never creates another.
edit_character
ChatGPTEdit a character of the user's Atlabs story (element_id from list_story_characters), like saving the cast's edit modal: only the fields given change. Which fields can change depends on where the portrait came from (editable_fields in list_story_characters); a drawn portrait's look (visual_appearance, clothing, age, gender, ethnicity), a library pick's clothing, or an upload's restyle (apply_style_transfer) redraws the portrait in the background, charged like the web app's redraw; a rename alone redraws nothing. height_cm only matters in stories that size characters. Change a voice with set_character_voice. Scenes already made keep the old look until they are regenerated. If the user has this story open in the Atlabs editor, tell them to reload it to see the change.
edit_location
ChatGPTEdit a location of the user's Atlabs story (element_id from list_story_locations), like saving the location form: only the fields given change. A drawn location (portrait_origin CREATE) with a new description is redrawn in the background, charged like the web app's redraw; a rename alone redraws nothing. An uploaded location only takes a new name; a library pick keeps its library image. Scenes already made keep the old look until they are regenerated. If the user has this story open in the Atlabs editor, tell them to reload it to see the change.
edit_product
ChatGPTEdit a product (object) of the user's Atlabs story (element_id from list_story_products), like saving the cast's edit modal: only the fields given change. Any real change - even a rename - redraws the portrait in the background, charged like the web app's redraw. apply_style_transfer restyles an uploaded or library image into the story's style. Scenes already made keep the old look until they are regenerated. If the user has this story open in the Atlabs editor, tell them to reload it to see the change.
export_story
ChatGPTExport the story to a video. Only for MAKING an export - to read one, use get_story_export. Steps: 1. Call export_story(story_id), with a resolution only if the user asked for one (default 2K). It starts the render at once; its credits are charged when it finishes. 2. Call get_story_export(story_id) until its status is READY (usually a few minutes). A story already exported can be exported again (the story changed, or the user wants another resolution): that is a new render and costs credits again, so export again only when the user asked for a new export, and say what it cost. While one is still rendering this is an error - call get_story_export until its status is READY.
generate_image
ChatGPTMake images from a text prompt, optionally guided by the user's reference images (e.g. edit a photo, keep a product or character consistent). Steps: 1. Work out what the user gave, then read the model list, list_models(tool="generate_image") (the default model comes first): reference or photo to edit -> upload each and pass them as reference_media_ids text only -> no files If the files don't fit a model, the call says which models take them and how to fix them. 2. Choose the model yourself from that list: the default unless the user named one or another fits the request clearly better (references, text in the image, style). 3. Call generate_image with that model. Leave resolution and quality out unless the user asked for them, so the model's defaults apply. It runs at once and returns a request_id.
generate_music
ChatGPTMake a song or instrumental from a description. The models are in list_models(tool="generate_music") (default first), each with whether it takes lyrics, a mood image or force_instrumental, and the exact duration_seconds values it allows (none: it picks its own length). If the user wants vocals but gave no lyrics, write them yourself (for MiniMax) or use ElevenLabs or Lyria. Steps: 1. Call generate_music. It runs at once and returns a request_id.
generate_video
ChatGPTMake a video: animate a start image, go from text to video, or build a video from reference images, videos or audio. Videos take a few minutes. Steps: 1. Work out what the user gave, then read the model list, list_models(tool="generate_video") (the default model comes first): an image to animate -> upload it and pass it as start_frame_media_id a text idea only -> no files people/products/voice -> upload each and pass them as reference_*_ids as references If the files don't fit a model, the call says which models take them and how to fix them (trim, upscale, reframe). 2. Choose the model yourself from that list: the default unless the user named one or another fits the request clearly better (length, audio, references). 3. Call generate_video with that model and options it supports (duration in seconds, aspect ratio, resolution, audio). It runs at once and returns a request_id.
get_account
ChatGPTThe user's own Atlabs account: their name and email, their credit balance, and their plan (whether it is paid, its name and status, when it renews or ends). Read it to answer 'how many credits do I have' or 'what plan am I on'. The balance here is their general one; a MiniTool's own price can show MORE credits available, because some credits are only spendable on certain tools - for whether one generation is affordable, trust that tool's price.
get_background_music
ChatGPTWhat the story plays under its scenes now: the track (name, genre, moods, length, preview link), whether music is on, and its volume (0-1).
get_result
ChatGPTWait for a MiniTool job by request_id and show its outputs. Each call waits up to 45 seconds and returns as soon as the job finishes: "success" comes with outputs (url and media_type each) and a player in the chat. Still "created" or "processing": call it again with the same request_id (for at most 10 minutes; its next_step says when to stop). A failed job is a tool error. Showing the result: - The chat app shows the outputs itself (image, playable video or audio). - One short line on what was made. Never paste a file's URL into your reply unless the user asks for a link: the player has its own Download and Open buttons, and the link expires. - Say which model and options were used and the credits spent, in one line, from the call's answer (this result does not repeat them). - Offer 2 or 3 next steps that fit, e.g. upscale_media, reframe_media to another aspect ratio, or generate_video to animate an image. Each output's media_id goes straight into the next tool: nothing needs re-uploading.
get_scene_assets
ChatGPTOne scene of a story: each shot's current file and its earlier generations (newest first), and the same for the scene's voiceover. Any media_id here can go to show_media, to a MiniTool, or back onto a shot with set_shot_media.
get_scene_captions
ChatGPTOne scene's captions: each word with its start and end in seconds from the scene's start, where the words come from (the voiceover, or a lip-sync clip's sound), and whether captions show in this scene and in the story. A new voiceover replaces them.
get_story
ChatGPTOne story: its scenes, length, the inputs the user gave it (prompt, script, style, track, avatar - whatever its flow asked for), and its latest export with a fresh download link when that is ready. Each scene carries the scene_id scene_edit_voiceover takes. cast lists its characters, products and locations: the mention a story-edit prompt tags each by, its portrait, and the element_id set_character_voice takes.
get_story_assets
ChatGPTThe media a story is built from, as media_ids any MiniTool takes. A visual also carries the aroll_id and shot_number of the shot it is in: the handle scene_edit_image, _motion and _lipsync take. A scene can hold several shots, so a media_id alone does not say which shot to edit.
get_story_export
ChatGPTThe story's latest exported video: its status, resolution and a download link once it is READY. Null until it has been exported.
get_story_generation_status
ChatGPTA story's live progress panel: progress, current step and approximate time left, updating itself. Call it once, right after create_story starts the story, then call wait_for_story.
get_trim_result
ChatGPTThe clip the user chose after trim_in_browser (media_id, url, duration_seconds). Pass the token trim_in_browser returned. Call it after the panel posts "Done - I trimmed the clip ..."; it checks once, without waiting. The panel already plays the clip to the user: do not call show_media for it unless they ask to see it again.
get_upload_result
ChatGPTThe file the user picked after upload_from_browser (media_id, url, width, height, duration_seconds). Pass the token upload_from_browser returned. Call it right after upload_from_browser: it waits up to a minute for the pick and returns as soon as the file arrives. The panel already shows the file to the user: do not call show_media for it unless they ask to see it again.
lip_sync
ChatGPTMake a face speak an audio track: re-sync the lips in a video, or turn a photo into a talking video. Without model, the first that fits the face (image or video) is used; the models and what each takes are in list_models(tool="lip_sync"). The output is about as long as the audio. Steps: 1. Get the face (an image or a video) and the speech audio media_ids. There is no text-to-speech here: the user supplies the audio. 2. Call lip_sync. It runs at once and returns a request_id.
list_image_styles
ChatGPTThe image styles a new story can take: Atlabs' own (SYSTEM) and the ones the user made (USER), each with a preview image. Choose the one that fits the story, unless the user named one, and pass its image_style_id to create_blank_story.
list_library_characters
ChatGPTList the characters from the user's character library (their own and Atlabs actors) that can be added to this story, newest first, at most 50; search matches the name. Read only. Show the user the options and let them choose: never pick one for them.
list_library_locations
ChatGPTList the locations from the user's location library that can be added to this story, newest first, at most 50; search matches the name. Read only. Show the user the options and let them choose: never pick one for them.
list_library_products
ChatGPTList the products (objects) from the user's library that can be added to this story, newest first, at most 50; search matches the name. Read only. Show the user the options and let them choose: never pick one for them.
list_media
ChatGPTThe user's Atlabs FILES - uploads and MiniTool outputs, not their stories - newest first. Filter with media_type (image, video or audio) and limit (1-100). "my video", "my latest video" (or music, image) is ambiguous: a STORY (a film they built in Atlabs: list_stories, whose finished video is get_story_export) or a FILE (uploaded, or made by a MiniTool: list_media). Most Atlabs users mean a story. Resolve it, stopping at the first that applies: 1. They named it -> that one. 2. It was made or uploaded earlier in this chat -> that one. 3. Otherwise ask "your story, or a file in your library?" and wait. For the latest library video, use media_type="video" and limit=1. Call show_media with its media_id to display it. To let the USER choose a file, call pick_media instead.
list_models
ChatGPTThe models a tool offers and what each one takes (aspect ratios, durations, resolutions, reference limits, and input_limits: each input file's size, dimensions, length and format, checked before the run), default first. Pass a model's model value to that tool. tool is one of: generate_image, generate_video, upscale_media, reframe_media, modify_video, motion_control, lip_sync, generate_music, scene_edit_image, scene_edit_motion, scene_edit_lipsync. The same list as the resource atlabs://minitools/<tool>/models.
list_music
ChatGPTThe background-music tracks this account can use (Atlabs' library and their own), shown to the user as a list with a player for each one's preview. Choose a track yourself by its genre, moods and length to fit the story, unless the user names one or picks it in the panel. Don't list the tracks again in the chat: the panel shows them. The panel also takes their own audio file (drop, paste or choose). Pass the story's story_id: then the user's pick or upload is set on the story by the panel itself, and the message you get back says it is saved - don't call set_background_music for it. Without a story_id the message gives you the music_id or media_id to pass to set_background_music. A track the user names in the chat is set with set_background_music, without the panel. search matches a name, genre or mood; pass current_music_id to mark the story's track, and offset for the next page.
list_stories
ChatGPTThe user's stories - the films they build in Atlabs - most recently edited first. Optional search (a name or a story id), page and page_size. "my video", "my latest video" (or music, image) is ambiguous: a STORY (a film they built in Atlabs: list_stories, whose finished video is get_story_export) or a FILE (uploaded, or made by a MiniTool: list_media). Most Atlabs users mean a story. Resolve it, stopping at the first that applies: 1. They named it -> that one. 2. It was made or uploaded earlier in this chat -> that one. 3. Otherwise ask "your story, or a file in your library?" and wait.
list_story_characters
ChatGPTList the characters of the user's Atlabs story, with their details: name, look, clothing, voice, where their portrait came from and which fields edit_character can change on each (none on one is_shared from another of the user's stories: edit it there). Read only.
list_story_locations
ChatGPTList the locations of the user's Atlabs story: name, description (what the place looks like) and where its portrait came from. One is_shared from another of the user's stories is edited there. Read only.
list_story_products
ChatGPTList the products (objects) of the user's Atlabs story: name, look (visual_appearance), where their portrait came from and whether a supplied image is restyled. One is_shared from another of the user's stories is edited there. Read only.
list_voices
ChatGPTThe voices this account can use for a scene voiceover, shown to the user as a list with a player for each one's preview. Choose one yourself from each voice's language, gender and description to fit the story, unless the user names one; if they pick one in the list instead, their pick comes back to you as a message. Each voice has its voice_code (what scene_edit_voiceover takes), pause_style (tagged: [pause]; timed: <break time="1s"/>; null: no pauses), takes_emotion and takes_pronunciations. Pass a language to narrow it (e.g. english), current_voice_code to mark the scene's voice, and offset for the next page.
modify_video
ChatGPTEdit one of the user's videos with a prompt (e.g. "make it snow", "change her jacket to red"), optionally guided by reference images. The models, how many references each takes and which keep the original audio are in list_models(tool="modify_video") (default first). Steps: 1. Get the video's media_id (upload it, or list_media) and any reference images. 2. Call modify_video. It runs at once and returns a request_id.
motion_control
ChatGPTMake the character in an image perform the motion of a driving video (dance, gestures, acting). The price follows the driving video's length. The models are in list_models(tool="motion_control") (default first). character_orientation: "video" (default) follows the video's framing, "image" keeps the image's; keep_original_sound keeps the video's audio (default true). Steps: 1. Get the character image and the driving video media_ids. 2. Call motion_control. It runs at once and returns a request_id.
override_captions
ChatGPTReplace one scene's captions in the user's Atlabs story with exactly these rows: [word, start, end], seconds from the scene's start, one word per row, start before end, in order, no overlap. Only when the user gives the timings or wants captions written from scratch - you can't hear the audio, so to fix words use resync_captions. Free. If the user has this story open in the Atlabs editor, tell them to reload it to see the change.
pick_media
ChatGPTLet the user choose files from their Atlabs library: it shows the library as a grid in the chat, and their pick comes back to you as a message with the media_ids. Use it whenever which file to use is the user's choice. media_type narrows it (image, video, audio). They can pick several by default (select_up_to, up to 10); when the next tool takes only one file, pass select_up_to=1 so a single tap picks it. For your own lookups, use list_media.
plan_story
ChatGPTPlan a new Atlabs story in one interactive HTML panel inside this chat. FIRST, before the first plan_story call: if the user attached or pasted an image for the story, it does not reach Atlabs by itself. Upload it with start_upload(for_story_plan=true) and PUT the bytes; if the PUT cannot connect, use upload_from_browser(for_story_plan=true), then get_upload_result. Pass each returned media_id in reference_media_ids on that first call. Never start the plan without it, and never say the plan uses a file you did not pass. Files already in the library can't be used: ask the user to add them with the panel's Add references button. Start with the user's idea in message and a new UUID turn_id. The panel shows the assistant_message, visual style thumbnails and question buttons. General reference uploads appear only on the first planning step; saved references stay visible later. A reference only guides the plan's text until the user picks a name under "Use as a reference for:" in the panel to make it the photo of a character, place or product. Story ideas and free-text changes belong in the main chat, not a repeated panel composer. When the user types a change here, send it to plan_story with the latest session_id and plan_version. Wait for panel choices otherwise; do not repeat the questions as text choices or open the Atlabs website. The panel saves replies and updates itself. After each plan_story call, say one short line pointing to the panel; never list its questions or choices in chat, and never guess that it may not show. Only if the user says the panel does not appear, ask the returned questions in chat. Share web_url (the plan in the Atlabs web app) only when the user asks to continue on the web, and only if it is set; otherwise show no link. panel.url is the panel's internal address: never show it. Send the user's reply in message or answers keyed by question id. Continue with session_id and plan_version from the last response and a fresh turn_id. Never invent answers or rewrite extracted_state. Retry a failed call with the SAME turn_id and arguments. With session_id and no message/answers, read the latest saved plan without running the agent. If detected_flows suggests a specialised workflow, the panel asks whether to continue general story planning. Only the user's agreement permits continue_general_story=true. Specialised wizards are not started here. Always show credit estimates for ALL three output modes when the plan is ready, plus the current balance. If pricing is unavailable, say so; never invent a price. When ready, the panel shows the summary, credits and a Start button per output mode. A Start click posts "Start my <mode> for <N> credits." in the chat: call create_story with the session_id, that mode and approved_credits=N. Never call create_story without that click: it starts the story and charges at once.
reframe_media
ChatGPTChange the aspect ratio of one of the user's images or videos; AI fills in the new area, optionally guided by a prompt (e.g. "extend the beach"). No model choice: picked from the media type. Steps: 1. Get the media_id (upload it, or list_media). 2. Call list_models(tool="reframe_media") for the aspect ratios and resolutions each media type allows; leave resolution out for the default. 3. Call reframe_media. It runs at once and returns a request_id.
resync_captions
ChatGPTFix the words of one scene's captions in the user's Atlabs story: text is the scene's words as they should read, and Atlabs re-times every word to the audio - the editor does the same when words change. The way to fix a misspelling or a wrong word. Read the current words with get_scene_captions first; change only what the user asked. Free. If the user has this story open in the Atlabs editor, tell them to reload it to see the change.
scene_edit_image
ChatGPTChange the image of one shot in the user's Atlabs story: the source image plus a prompt that says what to change, and optional reference images. The aspect ratio is the story's. Steps: 1) the shot: its aroll_id, from get_story_assets (a scene can hold several shots). 2) the files: the shot's own image (or animated_from_media_id, the image behind a clip) and the portrait_media_id of each character, product or location from the story's cast in the shot - add these yourself. Any other file of theirs the user picks, with pick_media (select_up_to=1 for one file); never choose one of those for them. 3) ask: you can't see their own files, so unless the user already said, ask what each such reference shows and what to take from it (a face, the view, the lighting...) - never guess. 4) the model: choose it yourself from list_models(tool=<this tool>), the default unless the user named one or another fits clearly better. 5) the prompt: write it yourself; point at each reference by its chip - @Image1, @Image2, @Video1 in order, or a portrait's mention (@KodaFox); every reference must be mentioned. An image edit also names its source: @CurrentFrame when it is the shot's own image (then references start at @Image1), else @Image1 (references from @Image2). A motion or lip-sync prompt never mentions the start frame or the face - describe the movement in words. 6) run: call the tool (it runs and charges at once), tell the user summary_for_user, then get_result with the request_id. A refusal says what to fix. Only the scene_edit_* tools change the story. A MiniTool (generate_video, generate_image, lip_sync, modify_video, ...) makes a NEW file in the library and leaves the story untouched, so it is never a fallback: if a story edit can't be done, say why. Use a MiniTool only when the user asks for one.
scene_edit_lipsync
ChatGPTSync the lips in one shot of the user's Atlabs story to its scene's voiceover (the audio is the scene's - make one first with scene_edit_voiceover if it has none). source_media_id is the face: an image or a video. With several people in the shot, tag who speaks in the prompt by their cast mention (@Mia, models with has_speaking_character), or set auto_detect_speaker on Sync 3. Steps: 1) the shot: its aroll_id, from get_story_assets (a scene can hold several shots). 2) the files: the shot's own image (or animated_from_media_id, the image behind a clip) and the portrait_media_id of each character, product or location from the story's cast in the shot - add these yourself. Any other file of theirs the user picks, with pick_media (select_up_to=1 for one file); never choose one of those for them. 3) ask: you can't see their own files, so unless the user already said, ask what each such reference shows and what to take from it (a face, the view, the lighting...) - never guess. 4) the model: choose it yourself from list_models(tool=<this tool>), the default unless the user named one or another fits clearly better. 5) the prompt: write it yourself; point at each reference by its chip - @Image1, @Image2, @Video1 in order, or a portrait's mention (@KodaFox); every reference must be mentioned. An image edit also names its source: @CurrentFrame when it is the shot's own image (then references start at @Image1), else @Image1 (references from @Image2). A motion or lip-sync prompt never mentions the start frame or the face - describe the movement in words. 6) run: call the tool (it runs and charges at once), tell the user summary_for_user, then get_result with the request_id. A refusal says what to fix. Only the scene_edit_* tools change the story. A MiniTool (generate_video, generate_image, lip_sync, modify_video, ...) makes a NEW file in the library and leaves the story untouched, so it is never a fallback: if a story edit can't be done, say why. Use a MiniTool only when the user asks for one.
scene_edit_motion
ChatGPTAnimate one shot of the user's Atlabs story into a clip, with a prompt for the movement. An image-to-video model (takes_start_frame) needs start_frame_media_id, usually the shot's image. A reference-to-video model takes no start frame, only reference images, videos or audio - if the user wants the shot's image in it, it goes in reference_image_ids. The aspect ratio is the story's. Steps: 1) the shot: its aroll_id, from get_story_assets (a scene can hold several shots). 2) the files: the shot's own image (or animated_from_media_id, the image behind a clip) and the portrait_media_id of each character, product or location from the story's cast in the shot - add these yourself. Any other file of theirs the user picks, with pick_media (select_up_to=1 for one file); never choose one of those for them. 3) ask: you can't see their own files, so unless the user already said, ask what each such reference shows and what to take from it (a face, the view, the lighting...) - never guess. 4) the model: choose it yourself from list_models(tool=<this tool>), the default unless the user named one or another fits clearly better. 5) the prompt: write it yourself; point at each reference by its chip - @Image1, @Image2, @Video1 in order, or a portrait's mention (@KodaFox); every reference must be mentioned. An image edit also names its source: @CurrentFrame when it is the shot's own image (then references start at @Image1), else @Image1 (references from @Image2). A motion or lip-sync prompt never mentions the start frame or the face - describe the movement in words. 6) run: call the tool (it runs and charges at once), tell the user summary_for_user, then get_result with the request_id. A refusal says what to fix. Only the scene_edit_* tools change the story. A MiniTool (generate_video, generate_image, lip_sync, modify_video, ...) makes a NEW file in the library and leaves the story untouched, so it is never a fallback: if a story edit can't be done, say why. Use a MiniTool only when the user asks for one.
scene_edit_voiceover
ChatGPTReplace the spoken line of one scene of the user's Atlabs story: scene_id from get_story, and text, the words to speak. Left out, the voice, speaking_rate, pitch and pronunciation fixes stay what the scene uses now. To change the voice, choose one yourself from list_voices (its language, gender and description) to fit the scene, unless the user named one; never make up a voice_code. In a character-voice story the scene's speaker decides the voice. The words may carry tags the voice takes (voice_tags in the answer; pause_style in list_voices): [Excitedly], [Laughs], [pause] or <break time="1s"/> - a tag the voice doesn't take is refused. For a word said wrong, voice_pronunciations takes [{"word": ..., "ipa": ...}] when the voice takes_pronunciations. The call runs and charges at once; tell the user summary_for_user afterwards. A shot in lip_synced_aroll_ids was synced to the voiceover being replaced: tell the user its lips will no longer match, and once the new voiceover is ready redo it with scene_edit_lipsync. Only the scene_edit_* tools change the story. A MiniTool (generate_video, generate_image, lip_sync, modify_video, ...) makes a NEW file in the library and leaves the story untouched, so it is never a fallback: if a story edit can't be done, say why. Use a MiniTool only when the user asks for one.
set_background_music
ChatGPTChange the background music of the user's Atlabs story - any of: the track (music_id from list_music, or media_id of one of their own audio files), is_on (music on or off), volume (0-1; the editor's default is 0.15, keep it low under a voiceover). Picking a track turns music on. To use a new track of their own, upload it (upload_from_browser; mp3, wav or m4a) and pass the media_id it returns; an audio file already in their library (list_media, media_type="audio") or made with generate_music goes in the same way. Choose the track yourself to fit the story, unless the user named one. See what plays now with get_background_music. Free. If the user has this story open in the Atlabs editor, tell them to reload it to see the change.
set_captions_shown
ChatGPTTurn captions on or off in the user's Atlabs story: with scene_id for one scene, without it for the whole story (a scene shows captions only when both are on). The words and their look stay as they are. Free. If the user has this story open in the Atlabs editor, tell them to reload it to see the change.
set_character_voice
ChatGPTSet the voice of a character in the user's Atlabs story (element_id from get_story's cast, voice_code from list_voices - choose one that fits the character unless the user named one). In a story where characters speak, every scene they speak uses it from now on. Free, and no audio is made: the scenes' existing voiceovers keep the old voice. If the user has this story open in the Atlabs editor, tell them to reload it to see the change.
set_narrator_voice
ChatGPTSet the voice of the narrator of the user's Atlabs story: the narrator and every narrated scene speak with voice_code from now on (a scene a character speaks keeps that character's voice). Choose one from list_voices that fits the story, unless the user named one. Free, and no audio is made: the scenes' existing voiceovers keep the old voice. If the user has this story open in the Atlabs editor, tell them to reload it to see the change.
set_scene_text
ChatGPTSave the line one scene of the user's Atlabs story says - its script - without making any audio (the Script step of building a story: the script, one scene at a time). Free. A scene that already has a voiceover is not changed (is_saved false): its line changes only with a new voiceover, so the words and the audio stay the same. If the user has this story open in the Atlabs editor, tell them to reload it to see the change.
set_shot_media
ChatGPTShow one of the user's own image or video files on a shot of their Atlabs story, REPLACING what the shot shows now - also how to switch a shot back to an earlier generation from get_scene_assets. The user picks the file (pick_media with select_up_to=1, or an earlier generation they choose); never choose for them. A lip-sync clip as the scene's only shot speaks for itself: its own audio and captions play and the voiceover is muted. Any other file plays under the voiceover, silent. Free. If the user has this story open in the Atlabs editor, tell them to reload it to see the change.
show_media
ChatGPTShow 1-4 of the user's images, videos or audio in the chat: an earlier output, or files from list_media or get_story_assets. Pass their media_ids. Before showing "their video", know which one they mean: "my video", "my latest video" (or music, image) is ambiguous: a STORY (a film they built in Atlabs: list_stories, whose finished video is get_story_export) or a FILE (uploaded, or made by a MiniTool: list_media). Most Atlabs users mean a story. Resolve it, stopping at the first that applies: 1. They named it -> that one. 2. It was made or uploaded earlier in this chat -> that one. 3. Otherwise ask "your story, or a file in your library?" and wait. Never paste a file's URL into your reply unless the user asks for a link: the player has its own Download and Open buttons, and the link expires.
start_upload
ChatGPTUpload a file the user pasted, attached or dragged in (image, video or audio) to their Atlabs library. The media_id comes back from the PUT (step 3). Any supported image, video or audio can be uploaded. Whether it suits a MiniTool is checked when you use it: if it doesn't, that tool's first call says which models take it and how to fix it (trim, upscale, reframe). For a reference image for plan_story, pass for_story_plan=true: the file then stays out of the library, the plan can use it, and it is removed once the story is created. Steps: 1. Find the file. Claude Code: the path the user gave; for an image pasted from the clipboard on macOS, save it first: osascript -e 'set f to open for access POSIX file "/tmp/atlabs_paste.png" with write permission' -e 'write (the clipboard as «class PNGf») to f' -e 'close access f' claude.ai / Claude Desktop: attached files are in /mnt/user-data/uploads/. 2. Call start_upload(file_name, content_type). 3. PUT the raw bytes to upload_url with the given Content-Type, e.g. curl -X PUT -H "Content-Type: image/png" --upload-file ./photo.png "<upload_url>" The response is the media (media_id, url, width, height, duration_seconds). The link works once and expires in 10 minutes. 4. If the PUT can't connect (connection refused, proxy 403, "host not allowed"), don't retry it: this sandbox has no network access. Fall back to upload_from_browser, which lets the user pick the file in their own browser.
trim_in_browser
ChatGPTLet the user pick the part to keep from an audio or video file, by hand. A player opens in the chat with a clip track under it: they drag the start and end, hear or watch the selection, and confirm. Use this whenever the user has NOT given you exact times - "cut the chorus", "just the part where he turns" - because only they can see where that is. Steps: 1. Call trim_in_browser(media_id). Tell the user to pick the part in the panel that appeared. 2. Stop and wait: when they confirm, the panel posts "Done - I trimmed the clip ..." in the chat. 3. Then call get_trim_result(token) with the token that came back. It returns the new clip (media_id, url, duration_seconds). If it says they have not confirmed yet, tell them once and stop again. If no panel appears, this chat app cannot show one: ask the user for the times in words and use trim_media instead. The clip keeps whatever the source was - audio stays audio, video stays video.
trim_media
ChatGPTCut a part of the user's audio or video into a new file (free, no credits), e.g. to fit a MiniTool's length limit. start_seconds and end_seconds are where the part starts and ends in the file; the part must be at least 0.5 seconds. keep="same" keeps the file's type (video stays video); keep="audio" takes only the audio of a video. Returns the new clip's media_id and length. Ask the user for the times first; you can't hear or watch the file. Use this only when the user gave exact times. When they described the part in words ("the chorus", "where he turns"), call trim_in_browser instead and let them pick it.
upload_from_browser
ChatGPTAsk the user to pick the file themselves: when they attached it in the chat or shared a link (neither can be imported), or when the PUT in start_upload cannot connect (a sandbox with no network access). A file picker opens in the chat and the file goes straight from the user's browser to Atlabs, so it never crosses the conversation. For a reference image for plan_story, pass for_story_plan=true: the file then stays out of the library, the plan can use it, and it is removed once the story is created. Steps: 1. Call upload_from_browser(), then tell the user in one line to choose their file in the panel that appeared. 2. Right away, call get_upload_result(token) with the token that came back. It waits for their pick and returns the media (media_id, url, width, height, duration), so carry on with the task without asking them to say they are done. If it says they have not picked yet, call it again (up to 3 calls), then ask once and stop. If no picker appears at all, this chat app cannot show one: ask the user to upload it on the Atlabs web app, then find it with list_media.
upscale_media
ChatGPTMake one of the user's images or videos sharper and larger. No model choice: the right upscaler is picked from the media type. Steps: 1. Get the media_id (upload it, or list_media). 2. An image takes image_scale; a video takes video_resolution and video_fps. Leave them out for the defaults. 3. Call upscale_media. It runs at once and returns a request_id.
wait_for_story
ChatGPTWait for a started story to finish. Each call waits up to 45 seconds; while it is still running, call it again right away and write nothing in between (the progress panel shows progress). When it is done, failed or paused, reply with story_url as a clickable full-domain link. After 10 minutes it says to stop and ask the user whether to keep waiting; on their yes, call it again. An elapsed estimate never means generation finished.