add_deck_slides
ChatGPTAdd slides to a deck that already exists, written against the same theme variables as the rest (--deck-bg, --deck-fg, --deck-accent, --deck-muted, --deck-font, --deck-scale). Use this to grow a deck the user asked to extend; never build a second deck beside the first. A request for a new or another deck is create_deck, never slides added to this one.
add_document_to_board
ChatGPTPut an EXISTING document on the board — the one the user attached, or one you found with list_documents. Use this whenever they ask to add/put/place a document they already have onto the board. Do NOT use create_whiteboard_element with type 'document' for this: that makes a NEW blank document instead of showing theirs. The document may live in another project; pass only its uid.
add_images
ChatGPTPut pictures you already have the addresses of onto the board: photos from your own web search, images on a page the user shared, links the user pasted. Storyflow downloads each one and keeps its own copy in the user's gallery, so it stays on the board after the link dies. Pass the image file's own address (ends in .jpg, .png, .webp or serves an image), not the page it sits on. BY DEFAULT IT PLACES THE PICTURES ITSELF, loose or inside parent_uid; do not create image elements for them afterwards. To fill an EMPTY image frame already on the board, pass one image and its target_uid. When the pictures go into something you build (deck slides, orbit members, shot-card frames, one picture per wall across several walls), pass place_on_board: false and use the image_url values it returns. Only use addresses you actually found or were given, never invented ones. An address that could not be stored comes back in missing: say which, and offer to try another link.
apply_board_template
ChatGPTPut a whole shipped template onto the board the user is on, in one go, with its exact layout — every wall, card, colour and connection where the template puts them. Then it reads the board back and returns an inventory of what landed, with a uid for every element, so you can rewrite the cards for THIS user's subject with update_element. The template arrives carrying its own worked example (Film Plan ships a North Face climbing commercial). That content is a starting point to REPLACE, not to leave: after applying, work through the inventory and rewrite every card that names the example's subject. Leaving it is worse than never applying, because the user is handed a stranger's production. Only apply when the user asked for that template, or agreed to start from it. Never apply one speculatively onto a board that already has their work on it.
board_widget_activity
ChatGPTWhat the realtime server pushed for this project since the widget last looked.
board_widget_graphql
ChatGPTThe board card's own data channel: the canvas inside a show_board card reads and saves the board through it. It is never for you to call; read and change boards with the other tools.
board_widget_part
ChatGPTOne part of a board widget answer too large for a single result.
board_widget_plan
ChatGPTWhether the signed-in account has used this week's free actions from AI assistants.
board_widget_session
ChatGPTWho the board widget is signed in as, and which AI app it is running in.
build_section
ChatGPTBuild one section of a board in one call: a wall and every card inside it, top to bottom, written in the order given. Send every section of a board this way; create_whiteboard_element is for loose items and for adding to a wall that already exists. A card takes the fields of create_whiteboard_element (type, title, text, table columns and rows, labels) except parent_uid, after_uid, frame_uid, project_uid and whiteboard_uid, and is never a wall. Give the wall a width when a card is a table. A document's card may carry its opening section in text. A card that fails leaves the others in place: the result lists each card's uid or error, so resend only a failed card with create_whiteboard_element and after_uid set to the card above it. A folder's contents go in a later call with whiteboard_uid set to the folder's board, from list_boards.
clear_document_from_table_cell
ChatGPTEmpty a cell of a table's document column. The document itself is NOT deleted — it stays in the project's documents and can be put back.
connect_whiteboard_elements
ChatGPTDraw an arrow between two elements on a board, to show flow or relationship. Both uids must be elements you have seen via get_whiteboard_elements. Connecting two walls standing side by side also widens the gap between them, so the line and any text on it have room. The read gave you both elements' positions, so USE THEM: an element sitting BELOW another is joined bottom to top, and leaving the default right-to-left there draws a line that loops around the outside of its own card before it arrives.
convert_notes_to_documents
ChatGPTMove whole notes into documents, keeping their text exactly as written. Use this whenever a note is long enough to be a document — roughly a screenful or more — and whenever the user asks for documents. NEVER retype a note's content into a new document yourself: that is slow, it risks dropping their words, and this does it as a move. The originals are deleted in the same undo step, so the board is left holding the documents and not both. Give wall_uid to file them into a wall you have already created.
create_carousel_pages
ChatGPTPut a social CAROUSEL POST on the board: every slide as its own design page, laid out left to right in slide order, all at the post's fixed size. This is what "carousel posts", "a swipe post", "slides for Instagram / LinkedIn / TikTok" build — never create_deck, whose slides live inside one element and move with it. Once placed, the pages are independent: the user drags, deletes or edits any one alone, and update_html_app rewrites one. Each page is a self-contained static HTML document under the same constraints as create_html_app: no scripts, no external URLs, pictures as empty data-image-slot elements named in image_slots.
create_chart
ChatGPTCreate ONE native chart element (bar, line or pie) on the board. Data and styling live in the element; the canvas renders it as a real interactive chart. Use real values only — never invented numbers. This is the RIGHT answer to most requests to chart something: one fact is one chart, and the same measure across several categories is this tool called once per category (small multiples read better than one crowded chart). Reach for create_dashboard only when the ask is an overview of several different measures. ALWAYS send value_format when the values are money or percentages — without it they render as bare numbers — and add a caption saying what the chart shows whenever you have a finding worth stating. BUILDING FROM A PICTURE THE USER PASTED: what carries across is the DATA, the category and series names, the chart type, the bar direction and the series colours. Nothing else does — the background, typography, gridlines, spacing and legend placement are the canvas's own and are not settable here. So say what you actually matched. Announcing a chart as being in "the same style" beside a screenshot it visibly does not resemble is the one claim the user checks immediately, and it costs you the ones they cannot check.
create_color_palette
ChatGPTPut a COLOUR PALETTE on the board: several swatches laid out as a grid, in ONE call. This is how a palette is built — never several create_whiteboard_element calls with type 'color', which cannot make a grid and leaves the swatches in one long row running off the canvas. Each swatch shows its colour, the name you give it, and its hex and RGB values (those two are rendered from the hex, so do not write them into the name). Use it whenever the user asks for a palette, colour scheme, brand colours or swatches — including when you are reading the colours off a picture they attached. The swatches sit loose on the canvas as a block; to put colours INSIDE a wall instead, use create_whiteboard_element with a parent_uid.
create_constellation
ChatGPTCreate a whole constellation in one call: a radial web of rich notes (a central idea, themes, sub-notes) laid out and connected by the tool. You supply ONLY the content tree; never create constellation notes or edges yourself. 20-35 nodes make a good constellation; node text can be a sentence or two.
create_dashboard
ChatGPTCreate a whole dashboard: chart tiles laid out in a justified grid the tool computes. You design WHICH tiles share a row and their relative spans; the tool owns the pixels. Rows render top to bottom; a good dashboard opens with a row of 3-4 metric tiles, then chart rows of 1-3 tiles. Max 16 tiles. Real values only. USE IT WHEN THE ASK IS AN OVERVIEW — a dashboard, a report, a summary, 'how are we doing' — or when four or more different measures are worth showing at once. A request for a chart, a graph or a picture of ONE thing is create_chart, not a grid with that chart buried in it. Never invent a tile to fill the grid: if the data holds four things worth showing, the dashboard is four tiles. ALWAYS send value_format on tiles whose values are money or percentages, and give a gauge its real value_min/value_max (NPS runs -100 to 100) — the ring is drawn against 0-100 otherwise and is wrong.
create_deck
ChatGPTPut a DECK on the board: one element that shows one slide at a time, with every slide created under it. Each slide is a self-contained static HTML page at the deck's fixed slide size, written against the deck theme's CSS variables (--deck-bg, --deck-fg, --deck-accent, --deck-muted, --deck-font, --deck-scale) so one theme change re-skins every slide. The same hard constraints as create_html_app apply to every slide: no scripts, no external URLs, pictures as empty data-image-slot elements named in image_slots. The user edits slides by hand afterwards, presents the deck fullscreen and exports it as one PDF. This is what a request for SLIDES builds — a pitch deck, a treatment, a lookbook, "a ten-page treatment" — not the PDF tools, which compose a file (ADR-0112). A social CAROUSEL post (Instagram, LinkedIn, TikTok slides) is not a deck: create_carousel_pages (ADR-0118). A shot list asked for by name is the card row create_shot_cards builds; only the design-shot-list workflow wants it as a deck. A deck already on the board does not make a request an edit; what the user asked for decides. Asked to change THAT deck ("the deck", "my deck", "this slide", "it", add, remove or reorder slides, re-theme it): change it with update_html_app per slide, add_deck_slides, remove_deck_slides, reorder_deck_slides, update_deck for the theme, and never build a second deck beside one the user asked you to alter. Asked for A deck ("a new pitch deck", "another deck", "a deck from these images"): this tool, and the deck already there is left exactly as it is: none of its slides rewritten, filled or removed. Only a whole-deck redo that could mean either ("redo the pitch deck with these pictures") gets one question first, even though it names the deck: change the deck on the board, or build a new one beside it. Pictures the user attached to their message go into the slides with fill_image_slot, not onto the board on their own.
create_diagram
ChatGPTDraw a DIAGRAM in one call — a flowchart, a user journey, an org chart, a swimlane, a state machine, a process: boxes on a grid with labelled arrows between them. Use this whenever the shape of the answer is boxes-and-arrows, however the user said it ('map the signup flow', 'how does a ticket move through support', 'chart our approval process'). It CANNOT be built one element at a time. Free placement answers 'somewhere free' rather than 'column 2, row 3', so the boxes step diagonally across the canvas and the arrows between them mean nothing. Here you say which CELL each node is in and the tool owns every coordinate: one width for every box, a column as wide as its widest node, and the space a labelled arrow needs bought out of the boundary it crosses so no chip lands on a box. Use create_mindmap for a centre with branches radiating off it, create_constellation for a web of notes with sub-branches, and create_orbit for one ring of small things around a hub. This is the one for a flow that goes somewhere. This builds BOARD ELEMENTS the user keeps working on. When they want ONE finished thing to take away instead — a timeline, framework or explainer to screenshot into a deck, show a client or send — that is create_html_app, which lays the same material out as a single designed page.
create_document_in_table_cell
ChatGPTCreate a project document and put it in one cell of a table's document column, so that cell opens the document. Use for 'give every episode an outline', 'add a script to each scene'. The cell shows the document's own name and icon — do NOT also write the title into a text cell. Fill the document afterwards with write_document_content, passing the returned document_uid and NO element_uid.
create_mindmap
ChatGPTCreate a whole mind map in one call: a central topic, branches and sub-branches, laid out and colored by the tool with connecting edges. You supply ONLY the content tree; never create mindmap notes or edges yourself. Node text is concise (3-8 words). A NODE HOLDS 3-8 WORDS, so a request that names the SECTIONS it wants — premise, acts, characters, themes, arcs — is asking for a board of walls it can write paragraphs in, and the word "map" in it does not make it a mind map. Build those with walls and cards; reach here for a branching tree of short labels, or when they ask for a mind map by name. THERE IS NO EXTEND. This always builds a WHOLE map, so "add more to this mind map" means deleting the one that is there and putting a replacement in its place — which costs every node the user dragged, and anything they attached to the old nodes. Ask before doing that, and if you do it, say it was REBUILT. Reporting a replacement as an expansion ("expanded the mindmap, keeping the same three branches") is a claim the layout itself contradicts the moment they look at it.
create_orbit
ChatGPTCreate an ORBIT in one call: a small central label with things ringed around it and a curved line drawn from the centre out to each one. ANY mix of cards can ring the hub — pictures, colour swatches, notes, links, videos, tickets, checklists, documents and folders — so this is the shape for 'everything about X in one place', as well as the film colour palette and inspiration wall the boards we ship use it for. It CANNOT be built by creating the pieces one at a time: free placement steps them diagonally across the canvas and nothing joins them up. Supply only the centre and the members; the tool owns every coordinate, the ring radius and every line. Use create_color_palette instead when the user wants a plain palette block (a grid of swatches, no hub, no lines) — that is the commoner request. Use create_constellation for a web of substantial NOTES with sub-branches; an orbit is ONE ring of small things.
create_project
ChatGPTCreate a new, empty Storyflow project with the given title, the same way the app's New project button does: it comes with its root board. Returns the new project's uid; pass it as project_uid to the board and document tools to fill it in. Use only when the user asks for a new project.
create_shot_cards
ChatGPTBuild a shot list in the CARD format — a connected left-to-right row of shot walls, each holding its frame, a chips note, a 'Shots required' checklist, a scene-direction note and an equipment note, with an arrow to the next shot. Use this INSTEAD of many create_whiteboard_element calls whenever you are building shot cards: it is one call for the whole row, so a 20- or 40-shot list actually finishes. You supply the content of every shot; the tool owns the walls, card order, colours and arrows. Pass EVERY shot the user asked for in one call. WHEN THE PICTURES ARE ALREADY ON THE BOARD — selected, or asked for in words — pass each one's uid as that shot's image_element_uid in THIS call, so their own pictures become the frames. Moving them in after the call instead leaves the empty placeholder frame this tool built standing in every wall beside them. Never leave a selected picture without a shot.
create_strip_board
ChatGPTBuild a strip board — the shooting schedule — in ONE call: a wall per shoot day, a coloured strip per scene, in shooting order, each day totalled in pages and chained to the next by an arrow. Use this INSTEAD of individual create_whiteboard_element calls for any strip board or shooting schedule: pass EVERY day and every strip at once. Strip colours are the industry code (INT/EXT × day/night) and the tool sets them — never colour a strip yourself. Take scenes, page counts and cast from the script's SCENE INDEX (read_script_scenes) or the scene table on the board, never from memory of the prose.
create_whiteboard_element
ChatGPTCreate ONE element on a whiteboard and return its uid. This is the only way to put anything on a board. Each call is one element, and every call whose inputs you already have goes in the SAME step: they land one after another in the order you write them, so the user still watches the board fill, and each step you do not take is one less re-read of the whole prompt. Wait for the next step only for a call that needs a uid another call returns. Compose whatever structure fits. A new wall and its cards are ONE build_section call; here, a card for a wall that already exists takes parent_uid set to that wall's uid. On a board that has walls, a folder, document or note goes in one; only a title note (background_color "transparent"), a picture or a shape sits loose. Position and size are decided for you so nothing overlaps — there is no geometry to pass. Creates are immediate and not reviewed; the user can undo. A CHECKLIST IS ONE CARD: for a to-do list, make a single todo call with every task on its own line in text. Each line becomes a checkbox on that one card. A separate card per task is not a list, even when earlier turns in this conversation or cards already on the board look like that. NOT for changing something that already exists. Adding detail to, expanding, or rewriting an existing element is update_element on THAT element — never a new element beside it holding the addition, even if the board or earlier turns already show that pattern.
divide_board_sections
ChatGPTDraw a LINE between groups of content so the board reads as separate sections — the vertical rule between a personal column and the team's columns, the line under a header row. Name what sits on each side and the line is measured and drawn for you: the sections are slid apart to make room, and the rule runs down the middle of that space, the height of the tallest thing it divides. Use it when the user asks to divide, split or separate parts of a board, and when a board YOU have just built has two runs of content that belong to different people, time ranges or stages — a divider is what says they are different rather than a long row of walls. Call it LAST, after everything it separates is on the board: it measures what is actually there, so a wall created afterwards lands on the wrong side of the line. Name the WALLS and other top-level elements, never the cards inside a wall.
fetch
ChatGPTFetch one record by an id returned from search: a project, a board's elements or a document.
find_board_template
ChatGPTSearch the board templates this app ships (Film Plan, Shotlist, Storyboard, Agency Hub, Moodboard, Second Brain and dozens more) and get back their names and uids. Use it when the user names a template, or when a request matches a board we already have a good shape for and starting from it beats building the shape from nothing. Returns candidates only — picking one and applying it is apply_board_template.
get_board_changes
ChatGPTWhat HAPPENED on this board — per card: created, edited, moved, refiled (into or out of a wall), restyled or deleted, who did it, when, and whether it was your own earlier work in this chat. Answers 'what changed?', 'what did I do here since last time?', 'how has this board evolved?'. Default window is since your last turn in this chat. Not a board read: it says what changed, not what is there — read the board itself with get_board_summary or get_whiteboard_elements.
get_board_layout
ChatGPTThe board's real geometry: every element's position and the size the canvas actually draws it at (stored sizes are not real — notes fit their text, walls grow with their cards, documents draw as large cards). Positions are absolute board coordinates; a wall's cards come with parent_uid and their place inside the wall. Use it before placing, aligning or resizing things relative to what is already there. Each element says whether its box was measured or estimated. A board that changed since its last measure takes a few seconds to measure. Returns at most 500 elements, top to bottom, and says so in note when a board holds more.
get_board_people
ChatGPTList the people who have access to this board — the same roster the assignee picker shows. Use it to answer 'who is on this board', and before filling a table's person column when the user did not name someone exactly. Returns each person's id and name; a person cell is written with the NAME.
get_board_summary
ChatGPTAn index of what is on a whiteboard — element counts by type, the names of its walls and folders, and the titles of what they hold — without reading every element's content. Use this FIRST for any board the user attached, and for any board you are deciding whether to read. Use get_whiteboard_elements instead once you know you need the actual content. It also reports authorship — how much of what was read the user wrote themselves.
get_deleted_elements
ChatGPTWhat is in this board's trash: everything deleted from it in the last 7 days, split into what the user deleted and what others deleted. Each entry carries the history_id that restore_deleted_elements needs — element uids do not restore anything. Use it when the user says something was deleted, lost or went missing from a board. Only board elements have a trash: a deleted project, document or gallery upload is gone for good, so say that instead of searching for it.
get_document
ChatGPTFetch a document by uid: title, content and notes. The content HTML carries data-block-id attributes — those are what the edit tools target, so read the document before editing it. The uid in a table's document CELL (inside its tableData payload) is a valid uid here — that is how you read what a cell's document actually says.
get_project
ChatGPTFetch a single project by uid, including title, status and the user's permission level.
get_tactic
ChatGPTFetch a tactic (blueprint) by uid — an expert framework of ordered flip-cards, possibly with a document view. Use get_tactic_cards to read its cards.
get_tactic_cards
ChatGPTRead the cards of a tactic (blueprint) by its numeric blueprint id, in display order.
get_tactic_template_cards
ChatGPTRead the cards of a tactic from the LIBRARY, in display order — each card's title, subtitle and body are the steps of the framework. This is the tool to call for a tactic the user ATTACHED to their message.
get_whiteboard
ChatGPTFetch a whiteboard's metadata by the owning project id (and optionally the board uid; omit it for the project's root board). Board-level metadata only — use get_whiteboard_elements for the actual content.
get_whiteboard_edges
ChatGPTRead a board's edges: the arrows and connections between its elements, with their text.
get_whiteboard_elements
ChatGPTRead what is on a board, with the real text of each element: notes, todos, headings, tickets, tables, documents, tactics, frames and walls. Pass element_uids to read specific elements, or parent_uid to read inside one wall, kanban, group or frame; otherwise the whole board. Containers include their children. An element someone else wrote is marked createdByYou: false.
group_into_walls
ChatGPTRehouse elements that are ALREADY on the board into walls — the whole plan in ONE call. Each group either makes a new wall (title) or files into a wall already there (wall_uid), and the elements are MOVED, so the user keeps the cards they wrote and the board holds no copies. This is how a board gets organized. Never do it as a run of create_whiteboard_element + move_element calls: fifty cards is fifty round trips, the user watches it crawl, and a turn that runs out of room leaves the board half sorted. A new wall joins the board's wall row, or — on a board with no walls yet — lands beside the material it holds. Every write shares this turn's single undo step. It moves elements and names walls. It never writes, rewrites or splits what the user wrote. The receipt carries still_loose: how many fileable cards are STILL on the canvas after your plan ran. Cards you meant to leave out are in that number too, so read it against what you intended — if it is higher than that, the plan missed cards and a second call files them.
list_boards
ChatGPTList a project's boards as a tree: each folder's board with its name, uid (pass it as whiteboard_uid), parent board and the folder element that opens it. Names only; read a board's content with get_whiteboard_elements and its whiteboard_uid.
list_documents
ChatGPTList the user's documents. scope: 'project' (requires project_uid), 'private', 'shared', or 'recent'. Returns summaries; use get_document for full content.
list_projects
ChatGPTList the user's Flow projects — the top-level containers holding whiteboards, documents and tactics. Returns id, uid, title, status, the user's role, and created_by_you: false means someone else made this project and shared it, so what is on it is mostly THEIR work, not the user's. Use a project uid with other tools to drill in. Order by 'viewed' to see what they actually work on; the default 'created' is newest-made first, which for a long-standing account is mostly the projects they opened once.
list_tactics
ChatGPTSearch the tactic LIBRARY — the published expert frameworks a user can attach or start from. Use this to find a tactic by name. Different from get_tactic, which reads a tactic already living inside a project.
move_element
ChatGPTMove an EXISTING element: into a wall (parent_uid + parent_order_index), out of a wall (parent_uid: '' plus a canvas location), reordering within a wall, or repositioning any element (location only, in board coordinates). Frame membership follows the destination on its own — land inside a frame to join it, outside to leave it. Applies immediately, like the user dragging it; the user can undo.
put_document_in_table_cell
ChatGPTPoint a cell of a table's document column at a project document that already exists. Find candidates with list_documents. To create a new one instead, use create_document_in_table_cell.
read_file
ChatGPTRead the text of a FILE on the board (PDF, DOCX, XLSX, XLS, CSV, TXT, MD, code…) and return its contents. Use this BEFORE answering anything about a file — summarising it, pulling its rows into a table, turning it into tasks or a shotlist. A board read gives you only the file's name and address; its contents come from here. Never answer from a filename. Long files come back truncated, and the result says so.
remove_deck_slides
ChatGPTDelete slides from a deck by uid and close the gap in the order. A deck has to keep at least one slide; to get rid of a whole deck, delete the deck element itself.
reorder_deck_slides
ChatGPTPut a deck's slides in a new order. Pass EVERY slide uid, in the order you want them — a partial list is refused rather than guessed at.
request_photo_upload
ChatGPTA picture the user attached in this chat never reaches Storyflow: you see it, Storyflow cannot. Call this to let them put pictures from their phone or computer on a board in one tap. It returns a link good for 15 minutes; put it in your reply as a link whose text is "Add your photos". The user taps it, picks any number of pictures, and each one lands on the board as it uploads, visible in the board card and in Storyflow. Pass target_uids for empty frames you placed for them, or parent_uid for the wall the pictures belong in; with neither, a wall is made for them when the first picture arrives. Never tell the user Storyflow cannot take their photo, and never ask them to upload inside Storyflow.
search
ChatGPTSearch the user's Storyflow projects, boards and documents by title. Returns ids for fetch: project:<uid>, board:<project_uid>/<whiteboard_uid>, document:<project_uid>/<uid>.
set_connection_text
ChatGPTChange the text riding on arrows already on the board, or clear it with an empty string. This is the answer to 'put the durations on those arrows' or 'make that one 6 weeks'. Do NOT delete the arrow and draw a new one: redrawing loses the curve the user dragged into it and gives the connection a new uid. edge uids come from get_whiteboard_edges or connect_whiteboard_elements' result — element uids are not edge uids.
set_document_cover
ChatGPTGive a document an icon and a banner image, the way a person would from the document header. Do this for documents YOU create — not for one the user made and you only edited. icon takes a TOPIC WORD, not an icon name: research, idea, strategy, planning, tasks, notes, meeting, launch, archive, inbox, templates, settings, design, writing, brand, photo, video, music, audio, marketing, sales, finance, budget, invoice, analytics, legal, clients, team, support, product, shop, engineering, bugs, security, data, cloud, travel, food, health, fitness, home, education, science, nature, mountain, camping, weather, transport, gear, events, gifts, reading, location, global, favourites, important, private, time, folder. A word outside that list sets no icon and tells you so. It also accepts a stored image key to use a picture as the icon. banner takes 'gradient' for one of the app's own gradients (free, and the right answer unless the subject genuinely wants a photograph), or a stored image key from find_document_images or generate_document_image. A url from the open web is refused: a cover comes from the same places the user's own picker offers.
show_board
ChatGPTShow a Storyflow board inside the chat: the user's real board, live, so they watch each change land as you make it, and can edit it right in the card or open it in Storyflow. Call it ONCE per board per conversation, before your first write to that board, or when the user asks to see a board. Every call draws a new card, so never call it after each write. Chat apps that cannot draw it show the link instead.
update_chart
ChatGPTChange a chart that is ALREADY on the board — its data, its title, or how it is drawn. This is a patch: send only what changes and the rest of the chart is kept, so "make it horizontal" is {layout: "horizontal"} and nothing else. Use it instead of building a replacement whenever the chart is nearly right — the user keeps its place, size and the undo history that goes with it. It applies immediately and the user can undo it. A chart's TYPE cannot change here (a bar chart cannot become a line chart): that is a create plus a delete of the old one.
update_deck
ChatGPTChange a deck that is already on the board: its title, its aspect, or any part of its theme. A PATCH — pass only what changes, because the palette, font and type scale the user set by hand are all in here and sending the ones you did not mean to touch resets them. Re-theming re-skins every slide at once; you never rewrite slides to change a colour.
update_element
ChatGPTUpdate an EXISTING element in place: its content and/or its styling. Applies immediately, exactly like the user editing on the canvas, and the user can undo it. content: for a note, todo or heading pass the full replacement text, markdown or HTML; for a ticket pass an object with the fields to change (title, description, label, labelColorHex, date); for other types pass an object patching the content keys you saw in get_whiteboard_elements A FOLDER takes {boardName} to rename it, {iconName} to change its icon and {iconColorHex} for its colour — for those two pass a WORD, not a hex or an icon name: iconName is one of [research, idea, strategy, planning, tasks, notes, meeting, launch, archive, inbox, templates, settings, design, writing, brand, photo, video, music, audio, marketing, sales, finance, budget, invoice, analytics, legal, clients, team, support, product, shop, engineering, bugs, security, data, cloud, travel, food, health, fitness, home, education, science, nature, mountain, camping, weather, transport, gear, events, gifts, reading, location, global, favourites, important, private, time, folder] and iconColorHex is one of [tan, blue, rose, purple, steel, brown, red, navy, violet, slate, coral, orange] (either can be 'none' to clear it), and {coverImage} to put a PICTURE on the tile instead of an icon — that is what a folder's cover image or thumbnail is. coverImage takes a stored image key (a board image's imageUrl, a generated image's image_url, or a gallery key), never a web url; 'none' clears it back to a plain tile. A folder shows a picture or an icon, never both, so setting iconName on a folder that has a cover replaces the picture. Changing only the colour leaves the icon or cover exactly as it is. An IMAGE (or AI image) takes {caption} — the line shown UNDER the picture, which is what "caption this" or "write a caption" means; a bare string is read as the caption too. An empty caption hides the caption row, and {showCaption: false} hides a caption while keeping its text. Nothing else about an image is edited here: its url, crop and source images are refused. Captions are not labels — labels are the parameter below. A TABLE is the one fiddly case: pass {tableData: "<json STRING>"} — tableData is stringified JSON, not an object — shaped {id, type:'table', data:{name, columns:[{id,name,type}], columnOrder:[id], rows:[{id, values:{<columnId>: cell}}], rowOrder:[id]}}. Keep the ids of everything you are not changing. Adding a column means appending to BOTH columns and columnOrder and adding that column's id to EVERY row's values; removing one means deleting it from all three; reordering means reordering columnOrder or rowOrder alone. Send the WHOLE table back, not a fragment. A column may also carry cellType ('number'|'currency'|'percent'|'datetime'|'duration'|'checkbox'|'rating'|'labels'|'status'|'person'|'url'|'email'|'phone'), width (px), icon (its header glyph) and, on a currency column, currency (an ISO code like 'EUR' picking the symbol its cells render in — the cells hold a bare number either way). data itself carries the table's own heading: title (the name shown ABOVE the grid), description (the caption under it) and icon (the glyph beside the title, a WORD from the same list as a column's). Renaming a table means changing data.title — data.name is the payload's internal label and is invisible on the canvas. PRESERVE every such field you are not deliberately changing, or you will silently reset the user's column types, widths, icons, captions and the table's own name. A column's icon is normally left off entirely, because the canvas derives one from the column's NAME — so renaming a column is usually all it takes to change its icon. To pin a specific one, set icon to a WORD from [name, title, owner, assignee, person, team, client, company, audience, character, identity, personality, background, relationship, story, status, stage, progress, priority, approval, done, task, checklist, type, category, tags, topic, platform, channel, date, deadline, schedule, calendar, duration, time, count, quantity, id, …
write_document_content
ChatGPTAppend to (or replace) the contents of a document by uid. Use this to fill a document you created on a board, one section per call, so it builds up rather than arriving all at once. For the document currently open on screen, use the editing tools instead.