create_block_variant
ChatGPTCreates a non-fallback audience variant and seeds content from the explicit, pinned, active-profile, fallback, or base block in that order.
create_campaign
ChatGPTCreates one campaign from a chosen design system, optionally in a folder, in a language, or for an integration and one of its destinations. Find ids with list_design_systems, list_folders, and list_integrations first; when more than one integration is available, pass the chosen one, and when the chosen integration has several destinations, pass destinationId too (list_integrations lists them; without it the call fails with "Choose a Destination"). Returns the new campaign with its id.
create_campaign_from_type
ChatGPTCreates one campaign from a campaign type (see list_campaign_types). The type decides the design system, destination and approvers, and the folder unless you pass one. When the type has a namePattern, pass nameFields with a value for every {field} other than {type} and {date}, and no name; otherwise pass name. When the type's hasDestination is false, pass destinationId from list_integrations. The result includes the type's instructions: follow them when you build the campaign.
create_segment
ChatGPTCreates a reusable Segment from Recipient Field conditions, on the campaign's integration or on the one named by integrationId. A Segment cannot reference another Segment. Call get_segmentation_catalog first: an integration that cannot segment refuses this.
delete_block
ChatGPTDeletes the named Block only if it is still at the specified 0-based index in the content zone. Concurrent changes fail safely.
delete_block_variant
ChatGPTDeletes a non-fallback block variant. If it is the final non-fallback variant, clears segmentation for the block.
duplicate_campaign
ChatGPTDuplicates one campaign, optionally with a new name, folder, language, integration, or destination. Omitted, the copy keeps the source's destination; when the chosen integration has several destinations, pass destinationId (list_integrations lists them). Returns the copy with its id.
get_block
ChatGPTReturns the current canonical values for one Campaign Block, Block variant, or the global Campaign settings. Use it when get_campaign reports that its complete response was truncated.
get_campaign
ChatGPTReturns the campaign's current definition: its blocks in order, their values, block variants, subject and preheader, and the design system's content zones. Read it before editing and once more after the final edit.
get_campaign_performance
ChatGPTHow one campaign's latest send performed, as reported by the ESP: sent, delivered, unique opens and clicks, open, click, click-to-open, unsubscribe and bounce rates, the organization's average open and click rates, clicks per link, and opens and clicks in 3-hour buckets over the 7 days after the send. Rates are fractions (0.25 is 25%). When state is not_available, explanation says why.
get_campaign_revision_state
ChatGPTReads the campaign's latest revision, whether the draft holds changes not yet in a revision, and how its latest send performed when the ESP has reported one.
get_guidelines
ChatGPTWhat to read before working here: how a build differs from a change, how content goes into a campaign, how to check and report, the organization's tone of voice, and the catalogue of its skills (load one with load_skill when its description fits). Call it once at the start of a task.
get_organization_profile
ChatGPTThe organization the signed-in user is working in: name, configured languages, and how many campaigns and design systems it has.
get_preflight_checks
ChatGPTReturns the pre-flight run for the campaign's LATEST SAVED REVISION — not the current draft. Findings are stale for anything edited since that revision, and there is no run at all until someone creates one. To check work you just did, use run_preflight.
get_segmentation_catalog
ChatGPTLists the Recipient Fields and Segments available for block variant conditions on this campaign, or one Segment in full by segmentId. Call it before creating variants or Segments: when the campaign's integration cannot segment, the result has segmentationSupported: false with the reason, and the variant and Segment tools will refuse. Deleting a variant still works, so leftovers can be cleaned up.
insert_block
ChatGPTInserts a Module as a Block with optional initial values at a 0-based index within a content zone. An index past the end appends the Block. For Campaign builds, supply all known final Block content in values. Omit values only when Design System defaults are intentionally the finished content. Do not insert defaults merely to update the Block immediately afterward. Repeatable settings contain items with a values object, for example values: { cards: [{ values: { title: "First card" } }] }. Insert assigns missing item ids.
list_campaign_performance
ChatGPTThe organization's sends in a period (sentAfter, sentBefore as ISO 8601), with per-send numbers, totals and average rates. Sort by sentAt (default), openRate or clickRate; rate rankings leave out sends delivered to fewer than 100 recipients unless minDelivered says otherwise. Each send carries the emailName it was exported under; find the campaign with search_campaigns.
list_campaign_types
ChatGPTLists the campaign types the user can create a campaign from: kinds of campaign the organization's admins set up, such as a brand or a newsletter. Each fixes the design system, destination, folder and approvers, and may have a naming scheme (namePattern) and instructions. When required is true, create_campaign is refused; use create_campaign_from_type.
list_campaigns
ChatGPTLists recent campaigns the signed-in user can access, newest first. Each result carries the campaign's id for the campaign tools; hasPerformanceData marks campaigns whose send numbers get_campaign_performance can read. Use offset to page.
list_components
ChatGPTLists a page of Modules currently available for insertion, their compact valueContract, the Block values format, and the Design System content zones they may be inserted into. Use the contract to populate insert_block.values in the same write. Follow pagination.nextOffset while pagination.hasMore is true to browse more Modules. If a large catalogue marks a chosen Module's valueContract as omitted, call this tool again with that componentId for its focused contract.
list_design_systems
ChatGPTLists design systems. The default purpose "createCampaign" returns published design systems the user may create a campaign from, owned first and then shared (continue with the returned cursor and nextSource while hasMore is true). Each result carries the id create_campaign takes.
list_folders
ChatGPTLists a bounded page of accessible Campaign Folders for choosing a creation or move destination. Use offset to continue while hasMore is true. When truncated is true, some Folders could not be checked, even if hasMore is false. Do not conclude a missing Folder does not exist or substitute the root. Ask the User to choose an available destination or retry later. A null folder means the workspace root.
list_integrations
ChatGPTLists the organization's integrations, each with its destinations (id, name, isDefault). An integration's id is its external id: what context.integration.id holds in design system Liquid, and the integrationId create_campaign and duplicate_campaign take. A destination's id (dst_…) is the destinationId those two take, and it is required when the chosen integration has several destinations.
list_recipient_fields
ChatGPTLists Recipient Fields valid for subject, preheader, copy, and links that allow personalization. Use insertionSyntax exactly as returned.
load_skill
ChatGPTLoads the full instructions of one of the organization's skills by its exact name, as listed by get_guidelines. Load a skill when its description matches the task at hand; do not load them all.
move_block
ChatGPTMoves a Block within or across content zones. Use expectedBlockId from the latest Campaign read to reject a stale positional move.
move_campaign_to_folder
ChatGPTMoves one campaign to a folder, or to the workspace root with a null folderId.
preview_campaign
ChatGPTShows the user an interactive preview of the campaign: subject and preheader, the rendered email, a desktop/mobile switch, a pre-flight button, and a link to open it in Better Email. Call it as the last step of every build and of any substantial edit, and whenever the user asks to see the campaign; the preview renders in the chat, so do not describe the email or paste its HTML.
reorder_block_variants
ChatGPTSets the complete order of non-fallback variants. The fallback variant always remains last.
request_upload_url
ChatGPTThe way to upload an image file you have on disk, when you can run a shell command: one curl, no base64. Returns a short-lived upload URL and the exact curl line to run; the curl answers with the hosted image url and its dimensions, ready for a Block's image input with update_block. Upload the ORIGINAL file. Never resize, compress or convert it first: Better Email serves every image at the width and device pixel ratio the design system declares for that image input, so a file you shrank first can only come out worse. Crop or recompose only when the design needs a different subject or aspect ratio than the source. The URL is good for 15 minutes, for this campaign and this media type, and can be used once. Use upload_image_from_url when the image is already at a public https URL, and upload_image only when you have no shell.
run_preflight
ChatGPTRuns the pre-flight checks against the CURRENT DRAFT — the campaign exactly as it stands right now, including every edit made this turn — and returns the findings inline. Creates no revision and leaves no history. Use this to verify your own work. depth 'fast' (the default) runs the deterministic checks (links, images, alt text, unrendered Recipient Fields, subject and preheader, accessibility, size) in a few seconds; depth 'full' additionally runs the AI copy and rendered-screenshot checks, which take considerably longer. The draft is only verified when summary.activeFindings is 0 AND summary.unverifiedChecks is 0: a check that could not reach a verdict — a skipped stage, a model timeout, an unavailable render, a check whose screenshot pass failed while its text pass passed, a stage still outstanding, or a run that failed outright — produces no finding, so activeFindings alone will read as clean when nothing was actually checked. notEvaluatedCheckIds names the checks a fast run skipped; rerun at depth 'full' to settle them. status 'not_run' means nothing was checked at all.
screenshot_campaign
ChatGPTRenders the campaign as it stands and returns a desktop or mobile screenshot. Use it after changes to layout, spacing, colour, images, or responsive behaviour.
screenshot_website
ChatGPTRenders a public web page and returns a screenshot of it, so you can see a brand's layout, colours, imagery and typography rather than infer them. Use it before building a campaign from a customer's website. The default is the top of the page at desktop width, which is the sharpest view; fullPage captures the whole page but a long one is scaled down and its fine print may not be legible.
search_campaigns
ChatGPTSearches the organization's campaigns and design systems by meaning and by name. Each campaign result carries its id for the campaign tools; hasPerformanceData marks campaigns whose send numbers get_campaign_performance can read.
set_block_fallback_hidden
ChatGPTSets whether the fallback/everybody-else variant is hidden. This is an absolute set, never a toggle.
set_block_variant_condition
ChatGPTUpdates a non-fallback block variant's audience condition and/or display name.
update_block
ChatGPTUpdates only the supplied values on a Block, Block variant, or global Campaign settings. Values are validated against the Design System before writing. A repeatable setting is sent as the full array of items, and every item needs an id and a values object, for example values: { cards: [{ id: "card-1", values: { title: "Updated card" } }] }. An item with the id of an existing item keeps every input you leave out. An item you leave out of the array is removed. An item with a new, non-empty id is added.
upload_asset
ChatGPTDownloads an approved non-image asset URL into Better Email storage and returns its hosted URL and media type.
upload_image
ChatGPTUploads a small image you hold as bytes, for when you have no shell. Send the bytes base64 in base64 with their media type, up to 10 MB, and it returns the hosted URL and dimensions, ready for a Block's image input. Prefer request_upload_url whenever you can run a shell command: base64 in a tool call costs you output tokens for every byte of the file, and a megabyte takes minutes. Use upload_image_from_url when the image is already at a public https URL. Send the ORIGINAL file: never resize, compress or convert it to make it fit this call, because Better Email serves every image at the width and device pixel ratio the design system declares for that image input.
upload_image_from_url
ChatGPTDownloads an image that is already at a public https URL into Better Email storage and returns the hosted URL and dimensions, ready for an image input. An SVG is converted to PNG unless convertSvg is false. Point it at the ORIGINAL image, the largest the source offers: never resize, compress or convert it first, because Better Email serves every image at the width and device pixel ratio the design system declares for that image input. For a file on disk use request_upload_url when you can run a shell command, or upload_image when you cannot.
upload_svg
ChatGPTUploads SVG markup you wrote into Better Email storage, for a shape that does not exist as a file yet. Converts it to PNG by default, which is what an image laid out normally needs since email clients do not render SVG reliably; pass convertSvg false to keep the vector, which is required for an imgTag mask_url asset because a vector mask stays sharp at every frame size. A preserved vector reports no dimensions. Use upload_image_from_url instead when the artwork already exists at a URL.