Publish the reviewed placement version, including its binding, targeting and approved component revision. expected_version rejects intervening edits. This changes the customer site. Cross-site super-admin callers must pass site_id from get_account_status; site-scoped callers stay on their own site.
5 parameters
| Parameter | Type | Description |
|---|
placement_id required | string | placement id |
expected_version required | number | Version from the latest read; conflicts return 409 |
site_id optional | string | Required for cross-site super-admin sessions: exact target site id from get_account_status. Ignored by site-scoped sessions, which remain locked to their own site. |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Approve a pending ad-theme suggestion into an active theme. Requires write authority and tenant approval policy permission; does not publish a content variant.
6 parameters
| Parameter | Type | Description |
|---|
suggestion_id required | string | |
label optional | string | |
description optional | string | |
utm_content_value optional | string | |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Attach a library asset to a content variant field — overwrites whatever image was on that field with the asset's blob_url. Also copies the asset's provenance (prompt, brief / reference / planner attribution, tags) into the variant's generated_metadata so the audit trail follows the image. Returns { ok, asset_id, variant_id, blob_url, field_key }. Use after search_assets surfaces an existing asset that matches what the operator wants — saves a generation call. The variant's image_url is also synced to the asset's blob_url so the runtime tag picks it up immediately.
6 parameters
| Parameter | Type | Description |
|---|
asset_id required | string | Asset id from search_assets (asset_<uuid> shape). |
variant_id required | string | content_variants.id to attach to. |
field_key required | string | The payload field key on the variant to overwrite (e.g. "image_url", "hero_image_url"). |
alt optional | string | Optional alt text override. When omitted, the variant's existing image_alt is preserved. |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Attach an existing resource to a campaign's manifest by REFERENCE (never a copy). Idempotent on (campaign, kind, ref_id): a repeat call updates `required`/`ref_version` and returns created:false. The ref must exist in this site or the call 404s. Attaching a variant or trigger also sets its serving-path campaign_id when unset, and is REFUSED (409) when it already serves under another campaign - detach it there first. Live content needs confirm_serving_change. `required:false` components are reported but do not gate readiness. Any change voids an approval (response `stage_reset`).
8 parameters
| Parameter | Type | Description |
|---|
campaign_id required | string | Campaign ID |
kind required | "page" | "variant" | "trigger" | "offer" | "audience" | "experiment" | "provider_campaign" | What the ref_id names |
ref_id required | string | The resource's own id: pages.id, content_variants.id, triggers.id, offers.id, custom_segments.id, a layout/component experiment id, or ad_platform_campaigns.id |
required optional | boolean | Gate readiness on this component (default true) |
ref_version optional | string | null | Optional pinned version (page revision id) |
confirm_serving_change optional | boolean | Required (true) when the variant is active or the trigger enabled: attaching puts live content under this campaign's window and audience (off the site if the campaign is not serving); detaching removes that gate so it serves to everyone. Without it the call returns 409 with details.reason = serving_change_requires_confirmation. Confirm with the operator first. |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Author a "move object" placement: relocate an EXISTING element on the page to a new location, WITHOUT changing its copy or injecting new content (pure rearrangement). Creates a source zone (element_selector = the element to move) + a move_object content variant whose payload carries the destination anchor + position. Use AXO skills with browser access, or the dashboard picker, to inspect the source and destination elements and obtain source_selector + dest_selector first. Target ONE segment via segment_id, OR all_visitors:true for everyone (the default — moves are usually global). CAUTION: once published this ships to the live site within ~60s. Review both selectors and the proposed placement before publishing.
10 parameters
| Parameter | Type | Description |
|---|
page_pattern required | string | URL pattern the move applies to (e.g. "/", "/blog/*") |
source_selector required | string | CSS selector of the EXISTING element to relocate (the object to move) |
dest_selector required | string | CSS selector of the destination anchor to move it next to / into |
position optional | "before" | "after" | "inside_start" | "inside_end" | Where to place the source relative to the destination. Default "after". ("replace" is intentionally not allowed for a move — it would destroy the destination.) |
zone_key optional | string | Zone identifier. Defaults to a generated "move_*" key. |
display_name optional | string | Human-readable name for the move. |
segment_id optional | string | Audience segment. Omit when all_visitors is true. |
all_visitors optional | boolean | Apply to ALL visitors regardless of segment (default true for moves). When false, provide segment_id. |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Clone a system or site template into a new site-owned template.
4 parameters
| Parameter | Type | Description |
|---|
template_id required | string | Source template ID |
name optional | string | Name for the clone |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Close a LAUNCHED or PAUSED campaign for good, as a durable job. Stops serving (status ended), pauses its running experiments (never ends them), then snapshots the OUTCOME into the campaign (get_campaign -> campaign.outcome) with every number labeled by evidence: causal (holdout lift per variant, offer and trigger; insufficient_evidence is reported as such, never as zero), observed (the goal's converting-session rate in the live window vs the same-length window before launch - not causal), and platform_attributed (ad spend and the platform's own conversions). Writes a campaign_closed row to the decision ledger. IRREVERSIBLE: a closed campaign is read-only and cannot be relaunched; use duplicate_campaign to run it again. Requires admin scope. Does not retire pages or pause ad platform campaigns (reported as needs_operator). Pass rationale to record why. Confirm with the operator first.
5 parameters
| Parameter | Type | Description |
|---|
campaign_id required | string | Campaign ID |
actor optional | string | Who is closing (recorded on the job, audit trail and decision ledger) |
rationale optional | string | Why the campaign is being closed (recorded on the decision ledger) |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Create a new campaign with a brief (objective, offer, tone, themes).
11 parameters
| Parameter | Type | Description |
|---|
name required | string | Campaign name |
brief optional | object | Campaign brief |
status optional | "active" | "draft" | "paused" | "archived" | |
goal_id optional | string | null | Primary goal: a site_goals.id (see get_site_config goals). Must be an ACTIVE goal of this site; null clears it. Readiness requires one. |
owner_user_id optional | string | null | Owner (a user id or name) responsible for the campaign; null clears it. |
starts_at optional | string | ISO-8601 start date for automated scheduling |
ends_at optional | string | ISO-8601 end date for automated scheduling |
eligibility optional | object | Advanced segment matching rules (e.g. segment_member, audience_signals) |
priority optional | number | Evaluation priority (higher = evaluated first) |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Create a draft test of one or more component placements against the unchanged page. With only placement_id it is the classic 50/50 test; additional_placement_ids adds further treatment arms (C, D, ...) so one visitor is drawn into exactly one of: unchanged page, treatment B, treatment C... with an equal fixed split. Every additional placement must sit on the same page pattern, anchor selector, audience and schedule as placement_id (otherwise 409 treatment_*_mismatch) and keeps its own placement row; a placement already in an open test is refused. Starting freezes each arm's revision, binding and audience; assignment is sticky per visitor across all arms. Requires migration 350 for more than one treatment (503 multi_treatment_unavailable otherwise). Cross-site super-admin callers must pass site_id from get_account_status; site-scoped callers stay on their own site.
7 parameters
| Parameter | Type | Description |
|---|
placement_id required | string | First treatment placement id (arm B); the control is cloned from it |
additional_placement_ids optional | string[] | Further treatment placement ids (arms C, D, ...), max 4. Same page, anchor, audience and schedule as placement_id. |
name optional | string | name |
hypothesis optional | string | hypothesis |
site_id optional | string | Required for cross-site super-admin sessions: exact target site id from get_account_status. Ignored by site-scoped sessions, which remain locked to their own site. |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Create a DRAFT component placement. For between, both anchors must be adjacent siblings. Preview and approve the revision before activation. Cross-site super-admin callers must pass site_id from get_account_status; site-scoped callers stay on their own site.
20 parameters
| Parameter | Type | Description |
|---|
idempotency_key optional | string | Stable key for retries of this draft placement creation |
field_overrides optional | object | Only exposed revision field keys; placement-specific text/image/link values. Empty object clears customizations. |
component_id required | string | component id |
component_revision_id required | string | component revision id |
position required | "before" | "after" | "between" | "inside_start" | "inside_end" | "replace" | position |
element_selector required | string | element selector |
second_anchor_selector optional | string | second anchor selector |
anchor_policy optional | "required" | "when_present" | required (default) reports a missing anchor. when_present waits for a conditional primary anchor without reporting absence as an error; invalid or ambiguous anchors still fail. |
page_pattern required | string | page pattern |
name optional | string | name |
page_type optional | string | page type |
order optional | number | order |
priority optional | number | priority |
eligibility optional | object | eligibility |
segment_id optional | string | segment id |
starts_at optional | string | ISO timestamp, or empty string to remove start |
ends_at optional | string | ends at |
goal_id optional | string | Built for goal: id of an active goal of this site (from get_site_config) that this placement is meant to move. The Impact page and get_zone_exposure_report group placements by it. A goal of another site is refused with goal_not_found. It is a reporting label: it never changes what visitors see, makes no new placement version and is allowed during a test. Returns placement_goal_unavailable (503) on a database that does not have the column yet. |
site_id optional | string | Required for cross-site super-admin sessions: exact target site id from get_account_status. Ignored by site-scoped sessions, which remain locked to their own site. |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
Create a DRAFT fixed-split test over existing content variants in one zone that all target the same audience segment (the all-visitors segment = everyone, independent of segment ranking). include_control adds an Original arm (the page as-is, arm A) that still records exposures. Allocation is visitor-sticky and never moved by the optimizer; while running, eligible visitors always get their drawn arm. One open test per zone. Nothing serves until update_content_experiment action=start.
8 parameters
| Parameter | Type | Description |
|---|
zone_id required | string | Zone id |
variant_ids required | string[] | 2–5 content variant ids in that zone (same segment). Arm keys follow this order after the optional Original arm. |
include_control optional | boolean | Add an Original control arm (default true) |
name optional | string | Test name |
hypothesis optional | string | What you hope to improve |
split optional | object | null | {armKey: weight} on any non-negative scale, e.g. {A: 50, B: 50}. Omit for equal. |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Create a personalized content variant for a zone + segment combination. For copy_swap/hero_swap, check the zone's field_schema (get_zones) FIRST and key the payload by its payload_key/canonical_name entries — a payload sharing NO renderable key with a schema-bearing zone binds nothing and is refused with a 400 naming the accepted keys. Do not copy another variant's payload shape without checking the target zone's schema. For product_reco variants, create with an empty payload ({}) and then call configure_product_reco to set the recommendation mode and curated products.
12 parameters
| Parameter | Type | Description |
|---|
zone_id required | string | Zone ID |
active optional | boolean | false saves an inactive private draft for human review; required under propose-only. Omit to enable immediately when policy permits. |
segment_id optional | string | Target segment ID (legacy mode, or mirrored from eligibility) |
type required | "overlay" | "hero_swap" | "copy_swap" | "product_reco" | "move_object" | Variant type |
payload required | object | Variant payload. For overlay/hero_swap/copy_swap: { headline, body, cta, image_url }. For product_reco: pass {} and configure via configure_product_reco. For move_object: { dest_selector, position } — but prefer author_move, which also creates the source zone. |
eligibility optional | object | Advanced segment matching rules (e.g. segment_member, audience_signals) |
priority optional | number | Evaluation priority (higher = evaluated first) |
campaign_id optional | string | Link this variant to an orchestration campaign |
destination_page_id optional | string | Make this a ROUTE to an axo Page (migration 260): the CTA URL is then SERVER-derived (<pageUrl>?vt_route=<variantId>) — do not supply URL fields in the payload. Prefer create_route. |
ends_at optional | string | Optional scheduled expiry (ISO 8601, at least 5 minutes out, within a year). The hourly watchdog sweep deactivates the variant once this passes and posts a notification. Omit for no expiry. |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Create a page-level layout experiment as a DRAFT. SIDE EFFECTS: inserts the experiment row, one layout-role zone for the container (page_pattern + element_selector) and an INACTIVE control variant for arm "A" ("Original"); nothing serves to visitors — a draft has no alternative layouts yet and cannot run or pause. Adding fragment arms (including the AI-generated arm B), extra containers, and starting the test are dashboard actions today. element_selector must be a CSS selector for the container (max 300 chars, no <>{ }); page_pattern must start with "/". Requires the layout_experiments module.
7 parameters
| Parameter | Type | Description |
|---|
name required | string | Experiment name (max 120 chars), e.g. "PDP gallery-first layout" |
page_type required | string | Page type the test runs on (e.g. home, pdp, plp, cart, checkout, blog) — must be one of the site's known page types |
page_pattern required | string | Path pattern the container appears on, starting with "/" (e.g. /products/*) |
element_selector required | string | CSS selector for the container being tested (e.g. main.product, #hero) |
hypothesis optional | string | What the alternative layout is expected to change, and why (max 2000 chars) |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Create an offer in this site's library. It is ALWAYS created as an UNAPPROVED DRAFT: a human must ratify it in the dashboard (approve the terms, and attest the code exists and is active in their commerce platform) before it can ever serve. There is no `status` argument here and no tool on any surface that can make an offer live — that transition is dashboard-only, by construction. MONEY IS CENTS AND PERCENTS ARE BASIS POINTS, integers only: value_bp 2500 = 25% off, value_cents 1000 = $10 off. The write is REJECTED when the depth exceeds the site's max_discount_pct ceiling, or when it meets/exceeds the site's gross margin (every order at that depth loses money and no conversion lift can fix it). `code` must be a discount code the merchant's platform ALREADY honors — fulfillment_mode accepts only "existing_code". Returns { id, warnings }; warnings cover mirrored terms and the break-even lift this discount needs. Then place it with place_offer.
21 parameters
| Parameter | Type | Description |
|---|
name required | string | Internal offer name (max 200 chars) |
offer_type required | "percent" | "fixed" | "free_shipping" | "gift" | "tiered" | percent needs value_bp. fixed needs value_cents. free_shipping/gift/tiered carry no single headline value, so the depth cap and break-even hint do not apply to them. |
value_bp optional | integer | Percent discount in BASIS POINTS, 0-10000 (2500 = 25.00%). Required for offer_type=percent. |
value_cents optional | integer | Fixed discount in CENTS (1000 = $10.00). Required for offer_type=fixed. |
currency optional | string | 3-letter ISO-4217 code (e.g. "USD"). Leave unset for percent / free_shipping. |
code optional | string | The discount code AS IT EXISTS in the merchant's commerce platform. AXO never mints codes. Two live offers cannot claim the same code. |
min_order_cents optional | integer | MIRRORED TERM (cents): minimum basket. Displayed as fine print and used to reason about a fixed offer's depth — their platform enforces it, and if the two disagree theirs wins. |
max_discount_cents optional | integer | MIRRORED TERM (cents): cap on the discount. Displayed as fine print only; AXO never enforces it at checkout. |
max_exposures_per_visitor optional | integer | The ONE cap AXO owns and enforces: how many times we show this offer to one visitor. There is deliberately no redemption limit — that ledger belongs to the merchant's platform. |
starts_at optional | string | ISO-8601 timestamp the offer becomes servable. |
ends_at optional | string | ISO-8601 timestamp the offer stops serving. Must be after starts_at. Enforced at config-build time, so the offer goes dark everywhere on the next build. |
stacking optional | "exclusive" | "stackable" | "group" | MIRRORED TERM, rendered as fine print ("Not combinable"). Default "exclusive". Their cart decides what actually stacks. |
fulfillment_mode optional | "existing_code" | Only "existing_code" is accepted: we reference a code the merchant already honors and never mint one. Minting is deliberately deferred — it is where AXO would start competing with their loyalty platform on accounting and liability. |
tiers optional | object[] | For offer_type=tiered: up to 10 entries of { min_order_cents, value_bp | value_cents }. |
gift_sku optional | string | For offer_type=gift: the catalog SKU the merchant adds to the cart. Required for gift offers. |
eligibility optional | object | SegmentPredicate (same shape as a content variant's eligibility), so loyalty tier / lapse (crm_attribute, profile_attribute) and anonymous behavior (propensity, intent, affinity) feed ONE evaluator. |
redeem_url optional | string | Where the offer CTA sends the visitor. Falls back to the placement's own cta_href when unset. |
terms_url optional | string | Full terms page; the renderer links it as "Terms apply". |
presentation optional | object | Default presentation inherited by every placement: { headline, body, cta, cta_href, show_code, show_expiry }. A placement's own presentation keys win over these. |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Create a page type configuration for sitemap analysis.
5 parameters
| Parameter | Type | Description |
|---|
page_type required | string | Page type (product, category, blog) |
url_pattern required | string | URL pattern to match |
selectors optional | object | CSS selectors for page elements |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Create a link a client or stakeholder can open, without logging in, to review one audience's view of the site on the real storefront: the private working copy (view "draft", the default) or exactly what visitors see (view "live"; ordinary auto-site links show live content; placement_id plus expected_version instead freezes one saved placement on either site mode). The link carries only that audience's content. Returns the URL to send. The link expires on its own (7 days by default, 30 at most) and can be turned off with revoke_preview_share_link. Pass a site-relative path to open on a specific page and a short label so the link is recognisable in the dashboard's list.
10 parameters
| Parameter | Type | Description |
|---|
placement_id optional | string | Component placement to freeze in this link; requires expected_version. Other content uses the published baseline. |
expected_version optional | integer | Reviewed placement version from list/get_component_placement. |
segment_id required | string | Audience (segment id) the reviewer sees the site as. Use get_segments to find ids. |
view optional | "draft" | "live" | draft (default): unpublished edits included. live: what visitors get today. |
path optional | string | Site-relative page to open on, e.g. /products/widget. Default /. |
zone_id optional | string | Optional zone the link is about; the zone header lists its links. |
label optional | string | Optional short note shown on the review page and in the list. |
ttl_days optional | number | How long the link works, in days. Default 7, max 30. |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Create a new triggered message. Requires name, mode (immediate|dormancy), watch_event, and at least one destination.
17 parameters
| Parameter | Type | Description |
|---|
name required | string | Human-readable name |
description optional | string | |
mode required | "immediate" | "dormancy" | Fire mode |
watch_event required | string | Event type to watch |
cancel_event optional | string | Event that cancels dormancy |
criteria optional | object | Matching criteria |
delay_ms optional | number | Dormancy delay in ms |
window_ms optional | number | Cancel-event window in ms |
identifier_type optional | "email" | "phone" | "device" | "external_id" | "profile_id" | |
destinations required | object[] | Destination configs |
cooldown_per_profile_ms optional | number | |
global_rate_limit_per_min optional | number | |
optimization_mode optional | "axo_bandit" | "external" | Optimization mode (axo_bandit or external) |
send_window optional | object | null | Per-trigger send window. null inherits the site setting; {"enabled": false} sends at any hour (for safety triggers); {"enabled": true, "start_hour": 9, "end_hour": 20} sets this trigger's own local hours. An enabled window needs the site trigger_timezone, and its start and end (with missing hours taken from the site) must differ. Needs migration 354. |
frequency_cap_exempt optional | boolean | When true this trigger ignores the site's per-person cap and its fires do not count toward it. For safety triggers such as a declined card. Default false. |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Create a new site-owned payload template for triggered messages.
7 parameters
| Parameter | Type | Description |
|---|
name required | string | Template name |
description optional | string | |
format required | "json" | "html" | "form" | Template format |
body required | string | Template body with mustache placeholders |
example_destination optional | string | Intended destination type |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Create a new personalization zone on the site. For lightbox zones (zone_key="lightbox"), pass display_rules to set when/where/who/how-often the popup fires — including country targeting (audience.country) and day/hour windows (schedule); otherwise call list_lightbox_presets and use one of those rule objects verbatim.
9 parameters
| Parameter | Type | Description |
|---|
page_pattern required | string | URL pattern (e.g. "/", "/product*") |
zone_key required | string | Zone identifier |
display_name required | string | Human-readable name |
element_selector optional | string | CSS selector |
position optional | string | Position (before/after/replace) |
goal_id optional | string | Built for goal: id of an active goal of this site (from get_site_config) that this placement is meant to move. The Impact page and get_zone_exposure_report group placements by it. A goal of another site is refused with goal_not_found. It is a reporting label: it never changes what visitors see, makes no new placement version and is allowed during a test. Returns placement_goal_unavailable (503) on a database that does not have the column yet. |
display_rules optional | object | Lightbox-only display rules (DisplayRules shape — see lib/display-rules.ts). Sub-objects: trigger {type, delay_ms?, scroll_pct?, inactivity_ms?}, page_targeting {exclude[]}, audience {visitor_type, converted, device[], country[]}, schedule {days[], hours[], tz}, frequency {cap, n_days?, cooldown_seconds?}, suppression {after_dismiss_days?, after_convert_days?, mutual_exclusion?}. audience.country takes ISO 3166-1 alpha-2 codes ("GB", not "UK" — invalid codes are DROPPED, which turns the filter off rather than erroring, so read the saved rules back to confirm). schedule.days is 0=Sunday..6=Saturday, schedule.hours is [{start,end}] with end EXCLUSIVE and end<=start wrapping past midnight, and schedule.tz is either "visitor" (default — each visitor's own device clock, so 11-14 is everyone's lunchtime) or an IANA zone like "America/Chicago" (one real-world window everyone sees at the same instant). The API sanitizes — bad fields are dropped, not 400d. Ignored on non-lightbox zones. |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Delete a campaign permanently.
3 parameters
| Parameter | Type | Description |
|---|
campaign_id required | string | Campaign ID |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Remove a placement without deleting the reusable component. Cross-site super-admin callers must pass site_id from get_account_status; site-scoped callers stay on their own site.
5 parameters
| Parameter | Type | Description |
|---|
placement_id required | string | placement id |
expected_version required | number | Version from the latest read |
site_id optional | string | Required for cross-site super-admin sessions: exact target site id from get_account_status. Ignored by site-scoped sessions, which remain locked to their own site. |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Soft-delete a content variant. The variant is hidden immediately but recoverable via restore_content_variant within 30 days. A history snapshot is automatically created before deletion.
3 parameters
| Parameter | Type | Description |
|---|
variant_id required | string | Variant ID |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Soft-delete an offer. It vanishes from list_offers and stops being hydrated on the next config build, but the row survives so historical per-offer lift stays attributable. Its PLACEMENTS are deliberately not deleted: they keep their offer_id, hydrate to nothing, and are dropped from tag config, so the page shows no half-resolved offer rather than a stale code — fail closed. If a slot should now carry something else, remove or repoint the placement yourself with delete_content_variant.
3 parameters
| Parameter | Type | Description |
|---|
id required | string | Offer ID (from list_offers) |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Delete a page type configuration.
3 parameters
| Parameter | Type | Description |
|---|
config_id required | string | Config ID |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Permanently delete a trigger and its fire history.
3 parameters
| Parameter | Type | Description |
|---|
trigger_id required | string | Trigger ID |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Delete a site-owned trigger payload template.
3 parameters
| Parameter | Type | Description |
|---|
template_id required | string | Template ID |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Delete a zone and all its content variants.
3 parameters
| Parameter | Type | Description |
|---|
zone_id required | string | Zone ID |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Remove a component from a campaign's manifest. Clears the variant/trigger serving-path campaign_id only when it points at THIS campaign (this is also how a variant linked from the content editor is removed). Live content needs confirm_serving_change. 404 when the pair is not attached. Does not delete the referenced resource. Any change voids an approval.
6 parameters
| Parameter | Type | Description |
|---|
campaign_id required | string | Campaign ID |
kind required | "page" | "variant" | "trigger" | "offer" | "audience" | "experiment" | "provider_campaign" | Component kind |
ref_id required | string | The attached resource id |
confirm_serving_change optional | boolean | Required (true) when the variant is active or the trigger enabled: attaching puts live content under this campaign's window and audience (off the site if the campaign is not serving); detaching removes that gate so it serves to everyone. Without it the call returns 409 with details.reason = serving_change_requires_confirmation. Confirm with the operator first. |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Use AI to generate a content variant draft for a segment + zone. Returns suggested headline, body, and CTA.
5 parameters
| Parameter | Type | Description |
|---|
segment_id required | string | Target segment |
zone_key optional | string | Zone key (e.g. "hero") |
variant_type optional | "overlay" | "hero_swap" | "copy_swap" | Variant type |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Create a new PLANNING campaign from an existing one (usually a closed one). Copies the brief (as the copy's revision 1), audience eligibility, priority, owner, the goal (only if still active) and the name (with ' (copy)' unless you pass name), and re-references its pages, offers and audiences. Does NOT copy variants or triggers (each serves under one campaign at a time - duplicate those and attach the copies), experiments (tied to the run that measured them) or ad platform campaigns; each comes back in skipped with the reason. Dates are cleared and nothing serves until the copy is approved and launched. The source campaign is untouched.
4 parameters
| Parameter | Type | Description |
|---|
campaign_id required | string | Source campaign ID |
name optional | string | Name for the copy (default: source name + " (copy)") |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
End a layout experiment — IRREVERSIBLE: an ended experiment can NEVER be restarted (create a new one instead), every arm's variants are deactivated in the same call so visitors immediately see the original layout again, and the results window freezes at ended_at. The transition (with your reason and optional winner_arm_key) is appended to the experiment's history, and the workspace is notified (bell row + same-day email). winner_arm_key here only RECORDS the outcome — it does not keep that arm serving; to end AND keep the winning layout live for everyone, use ship_layout_winner instead. Check get_layout_experiment_results first and do not end a test that is still `collecting` unless the operator asked for it.
5 parameters
| Parameter | Type | Description |
|---|
experiment_id required | string | Layout experiment id (lexp_…), from list_layout_experiments |
winner_arm_key optional | string | Arm key to record as the winner (e.g. "B"). Annotation only — the winning layout stops serving; use ship_layout_winner to keep it live. |
reason optional | string | Why the test is being ended (recorded in history and stop_reason; max 80 chars, default "manual") |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
One campaign with its MANIFEST (#2198): every attached component (page, variant, trigger, offer, audience, experiment, provider_campaign) with `state` resolved from the referenced resource on this read - missing | draft | ready | live | stopped | failed - plus a `reason`, and `readiness` (ready, goal, required_total/required_satisfied, missing[], live[], stopped[], notes[]). `lifecycle` (planning -> ready -> approved; launched/paused/closed arrive with later phases) is the unit-of-work state and is SEPARATE from `status` (draft/active/ended), the serving gate driven by the flight window; readiness.notes says when the two disagree. Also returns the legacy `content` and `triggers` arrays (the FK-linked view).
1 parameter
| Parameter | Type | Description |
|---|
campaign_id required | string | Campaign ID |
Preflight for launch_campaign, with NO writes: whether the campaign can launch (or resume, if paused), the blockers, and per-component steps - which approved pages would be published, which variants would be published on a manual-publishing site, which paused experiments would restart, and what needs an operator (an approved-but-not-live offer: agents cannot set offers live) or is reference-only (ad platform campaigns). Call this and show the operator before launch_campaign.
1 parameter
| Parameter | Type | Description |
|---|
campaign_id required | string | Campaign ID |
Read a component test: status, version, history and `arms` in allocation order - arm A is the unchanged-page control, B the first treatment placement, C+ any additional treatment placements (each keeps its own placement id, pinned component revision and equal weight). Cross-site super-admin callers must pass site_id from get_account_status; site-scoped callers stay on their own site.
2 parameters
| Parameter | Type | Description |
|---|
experiment_id required | string | experiment id |
site_id optional | string | Required for cross-site super-admin sessions: exact target site id from get_account_status. Ignored by site-scoped sessions, which remain locked to their own site. |
Read one component placement, including its exact revision, customizations, anchors, targeting and concurrency version. Cross-site super-admin callers must pass site_id from get_account_status; site-scoped callers stay on their own site.
2 parameters
| Parameter | Type | Description |
|---|
placement_id required | string | placement id |
site_id optional | string | Required for cross-site super-admin sessions: exact target site id from get_account_status. Ignored by site-scoped sessions, which remain locked to their own site. |
Read one content test: audience, arms (variant per arm, effective weight, Original control if any), split, status, version and history.
1 parameter
| Parameter | Type | Description |
|---|
experiment_id required | string | Content experiment id (cxp_…) |
One layout experiment in full: status, hypothesis, traffic split, covered zones (page_pattern + element_selector per container), every arm (control "A" plus fragment arms, each with per-zone variants, fragment metadata and impressions), schedule (ends_at), auto_stop and CWV guardrail settings, stop_reason, winner_arm_key — and `history`: every status transition with its timestamp, from/to, reason (manual | scheduled | significance | guardrail:<metric>:<arm>) and actor (user | scheduler | guardrail | api), plus winner/shipped flags, so "why did this test stop?" is always answerable from this one call. For the per-arm conversion/lift numbers use get_layout_experiment_results. Read-only.
1 parameter
| Parameter | Type | Description |
|---|
experiment_id required | string | Layout experiment id (lexp_…), from list_layout_experiments |
RAW multi-armed bandit state: per-arm Thompson Sampling allocation weights, impressions, conversions and Beta posterior params (alpha/beta, expected_reward). READ THE GATES BEFORE COMPARING: every arm carries cvr_ci95 (95% Wilson interval on its observed rate) and `sufficient` (impressions at/above the scorecard's shared per-variant floor), and the response carries a top-level `warning` naming how many arms are below it. A 40-impression arm will regularly out-"score" a 4,000-impression arm by pure noise — never rank or declare winners across arms whose intervals overlap or whose sufficient flag is false, and never report expected_reward as a measured conversion rate (it is a posterior mean that includes the prior). These numbers refresh continuously: re-reading until a comparison looks decisive is peeking and inflates false positives. For the causal "is it working" verdict use get_scorecard.
no parameters
Get full trigger configuration: events, dormancy, identifier type, destinations, payload templates.
1 parameter
| Parameter | Type | Description |
|---|
trigger_id required | string | Trigger ID |
Get full details of a trigger payload template.
1 parameter
| Parameter | Type | Description |
|---|
template_id required | string | Template ID |
Get personalization zones. Pass zone_id to fetch a single zone (recommended when working on a specific zone — full response is 200KB+). Without zone_id, returns all zones for the site. Every zone carries `lifecycle`: `state` is whether it serves right now — live, test_arm (a serving arm of a running content, layout or component test; `experiment` names it, and `also_live_outside_test` says it serves plain content too), paused (everything in it is switched off or ended, or the zone itself is switched off while it holds published content) or draft (empty, nothing published yet, or not approved with nothing published) — plus a plain `summary`. Read the state from this field, never from the zone name: names like "DRAFT ·" or "LIVE ·" are free text and go stale. null means the state could not be read.
1 parameter
| Parameter | Type | Description |
|---|
zone_id optional | string | If provided, return only this zone (much smaller response — use this when repairing a specific zone's field_schema) |
Install a lifecycle recipe as a trigger on this site. AXO builds the lifecycle event and shapes it for each destination; no payload template is needed. The trigger is created switched off unless enabled is true. Marketing Cloud Engagement destinations need mapping.event_definition_key unless the integration already has one.
8 parameters
| Parameter | Type | Description |
|---|
recipe_id required | string | Recipe id from list_lifecycle_recipes, e.g. abandoned_cart |
destinations required | object[] | Where to deliver the event |
settings optional | object | Recipe settings; omitted settings take the recipe defaults |
name optional | string | Trigger name (default: the recipe name) |
enabled optional | boolean | Switch the trigger on now (default false) |
allow_duplicate optional | boolean | Install again on an integration that already has this recipe (default false: refused with 409) |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Launch an APPROVED campaign (or resume a PAUSED one) as a durable job. Turns visitors-facing content ON: publishes approved pages, publishes live variants on manual-publishing sites, restarts experiments a pause stopped, then sets the campaign's serving gate active so linked variants and triggers serve inside the flight window. Refused (409 with details.plan) unless approved/paused and the manifest is ready. When approval is required, an unapproved campaign cannot launch (approval_required); submit it via request_review first. Idempotent and deduped per campaign: a retry or a second agent gets the same job, and completed steps are skipped. Returns the job – if status is queued/running, poll get_job. Never sets offers live and never enables ad platform campaigns (reported as needs_operator / reference_only). Confirm with the operator first; call get_campaign_launch_plan to show what will happen.
4 parameters
| Parameter | Type | Description |
|---|
campaign_id required | string | Campaign ID |
actor optional | string | Who is launching (recorded on the job and audit trail) |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
List pending ad-theme suggestions for the current site before approving or rejecting them.
no parameters
List all campaigns for the site with status and briefs. To page through a long list, pass `limit`: the response then carries `next_cursor` — pass it back as `cursor` to continue, until it is null. Cursored pages are ordered newest-created first (not active-first).
2 parameters
| Parameter | Type | Description |
|---|
limit optional | number | Page size (max 200). Passing this switches the response to paginated mode with `next_cursor`. |
cursor optional | string | Opaque pagination cursor. To fetch the next page, pass the `next_cursor` value returned by the previous call verbatim; omit for the first page. The response's `next_cursor` is null when there are no more rows. Never construct or modify a cursor yourself. |
List controlled component tests and lifecycle state. Cross-site super-admin callers must pass site_id from get_account_status; site-scoped callers stay on their own site.
2 parameters
| Parameter | Type | Description |
|---|
placement_id optional | string | placement id |
site_id optional | string | Required for cross-site super-admin sessions: exact target site id from get_account_status. Ignored by site-scoped sessions, which remain locked to their own site. |
Read previous full placement bindings, revisions, audiences and schedules for rollback. Cross-site super-admin callers must pass site_id from get_account_status; site-scoped callers stay on their own site.
2 parameters
| Parameter | Type | Description |
|---|
placement_id required | string | placement id |
site_id optional | string | Required for cross-site super-admin sessions: exact target site id from get_account_status. Ignored by site-scoped sessions, which remain locked to their own site. |
List component placements with anchors, pinned revision, audience, active state and concurrency version. Cross-site super-admin callers must pass site_id from get_account_status; site-scoped callers stay on their own site.
2 parameters
| Parameter | Type | Description |
|---|
component_id optional | string | component id |
site_id optional | string | Required for cross-site super-admin sessions: exact target site id from get_account_status. Ignored by site-scoped sessions, which remain locked to their own site. |
List fixed-split content tests (A/B/n of ordinary hero/copy/offer variants) and their lifecycle state. Optional zone_id / status filters.
2 parameters
| Parameter | Type | Description |
|---|
zone_id optional | string | Restrict to one zone id |
status optional | "draft" | "running" | "paused" | "ended" | Restrict to one status |
List the published revisions of a content variant, newest first, plus which one is currently published. A revision is a publish act (what visitors saw); get_content_history is the per-save audit trail of the working copy. Cross-site super-admin callers must pass site_id from get_account_status; site-scoped callers stay on their own site.
3 parameters
| Parameter | Type | Description |
|---|
variant_id required | string | Variant ID |
limit optional | number | Max revisions to return (default 20, max 100) |
site_id optional | string | Required for cross-site super-admin sessions: exact target site id from get_account_status. Ignored by site-scoped sessions, which remain locked to their own site. |
List the site's layout experiments — page-level A/B tests of whole containers (header, hero, grid, footer), each testing the original layout (control arm "A") against one or more alternative-layout fragment arms. Returns per experiment: id, name, status (draft | running | paused | ended), page_type, covered zones, arms with allocation weight and impressions, schedule (ends_at), auto_stop and Core Web Vitals guardrail settings, stop_reason and winner_arm_key. Pass page_type to scope to one page type. Pass include_results: true to attach each non-draft experiment's per-arm real-exposure results inline (same readout as get_layout_experiment_results; draft experiments get results: null) — the Scorecard's "Layout tests" view in one call. Read-only.
2 parameters
| Parameter | Type | Description |
|---|
page_type optional | string | Scope to one page type (e.g. home, pdp, plp). Omit for all experiments. |
include_results optional | boolean | Attach per-arm results inline for every non-draft experiment (heavier; omit when only the list/status is needed) |
List the ready-made lifecycle recipes (abandoned cart, abandoned browse, abandoned checkout, high-intent return, lapsed visitor). Each entry gives the event it watches, the settings a site may change with their bounds, and the integration types it can deliver to (klaviyo, braze, sfmc, webhook, custom).
no parameters
List the canned lightbox display-rule presets (Welcome offer, Exit intent newsletter, Cart recovery, Promo bar, Returning visitor offer). Each preset returns a complete DisplayRules object that can be passed verbatim as create_zone.display_rules or update_zone.display_rules. Use this instead of authoring the rules JSON from scratch unless you need a custom combination.
no parameters
List this site's offer library plus the guardrail dials every offer write is validated against. Returns each non-deleted offer (name, status, offer_type, value_bp / value_cents, code, validity window, stacking, approved, code_verified_at), `site_dials` (max_discount_pct — the hard depth ceiling; gross_margin_pct — null when the operator has not configured one), and a per-offer `break_even` hint: the relative conversion lift the discount must produce just to pay for itself (d / (m - d)), null when no margin rate is set. Call this before authoring or placing anything — it is how you tell a ratified, servable offer (status "live" AND approved AND code_verified_at) from a draft that will render nothing. AXO is a SHADOW promo layer: these rows REFERENCE a discount code the merchant's own platform already honors; we never mint one and never touch redemption accounting.
no parameters
List page type configurations (product, category, blog).
no parameters
List this site's client review links (newest first) with status (active, expired, revoked), audience, view, page, expiry and whether they have been opened. Pass zone_id to narrow to one zone.
1 parameter
| Parameter | Type | Description |
|---|
zone_id optional | string | Optional zone id filter |
List approval requests for the current site across workflow states.
1 parameter
| Parameter | Type | Description |
|---|
state optional | "needs_me" | "in_review" | "changes_requested" | "approved" | "drafts" | "live" | "all" | Workflow state filter. Defaults to all. |
Get the audit log of fire attempts for a trigger: successes, errors, skipped fires with skip_reason. Paginated: the response carries `next_cursor` — pass it back as `cursor` to continue, until it is null.
3 parameters
| Parameter | Type | Description |
|---|
trigger_id required | string | Trigger ID |
limit optional | number | Max rows (default 100, max 500) |
cursor optional | string | Opaque pagination cursor. To fetch the next page, pass the `next_cursor` value returned by the previous call verbatim; omit for the first page. The response's `next_cursor` is null when there are no more rows. Never construct or modify a cursor yourself. |
List available payload templates: system seeds and site-owned custom templates.
no parameters
List all triggered messages for the site with watch event, mode, destinations, and enabled status.
no parameters
Pause a LAUNCHED campaign as a durable job. Immediately stops every variant and trigger linked to the campaign (serving gate off) and pauses its running experiments (never ends them). Does NOT retire published pages and does NOT pause ad platform campaigns - both come back as needs_operator so you can tell the operator exactly what is still running. Reversible with launch_campaign. Idempotent: pausing a paused campaign runs again to finish anything an interrupted pause left running, and job.result.outcome is pause_completed (it paused something) or already_paused (nothing left).
4 parameters
| Parameter | Type | Description |
|---|
campaign_id required | string | Campaign ID |
actor optional | string | Who is pausing (recorded on the job and audit trail) |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Pause a component placement; insertion is removed or original content restored on the next config reconciliation. Cross-site super-admin callers must pass site_id from get_account_status; site-scoped callers stay on their own site.
5 parameters
| Parameter | Type | Description |
|---|
placement_id required | string | placement id |
expected_version required | number | Version from the latest read; conflicts return 409 |
site_id optional | string | Required for cross-site super-admin sessions: exact target site id from get_account_status. Ignored by site-scoped sessions, which remain locked to their own site. |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Deploy an offer into a zone: creates a type="offer" content variant bound to a zone + audience. Target ONE segment via `segment_id`, OR set `all_visitors: true` to show it to EVERYONE regardless of segment (provide exactly one). The placement stores ONLY the offer_id plus presentation overrides — the economics (value, code, window, terms) are joined in from the offer row on every config build, which is what makes an offer ending at midnight go dark everywhere instead of leaving a stale code on the page. The renderer writes into the anchor zone's element, so pick a zone whose contents the offer should own (create_zone first if none exists). Two DIFFERENT offers cannot compete in one zone + audience and the write is rejected if you try: the optimizer ranks on conversion rate, so given a choice of depths it always crowns the deepest one and reports the lost margin as a win — competing arms must share one offer and vary only presentation. Placing an unapproved or non-live offer succeeds but serves nothing until a human ratifies it in the dashboard; check status/approved via list_offers first.
7 parameters
| Parameter | Type | Description |
|---|
offer_id required | string | Offer to serve (from list_offers). Must belong to this site and not be deleted. |
zone_id required | string | Zone whose element the offer renders into |
segment_id optional | string | Audience segment to show it to. Omit when all_visitors is true. |
all_visitors optional | boolean | Show the offer to ALL visitors regardless of segment. When true, omit segment_id. |
presentation optional | object | Per-placement presentation overrides — { headline, body, cta, cta_href, show_code, show_expiry }. These win over the offer's own presentation defaults. Never put economics here: value and code come from the offer row. |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Compile an isolated component preview, optionally with placement-specific field values. Returns HTML and hash without saving or publishing; use the Content page picker for host-page anchor validation. Cross-site super-admin callers must pass site_id from get_account_status; site-scoped callers stay on their own site.
4 parameters
| Parameter | Type | Description |
|---|
field_overrides optional | object | Optional exposed field values for this preview |
component_id required | string | component id |
revision_id required | string | revision id |
site_id optional | string | Required for cross-site super-admin sessions: exact target site id from get_account_status. Ignored by site-scoped sessions, which remain locked to their own site. |
PUBLISH the working copy of one or more content variants so visitors see it: snapshots each into an immutable revision and moves its published pointer. All ids must be live variants of this site or nothing is published. On an auto-publishing site (the default) visitors already see the working copy, so this only records a restore point. Read GET /api/content first: has_unpublished_changes tells you which variants have pending edits on a manual site. When content approval is required, publishing unapproved changes returns approval_required; call request_review first to submit for approval.
3 parameters
| Parameter | Type | Description |
|---|
variant_ids required | string[] | Variant ids to publish together (max 200). |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Reject a pending ad-theme suggestion for this site.
3 parameters
| Parameter | Type | Description |
|---|
suggestion_id required | string | |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Update only the listed placements to an approved revision. Returns individual success/conflict results; never assume a partial release was atomic. Cross-site super-admin callers must pass site_id from get_account_status; site-scoped callers stay on their own site.
6 parameters
| Parameter | Type | Description |
|---|
component_id required | string | component id |
revision_id required | string | revision id |
placements required | object[] | Array of {id,expected_version} for exactly the placements to update |
site_id optional | string | Required for cross-site super-admin sessions: exact target site id from get_account_status. Ignored by site-scoped sessions, which remain locked to their own site. |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Change only a placement's name, everywhere it is shown, without saving a new version or re-publishing. Content, targeting, activation and test assignment stay as they are, so it works on a live placement and on an arm of a running component test. Read expected_version first; a mismatch returns 409. Cross-site super-admin callers must pass site_id from get_account_status; site-scoped callers stay on their own site.
6 parameters
| Parameter | Type | Description |
|---|
placement_id required | string | placement id |
display_name required | string | New placement name, up to 200 characters |
expected_version required | number | Version from the latest read; conflicts return 409 |
site_id optional | string | Required for cross-site super-admin sessions: exact target site id from get_account_status. Ignored by site-scoped sessions, which remain locked to their own site. |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Submit one or more items (variants, placements, pages, campaigns) for human review and approval. When approval is required by workspace policy, changes cannot go live directly and must be submitted through this tool first. Approvers are notified to review in the dashboard or via connected channels.
5 parameters
| Parameter | Type | Description |
|---|
items required | object[] | List of 1 to 20 items to submit for approval together. |
title optional | string | Optional title for the review request. |
note optional | string | Optional note explaining the changes for approvers. |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Restore a previous full placement binding as a new private draft. Preview and explicitly publish to change delivery. Cross-site super-admin callers must pass site_id from get_account_status; site-scoped callers stay on their own site.
6 parameters
| Parameter | Type | Description |
|---|
placement_id required | string | placement id |
version required | number | version |
expected_version required | number | expected version |
site_id optional | string | Required for cross-site super-admin sessions: exact target site id from get_account_status. Ignored by site-scoped sessions, which remain locked to their own site. |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Restore a content variant. Two modes: (1) pass only variant_id to un-delete a soft-deleted variant; (2) also pass version to roll back the payload to a specific historical version (use get_content_history to find version numbers). Restoring to a version is itself snapshotted, so you can always roll forward again.
4 parameters
| Parameter | Type | Description |
|---|
variant_id required | string | Variant ID to restore |
version optional | integer | History version to restore payload to. Omit to only un-delete. |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Copy a published revision back into the variant's WORKING COPY. The current state is snapshotted into the variant's history first. On an auto-publishing site the working copy is what visitors see, so it takes effect at once; on a manual site it becomes pending edits to preview and then publish. Component placements and routed variants are refused: restore those with restore_content_variant, which re-validates them.
4 parameters
| Parameter | Type | Description |
|---|
variant_id required | string | Variant ID |
revision_id required | string | Revision id from list_content_variant_revisions |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Turn a client review link off immediately. The row is kept for the audit trail; anyone opening the link sees that it was turned off. Use list_preview_share_links to find codes.
3 parameters
| Parameter | Type | Description |
|---|
code required | string | The link code (the last path segment of its URL) |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Stage a campaign: planning -> ready -> approved (and back). `ready` and `approved` are REFUSED (409, with `details.readiness`) until the manifest is ready: an active goal, at least one required component, every required component ready/live. `approved` pins approved_revision to the latest brief version; a later brief edit voids it (the campaign drops back to ready). launched / paused / closed are refused here - use launch_campaign / pause_campaign / close_campaign. Never writes `status` (the serving gate).
5 parameters
| Parameter | Type | Description |
|---|
campaign_id required | string | Campaign ID |
lifecycle required | "planning" | "ready" | "approved" | Target stage |
actor optional | string | Who is approving (recorded as approved_by when lifecycle=approved) |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
End a layout experiment AND ship the winning layout: the winning fragment arm's variants STAY ACTIVE and serve to 100% of visitors through the ordinary variant path (the always-on holdout keeps measuring them), while every other arm's variants — the control included — are retired. IRREVERSIBLE as a test: the experiment is ended, can never be restarted, and its results freeze at ended_at; the ship is recorded in history (shipped: true) and the workspace is notified. winner_arm_key must name one of the test's FRAGMENT arms — shipping the control is meaningless (that is just end_layout_experiment: naming the control here ends the test WITHOUT shipping anything). Before shipping, read get_layout_experiment_results: do not ship while `collecting` is true, while a guardrail breach stands against the winner, or when the winner is not significant, unless the operator explicitly accepts that.
5 parameters
| Parameter | Type | Description |
|---|
experiment_id required | string | Layout experiment id (lexp_…), from list_layout_experiments |
winner_arm_key required | string | Fragment arm to ship (e.g. "B"). Must be one of the experiment's fragment arms. |
reason optional | string | Why the winner is being shipped (recorded in history and stop_reason; max 80 chars, default "manual") |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Return the segment-aware donation ask ladder for a donor — the amounts a fundraising form should show first, plus the recurrence default + rationale. Pass `segment_suffix` for the default ladder per segment (e.g. "donor_ready", "high_capacity_uncontacted", "lapsed_quarterly"), OR pass `profile_id` to personalise off the donor's CRM-fed attributes (last_gift_amount_cents / recurring_amount_cents / lifetime_giving_cents / capacity_score). When `profile_id` is given without `segment_suffix`, the profile's current segment is used. Returns { ladder: { amounts_cents, recurrence, rationale, highlight_index?, highlight_label? }, resolved }. Amounts are in CENTS. Use before authoring a copy_swap variant that writes the amounts onto a donation form, or when the agent needs to suggest "what should we ask for" from the donor context.
6 parameters
| Parameter | Type | Description |
|---|
segment_suffix optional | string | verticals.ts segment suffix (e.g. donor_ready, high_capacity_uncontacted, lapsed_quarterly). |
profile_id optional | string | Profile to personalise off — last gift, recurring amount, capacity. CRM attributes pulled from profiles.attributes. |
last_gift_amount_cents optional | integer | Override (cents). Useful when profile data is stale or unavailable. |
recurring_amount_cents optional | integer | Override (cents). For recurring_card_declined the ladder surfaces ONLY this amount. |
lifetime_giving_cents optional | integer | Override (cents). Elevates the high-capacity ladder when ≥ $10k. |
capacity_score optional | number | Override (0..1). Elevates the high-capacity ladder when ≥ 0.9. |
Read-only. Suggested "Built for goal" values for this site's placements (content zones and component placements) that have no goal set. Rules: an email or lead-form placement, or a sign-up call to action (zone key or name says signup, email, newsletter or enews, or the zone holds a lead form), maps to the site's matching form, email or newsletter goal; on an affiliate site, a placement whose live content shows product picks, a comparison or a product list (a product recommendation, a list of two or more products or links, or a picks or comparison name), or holds affiliate links or two or more links to other sites, maps to the affiliate click goal; headline, hero and copy zones never qualify on their name or the site vertical; anything else gets no suggestion. Only live placements are considered: drafts, paused and unapproved zones get none. Returns { suggestions: [{ zone_id, placement_id, kind ("zone" | "component_placement"), name, page_pattern, goal {id, name, kind}, rule ("signup" | "affiliate"), reason }], goals, affiliate_site, can_accept }. Nothing is written: show the suggestions to the owner and, only after they agree, accept each with update_zone {zone_id, goal_id} (that works for component placement zones too). can_accept false means goals cannot be saved on this database yet.
no parameters
Fire a trigger against a test target, bypassing cooldown/rate limits. Goes through the real dispatch pipeline — WILL send real email/SMS. A lifecycle trigger (installed from a recipe) takes only identifier {type: email, phone or external_id, value} and is a dry run that returns the exact payload for each destination; pass dry_run: false to send it. Test fires stay out of lift.
7 parameters
| Parameter | Type | Description |
|---|
trigger_id required | string | Trigger ID |
profile_id optional | string | Profile ID |
identifier optional | object | Test target identifier |
event_properties optional | object | Override event properties |
dry_run optional | boolean | Lifecycle triggers only. Default true: return the payloads and send nothing. false sends to the test identifier. |
integration_id optional | string | Lifecycle triggers only: test one destination of the trigger |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Update a campaign name, brief, status, goal or owner. A brief edit on an APPROVED campaign voids the approval (lifecycle drops to ready; response carries approval_cleared:true). status can only be changed while the campaign is planning or ready; from approved on it is controlled by launch_campaign / pause_campaign (409 otherwise).
12 parameters
| Parameter | Type | Description |
|---|
campaign_id required | string | Campaign ID |
name optional | string | |
brief optional | object | |
status optional | "active" | "draft" | "paused" | "archived" | |
goal_id optional | string | null | Primary goal: a site_goals.id (see get_site_config goals). Must be an ACTIVE goal of this site; null clears it. Readiness requires one. |
owner_user_id optional | string | null | Owner (a user id or name) responsible for the campaign; null clears it. |
starts_at optional | string | null | |
ends_at optional | string | null | |
eligibility optional | object | null | |
priority optional | number | |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Start, pause or end a controlled component test, or add a treatment to a DRAFT one. ship=A keeps the unchanged page; ship=<treatment key> (B, C, ...) releases that treatment to everyone eligible and hides the others; no ship restores each placement's pre-test state. action=add_treatment with placement_id attaches the next arm (same page, anchor, audience and schedule as the first treatment) and is refused once the test has started: adding an arm would re-slice the equal split under visitors already assigned, so end the running test and start a fresh one instead. Changes live delivery. Alternatively, omit action and send ends_at (UTC ISO instant or null) and/or auto_stop alone to configure scheduling. Statistical auto-stop and automatic ship settings are recorded but withheld pending evidence qualification. Cross-site super-admin callers must pass site_id from get_account_status; site-scoped callers stay on their own site.
10 parameters
| Parameter | Type | Description |
|---|
experiment_id required | string | experiment id |
action optional | "start" | "pause" | "end" | "add_treatment" | action; omit to configure scheduling |
expected_version required | number | expected version |
ship optional | string | Arm key to ship on end: A (unchanged page) or a treatment key such as B or C |
placement_id optional | string | For add_treatment: the placement to attach as the next treatment arm |
ends_at optional | string | null | UTC ISO deadline; null removes it |
auto_stop optional | object | |
site_id optional | string | Required for cross-site super-admin sessions: exact target site id from get_account_status. Ignored by site-scoped sessions, which remain locked to their own site. |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Save a private draft of placement anchors, targeting, schedule or component revision. Visitors retain the published placement. Read expected_version first; publish explicitly after review. goal_id alone sets the placement's built-for goal without a new version or review. Cross-site super-admin callers must pass site_id from get_account_status; site-scoped callers stay on their own site.
21 parameters
| Parameter | Type | Description |
|---|
field_overrides optional | object | Only exposed revision field keys; placement-specific text/image/link values. Empty object clears customizations. |
placement_id required | string | placement id |
expected_version required | number | Version from the latest read; conflicts return 409 |
component_revision_id optional | string | component revision id |
position optional | "before" | "after" | "between" | "inside_start" | "inside_end" | "replace" | position |
element_selector optional | string | element selector |
second_anchor_selector optional | string | second anchor selector |
anchor_policy optional | "required" | "when_present" | required reports a missing anchor. when_present waits for a conditional primary anchor without reporting absence as an error; invalid or ambiguous anchors still fail. Omit to preserve. |
page_pattern optional | string | page pattern |
name optional | string | name |
page_type optional | string | page type |
order optional | number | order |
priority optional | number | priority |
eligibility optional | object | eligibility |
segment_id optional | string | segment id |
starts_at optional | string | ISO timestamp, or empty string to remove start |
ends_at optional | string | ends at |
goal_id optional | string | null | Built for goal: id of an active goal of this site (from get_site_config) that this placement is meant to move. The Impact page and get_zone_exposure_report group placements by it. A goal of another site is refused with goal_not_found. It is a reporting label: it never changes what visitors see, makes no new placement version and is allowed during a test. Pass null (or an empty string) to clear it; omit to leave it unchanged. Sent alone (with expected_version), it is saved without a new placement version. Returns placement_goal_unavailable (503) on a database that does not have the column yet. |
site_id optional | string | Required for cross-site super-admin sessions: exact target site id from get_account_status. Ignored by site-scoped sessions, which remain locked to their own site. |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Start, pause or end a content test (action), or change its name/hypothesis/split (no action). Ending with ship=<armKey> keeps that arm live and turns the others off (ship=A with an Original arm restores the page); ending without ship restores each variant's pre-test state. Changing the split on a RUNNING test re-assigns some visitors and restarts the measured window. Requires expected_version (409 on conflict). Changes live delivery. When content approval is required, starting a test with unapproved arm content returns approval_required; call request_review first. Alternatively, omit action and send ends_at (UTC ISO instant or null) and/or auto_stop alone to configure scheduling. Statistical auto-stop and automatic ship settings are recorded but withheld pending evidence qualification.
12 parameters
| Parameter | Type | Description |
|---|
experiment_id required | string | Content experiment id (cxp_…) |
action optional | "start" | "pause" | "end" | Lifecycle transition; omit to update settings only |
expected_version required | integer | The version you read (optimistic lock) |
ship optional | string | With action=end: arm key to keep live |
reason optional | string | With action=end: why |
name optional | string | |
hypothesis optional | string | |
ends_at optional | string | null | UTC ISO deadline; null removes it |
auto_stop optional | object | |
split optional | object | null | New {armKey: weight}; null for equal |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Update a content variant payload or active status. A history snapshot of the previous state is automatically saved before the update, so changes are always reversible via restore_content_variant. When replacing a copy_swap/hero_swap payload, read-modify-write against the zone's field_schema keys — a re-keyed payload sharing NO renderable key with the zone is refused with a 400 naming the accepted keys.
12 parameters
| Parameter | Type | Description |
|---|
variant_id required | string | Variant ID |
payload optional | object | Updated payload |
active optional | boolean | Enable/disable |
type optional | "overlay" | "hero_swap" | "copy_swap" | "product_reco" | "move_object" | |
eligibility optional | object | |
priority optional | number | |
segment_id optional | string | |
campaign_id optional | string | null | |
destination_page_id optional | string | null | Re-point the route at another page, or null to clear it (strips the vt_route attribution param). On a routed variant the CTA URL stays server-derived; activating re-validates the destination is published. |
ends_at optional | string | null | Scheduled expiry (ISO 8601, at least 5 minutes out, within a year); null clears it. The hourly watchdog sweep deactivates the variant once this passes. active: true is also the manual re-enable after a watchdog auto-disable — it clears the disable stamp and restarts the CVR measurement window. |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Update an offer's terms, or move it between draft / paused / archived. `status` accepts ONLY those three. "live" is a dashboard-only transition gated on human approval plus code verification, and it is refused outright on the API-key path that every agent surface authenticates with — so you CAN pause or archive an offer that is misbehaving, and you CANNOT start one. Ask the operator to approve it in the dashboard instead. Editing the economics (offer_type, value_bp, value_cents, currency, tiers, gift_sku, code) UN-RATIFIES the offer and it stops serving until a human re-approves: approval attaches to specific terms, not to a row id, so a 10%-off offer approved yesterday can never silently become 40% off today — the response reports `approval_reset`. Changing `code` also clears the code verification. Same units and guardrails as create_offer (cents, basis points, the site depth ceiling, the margin floor). OMITTING a field leaves it untouched; sending it as NULL REMOVES it, which is how you make a promo open-ended (ends_at: null = runs indefinitely) or drop a threshold, a cap or a link. Only starts_at, ends_at, min_order_cents, max_discount_cents, max_exposures_per_visitor, code, redeem_url and terms_url accept null — null on anything else is rejected rather than ignored, so a mistaken null never silently no-ops. The response echoes what you removed as `cleared`.
23 parameters
| Parameter | Type | Description |
|---|
expected_revision optional | string | Revision from the latest read; on conflict reload and reconsider, never drop the guard |
id required | string | Offer ID (from list_offers) |
status optional | "draft" | "paused" | "archived" | draft | paused | archived only. "live" is dashboard-only and is rejected on this path — no agent tool can make an offer servable. |
name optional | string | New internal name (max 200 chars) |
offer_type optional | "percent" | "fixed" | "free_shipping" | "gift" | "tiered" | Changing this un-ratifies the offer. |
value_bp optional | integer | Percent discount in BASIS POINTS, 0-10000 (2500 = 25.00%). Changing it un-ratifies the offer. |
value_cents optional | integer | Fixed discount in CENTS. Changing it un-ratifies the offer. |
currency optional | string | 3-letter ISO-4217 code. Changing it un-ratifies the offer. |
code optional | string | null | Discount code as it exists in the merchant's platform. Changing it un-ratifies the offer AND clears code_verified_at, so a human must re-verify it. null removes the code — do this only for an offer that needs none (an automatic discount, a free-shipping threshold), because a code-less offer CANNOT be verified and so cannot go live again until a code is set. |
min_order_cents optional | integer | null | MIRRORED TERM (cents) — fine print only; their platform enforces it. null removes the minimum-spend threshold. |
max_discount_cents optional | integer | null | MIRRORED TERM (cents) — fine print only; their platform enforces it. null removes the cap. |
max_exposures_per_visitor optional | integer | null | How many times WE show it to one visitor — the only cap AXO enforces. null uncaps it. |
starts_at optional | string | null | ISO-8601 start of the validity window. null removes the start date, so it is valid from now. |
ends_at optional | string | null | ISO-8601 end of the validity window; must be after starts_at. null removes the end date, so the offer runs INDEFINITELY until someone pauses it — the only way to express an open-ended promo. |
stacking optional | "exclusive" | "stackable" | "group" | MIRRORED TERM rendered as fine print. |
tiers optional | object[] | Tier ladder for offer_type=tiered (max 10). Changing it un-ratifies the offer. |
gift_sku optional | string | Gift SKU for offer_type=gift. Changing it un-ratifies the offer. |
eligibility optional | object | SegmentPredicate gating who the offer is valid for. |
redeem_url optional | string | null | Where the offer CTA sends the visitor. null removes it. |
terms_url optional | string | null | Full terms page. null removes it. |
presentation optional | object | Default presentation inherited by placements: { headline, body, cta, cta_href, show_code, show_expiry }. |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Update a page type configuration.
6 parameters
| Parameter | Type | Description |
|---|
expected_revision optional | string | Revision from the latest read; on conflict reload and reconsider, never drop the guard |
config_id required | string | Config ID |
url_pattern optional | string | Updated URL pattern |
selectors optional | object | Updated selectors |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Update an existing trigger. Pass only the fields to change.
20 parameters
| Parameter | Type | Description |
|---|
expected_revision optional | string | Revision from the latest read; on conflict reload and reconsider, never drop the guard |
trigger_id required | string | Trigger ID |
name optional | string | |
description optional | string | |
enabled optional | boolean | |
mode optional | "immediate" | "dormancy" | |
watch_event optional | string | |
cancel_event optional | string | |
criteria optional | object | |
delay_ms optional | number | |
window_ms optional | number | |
identifier_type optional | string | |
destinations optional | object[] | |
cooldown_per_profile_ms optional | number | |
global_rate_limit_per_min optional | number | |
optimization_mode optional | "axo_bandit" | "external" | Optimization mode |
send_window optional | object | null | Per-trigger send window. null inherits the site setting; {"enabled": false} sends at any hour (for safety triggers); {"enabled": true, "start_hour": 9, "end_hour": 20} sets this trigger's own local hours. An enabled window needs the site trigger_timezone, and its start and end (with missing hours taken from the site) must differ. Needs migration 354. |
frequency_cap_exempt optional | boolean | When true this trigger ignores the site's per-person cap and its fires do not count toward it. For safety triggers such as a declined card. Default false. |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Update a site-owned trigger payload template.
9 parameters
| Parameter | Type | Description |
|---|
expected_revision optional | string | Copy revision from the latest resource read. On conflict reload and reconsider; never drop the guard to force the edit. |
template_id required | string | Template ID |
name optional | string | |
description optional | string | |
format optional | "json" | "html" | "form" | |
body optional | string | |
example_destination optional | string | |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |
Update an existing zone (selector, name, priority, approval, built-for goal, display_rules, or field schema). To add a missing field (e.g. image_url): call get_zones(zone_id) first to read the existing field_schema, then pass the full updated array with the new entry appended.
11 parameters
| Parameter | Type | Description |
|---|
expected_revision optional | string | Copy revision from the latest resource read. A stale revision returns conflict; reload and reconsider the edit, never remove the guard to force it. |
zone_id required | string | Zone ID |
display_name optional | string | |
element_selector optional | string | |
approved optional | boolean | |
priority optional | number | |
goal_id optional | string | null | Built for goal: id of an active goal of this site (from get_site_config) that this placement is meant to move. The Impact page and get_zone_exposure_report group placements by it. A goal of another site is refused with goal_not_found. It is a reporting label: it never changes what visitors see, makes no new placement version and is allowed during a test. Pass null (or an empty string) to clear it; omit to leave it unchanged. Alone it is saved without expected_revision and also works on a component placement zone. Returns placement_goal_unavailable (503) on a database that does not have the column yet. |
display_rules optional | object | Lightbox display rules — same shape as create_zone.display_rules (incl. audience.country ISO 3166-1 alpha-2 and schedule {days, hours, tz}). Send the full object to overwrite; omit to leave unchanged. Sanitized at the API — invalid country codes and unresolvable timezones are dropped silently, so read the zone back if the targeting matters. |
field_schema optional | object[] | Full replacement field schema — pass the complete array including existing entries you want to keep. Read the current schema first with get_zones(zone_id). |
dry_run optional | boolean | Preview only: returns the request this tool would send without sending it. Server-side validation is not exercised. |
idempotency_key optional | string | Retry-safe key (8–200 chars). Repeating a call with the same key returns the first result instead of running again. |