Edit the screenplay with structured operations, applied in order in one write. Live collaborators see the change immediately, and the pre-edit script is saved to version History so the user can undo it.
The script is a flat list of elements. Each element has a type and plain-text content:
- SCENE_HEADING: "INT. KITCHEN - NIGHT" (optional placeId links a place entity)
- ACTION: description of what happens
- CHARACTER: the speaker's name before dialogue, optionally followed by a cue extension: "MARA" or "MARA (O.S.)" (optional characterId links a character entity). characterId links the name only: a linked line shows the entity's name followed by the extension. Pass extension ("O.S.", "V.O.", "CONT'D") instead of typing it into content if you prefer
- DIALOGUE: the spoken line, right after CHARACTER (or PARENTHETICAL)
- PARENTHETICAL: acting direction such as "(whispering)", between CHARACTER and DIALOGUE
- TRANSITION: "CUT TO:"
- SHOT: a camera shot line
- Structure: EPISODE, ACT, SEQUENCE, STORY_BEAT (content is the title); OUTLINE is a note or the description of the structure element before it.
Operations:
- insert: { op: "insert", afterElementId? | beforeElementId?, elements: [{ type, content, extension?, characterId?, placeId? }] }. With no anchor, elements are appended at the end of the script. New ids are created by the server and returned.
- update: { op: "update", elementId, content?, type?, extension?, characterId?, placeId? }. null clears extension / characterId / placeId. extension is applied after content and replaces the extension already on the cue.
- delete: { op: "delete", elementIds }. Any delete requires confirmDeletes: true; ask the user before deleting their writing.
Element ids come from get_scene or search_script; entity ids come from list_entities. Never invent ids: an unknown entity id, a characterId outside CHARACTER / DIALOGUE, or a placeId outside SCENE_HEADING is rejected, and so is an extension outside CHARACTER. Leave them unset when unsure: the app links CHARACTER names and scene headings to existing entities by name, and creates missing ones, when the project is open. A dialogue exchange is CHARACTER then DIALOGUE elements; a new scene starts with a SCENE_HEADING. Limits: 100 operations and 200 inserted elements per call; write a longer script in several calls, each inserting after the last element id the previous call returned. Final Draft (.fdx) and WriterDuet files go through import_script instead.