---
title: "Perform experience action"
method: POST
path: "/v25-10-beta/experiences/{experienceId}/actions/{action}"
tags: ["Perform Experience Action"]
---

# Perform experience action

`POST /v25-10-beta/experiences/{experienceId}/actions/{action}`

## Request

- Base URL: `https://api.intelligems.io`
- URL: `https://api.intelligems.io/v25-10-beta/experiences/{experienceId}/actions/{action}`
- Auth: API key in header `intelligems-access-token`
- TypeScript: <https://skmtc.dev/intelligems/apis/intelligems-external-api-v25-10-beta/docs/v25-10-beta/experiences/:experienceId/actions/:action/post.ts> (a function with typed inputs; its response is checked against the schema)

Performs an action on an experience to control its lifecycle.

### Supported Actions

- `start` - Activate the experience and begin serving it to visitors
- `pause` - Temporarily stop serving the experience (can be resumed with start)
- `end` - Permanently end the experience

### Important Notes

- The experience must exist and belong to your organization
- Starting an experience sets it live and removes preview mode
- Pausing or ending an experience returns it to preview mode
- Only certain state transitions are valid (e.g., cannot pause an already ended experience)

### Request Body Fields

- `variationId` (string UUID, optional) — The ID of the variation to apply. When ending an experience, this selects the winning variation.

### Usage Examples

**Start an experience** (no body fields needed):

```
POST /v25-10-beta/experiences/{experienceId}/actions/start
Body: {}
```

**Pause an experience** (no body fields needed for content tests):

```
POST /v25-10-beta/experiences/{experienceId}/actions/pause
Body: {}
```

**End an experience** with a winning variation:

```
POST /v25-10-beta/experiences/{experienceId}/actions/end
Body: { "variationId": "<uuid>", "updatePricesToVariation": true }
```

**Rate Limit:** 50 requests per 30s window, refilling 25 tokens every 30s.

## Path parameters

- `experienceId` string, uuid, required
- `action` 'start' | 'pause' | 'end', required

## Request body

- object
  - `variationId` string, uuid, nullable
  - `updatePricesToVariation` boolean

## Response `200`

OK

- object
  - `experience` object, nullable, required: Full single-experience payload returned by GET /experiences/{experienceId}. Includes `experienceCustomMetrics`, `experienceIntegrations`, `experienceKeyMetrics`, and `shippingTestMethodDefinitions`. Unlike GET /experiences-list items, this response does not include `history`.
    - `id` string, uuid, required: Server-generated. Read-only.
    - `name` string, required: Display name shown in dashboards and reports.
    - `isPreview` boolean, required: True while in draft mode. Must be set to false before the experience can be started.
    - `description` string, nullable: Internal note explaining what this experience tests.
    - `devicePreview` object, nullable: Device and path configuration for previewing the experience.
      - `device` 'any' | 'mobile' | 'desktop', required: Viewport to simulate when rendering the preview.
      - `path` string, required: Storefront URL path to load in the preview (e.g., '/products/example').
    - `organizationId` string, uuid, required: Server-generated. Read-only. The Shopify store that owns this experience.
    - `type` 'content/advanced' | 'content/onsiteEdits' | 'content/url' | 'content/theme' | 'content/template' | 'personalization' | 'personalization/offer' | 'pricing' | 'checkoutBlock' | 'postPurchase' | 'onsiteUpsell' | 'shipping' | 'sitewide', required: Determines which variation fields are relevant: content/onsiteEdits for DOM edits, content/advanced for CSS/JS injection, content/url for redirect split tests, content/theme for theme tests, content/template for template tests.
    - `category` 'experiment' | 'personalization', required: Distinguishes A/B experiments (statistical testing) from personalization rules (deterministic targeting).
    - `status` 'pending' | 'started' | 'ended' | 'paused', required: Server-managed lifecycle state. Transitions via start/pause/end actions: pending -> started -> paused/ended.
    - `testTypes` object, required: Server-generated. Read-only. Flags derived from 'type' indicating which variation capabilities are active.
      - `hasTestPricing` boolean, required: Server-generated. Read-only. True when price testing is active.
      - `hasTestShipping` boolean, required: Server-generated. Read-only. True when shipping rate testing is active.
      - `hasTestCampaign` boolean, required: Server-generated. Read-only. True when campaign/offer testing is active.
      - `hasTestContent` boolean, required: Server-generated. Read-only. True when any content variation type is enabled.
      - `hasTestContentUrl` boolean, required: Server-generated. Read-only. True when URL redirect variations are in use.
      - `hasTestContentAdvanced` boolean, required: Server-generated. Read-only. True when custom JS/CSS variations are in use.
      - `hasTestContentOnsite` boolean, required: Server-generated. Read-only. True when visual onsite edit variations are in use.
      - `hasTestContentTemplate` boolean, required: Server-generated. Read-only. True when Shopify template variations are in use.
      - `hasTestContentTheme` boolean, required: Server-generated. Read-only. True when Shopify theme variations are in use.
      - `hasTestOnsiteInjections` boolean, required: Server-generated. Read-only. True when CSS/JS injection variations are in use.
      - `hasTestCheckoutBlocks` boolean, required: Server-generated. Read-only. True when checkout block variations are in use.
      - `hasTestPostPurchase` boolean, required: Server-generated. Read-only. True when post-purchase upsell variations are in use.
      - `hasTestOnsiteUpsell` boolean, required: Server-generated. Read-only. True when onsite upsell components are in use.
    - `experiencePageTargeting` object[], required: Rules controlling where this experience activates. Primarily URL/path rules, but the same expression format also supports 'device', 'country', 'visitor', 'trafficSource', 'referrer', and 'cookie'. Empty means all pages. To target the whole experience at a device (e.g. desktop only), prefer an `audience` filter over a page-targeting rule.
      - `id` string, uuid, required
      - `filter` 'equals' | 'contains' | 'startsWith' | 'endsWith' | 'doesNotEqual' | 'doesNotContain' | 'doesNotStartWith' | 'doesNotEndWith' | 'isNull' | 'isNotNull' | 'regex', nullable
      - `filterType` 'utm' | 'url' | 'device' | 'visitor' | 'jsExpression' | 'trafficSource' | 'country' | 'referrer' | 'cookie', required
      - `value` string, required
      - `order` number, required
      - `expression` object[], nullable
        - `query` object
          - `key` string, required: Visitor attribute or parameter name to match (e.g., 'utm_source', 'device_type').
          - `value` string, required: Expected value to compare against the visitor's actual value for this key. Constrained by `type`: when type is 'device' this must be exactly 'any', 'mobile', or 'desktop'.
          - `filter` 'equals' | 'contains' | 'startsWith' | 'endsWith' | 'doesNotEqual' | 'doesNotContain' | 'doesNotStartWith' | 'doesNotEndWith' | 'isNull' | 'isNotNull' | 'regex', nullable: Comparison operator (e.g., equals, contains, startsWith).
          - `type` 'utm' | 'url' | 'urlPath' | 'device' | 'visitor' | 'purchaseLikelihood' | 'jsExpression' | 'trafficSource' | 'country' | 'referrer' | 'cookie' | 'klaviyo' | 'landingPage', required: Category of the parameter being matched. Determines which keys are valid. Use 'device' for device targeting (pair with key 'device', filter 'equals', and value 'any' | 'mobile' | 'desktop'); 'utm'/'url' for query params; 'urlPath' for the path; and 'country', 'visitor', 'trafficSource', 'referrer', 'cookie', 'landingPage', 'klaviyo', or 'jsExpression' for the rest.
        - `operator` 'and' | 'or' | 'start_paren' | 'end_paren'
      - `experienceId` string, uuid
    - `experienceProductTargeting` object[], required: Product attribute rules controlling which products this experience applies to. Empty means all products.
      - `id` string, uuid, required: Server-generated. Read-only.
      - `experienceId` string, uuid, required: References the parent experience.
      - `target` 'productPage' | 'productCard', required: Storefront context where targeting rules are evaluated (product detail pages vs collection/search listings).
      - `expression` object[], nullable: Boolean expression tree of product attribute conditions. Each node has either a 'query' (leaf) or 'operator' (combinator).
        - `query` object
          - `key` 'productId' | 'collection' | 'tag' | 'price' | 'inventory', required: Product attribute to filter on. Determines which product property is evaluated.
          - `value` union, required: Expected value. String for text attributes (productId, collection, tag); number for numeric attributes (price, inventory).
            - string
            - number
          - `filter` 'includes' | 'doesNotInclude' | 'greaterThan' | 'lessThan', required: Comparison operator for evaluating the product attribute against the value.
          - `type` 'productId' | 'collection' | 'tag' | 'price' | 'inventory', required: Mirrors the key field. Determines attribute category for validation.
        - `operator` 'and' | 'or' | 'start_paren' | 'end_paren'
    - `experienceActions` object[], required: Server-generated. Read-only. Lifecycle state transitions (start, pause, end, delete, reset) recorded for this experience. On GET /experiences/{experienceId}, each entry includes a `performedBy` field with the triggering user's email, resolved from History records (may be null if unresolvable). Distinct from the list endpoint's raw `history` field, which contains broader user-action records.
      - `id` string, uuid, required
      - `experienceId` string, uuid, required
      - `action` 'start' | 'pause' | 'end' | 'delete' | 'reset', required
      - `actionTs` number, required
      - `performedBy` string, nullable: Email of the user who triggered this lifecycle event. Resolved from History records by matching action type and timestamp within a 5-minute window. Null if no matching History record is found, or if the record has no associated user. Currently only populated by GET /experiences/{experienceId}; list endpoints return null.
    - `experienceIntegrations` object[], required: Connected third-party integrations (e.g., Google Analytics, Segment).
      - `id` string, uuid, required
      - `createdAtTs` number, required
      - `integration` object, required
        - `id` string, uuid, required
        - `name` 'Recharge' | 'StayAi' | 'GrowLTV' | 'OneClickUpsell' | 'Google' | 'Amped' | 'Clarity' | 'Hotjar' | 'Heatmap' | 'CustomApi' | 'Klaviyo' | 'Slack' | 'Amplitude' | 'Heap' | 'Segment' | 'IntelligemsAPI' | 'IntelligemsMcp' | 'UPS' | 'MetaAds', required
        - `description` string, required
        - `enabled` boolean, required
        - `globalSettings` unknown, required
        - `apis` object[], required
          - `id` string, uuid, required
          - `name` string, required
          - `description` string, nullable
          - `accessToken` string, required
          - `scopes` string[], required
          - `organization` object, required
            - `id` string, uuid, required
            - `name` string, required
        - `createdAtTs` number
        - `lastUpdateTs` number
      - `experienceSettings` unknown, required
      - `enabled` boolean, required
    - `experienceCustomMetrics` object[], required: Custom event-based metrics tracked alongside standard key metrics.
      - `id` string, uuid, required: Server-generated. Read-only.
      - `experienceId` string, uuid, required: References the parent experience.
      - `order` number, required: Display position in the analytics dashboard. 0-indexed.
      - `customEventId` string, uuid, required: References the custom event definition configured in the organization's analytics settings.
      - `customEvent` union, required: Server-generated. Read-only. Expanded custom event definition with name, tracking details, and configuration.
        - object
          - `id` string, uuid, required
          - `identifier` string, required
          - `name` string, required
          - `description` string, nullable
          - `eventCountLastDay` number, nullable
          - `lastEventTs` number, nullable
          - `error` string, nullable
          - `createdAtTs` number, required
          - `lastUpdateTs` number, required
          - `archivedAtTs` number, nullable
          - `applyToUrls` object[], nullable
            - `matchBy` 'equals' | 'contains' | 'startsWith' | 'endsWith' | 'doesNotEqual' | 'doesNotContain' | 'doesNotStartWith' | 'doesNotEndWith' | 'isNull' | 'isNotNull' | 'regex', required
            - `value` string, required
            - `error` string, nullable
          - `experiencesList` string[], nullable
          - `type` 'pageView', required
          - `settings` object, required
        - object
          - `id` string, uuid, required
          - `identifier` string, required
          - `name` string, required
          - `description` string, nullable
          - `eventCountLastDay` number, nullable
          - `lastEventTs` number, nullable
          - `error` string, nullable
          - `createdAtTs` number, required
          - `lastUpdateTs` number, required
          - `archivedAtTs` number, nullable
          - `applyToUrls` object[], nullable
            - `matchBy` 'equals' | 'contains' | 'startsWith' | 'endsWith' | 'doesNotEqual' | 'doesNotContain' | 'doesNotStartWith' | 'doesNotEndWith' | 'isNull' | 'isNotNull' | 'regex', required
            - `value` string, required
            - `error` string, nullable
          - `experiencesList` string[], nullable
          - `type` 'productPageView', required
          - `settings` object[], required
            - `productId` string, required
            - `handle` string, required
        - object
          - `id` string, uuid, required
          - `identifier` string, required
          - `name` string, required
          - `description` string, nullable
          - `eventCountLastDay` number, nullable
          - `lastEventTs` number, nullable
          - `error` string, nullable
          - `createdAtTs` number, required
          - `lastUpdateTs` number, required
          - `archivedAtTs` number, nullable
          - `applyToUrls` object[], nullable
            - `matchBy` 'equals' | 'contains' | 'startsWith' | 'endsWith' | 'doesNotEqual' | 'doesNotContain' | 'doesNotStartWith' | 'doesNotEndWith' | 'isNull' | 'isNotNull' | 'regex', required
            - `value` string, required
            - `error` string, nullable
          - `experiencesList` string[], nullable
          - `type` 'collectionPageView', required
          - `settings` object[], required
            - `handle` string, required
        - object
          - `id` string, uuid, required
          - `identifier` string, required
          - `name` string, required
          - `description` string, nullable
          - `eventCountLastDay` number, nullable
          - `lastEventTs` number, nullable
          - `error` string, nullable
          - `createdAtTs` number, required
          - `lastUpdateTs` number, required
          - `archivedAtTs` number, nullable
          - `applyToUrls` object[], nullable
            - `matchBy` 'equals' | 'contains' | 'startsWith' | 'endsWith' | 'doesNotEqual' | 'doesNotContain' | 'doesNotStartWith' | 'doesNotEndWith' | 'isNull' | 'isNotNull' | 'regex', required
            - `value` string, required
            - `error` string, nullable
          - `experiencesList` string[], nullable
          - `type` 'clickEvent', required
          - `settings` object, required
            - `selectors` string[], required
        - object
          - `id` string, uuid, required
          - `identifier` string, required
          - `name` string, required
          - `description` string, nullable
          - `eventCountLastDay` number, nullable
          - `lastEventTs` number, nullable
          - `error` string, nullable
          - `createdAtTs` number, required
          - `lastUpdateTs` number, required
          - `archivedAtTs` number, nullable
          - `applyToUrls` object[], nullable
            - `matchBy` 'equals' | 'contains' | 'startsWith' | 'endsWith' | 'doesNotEqual' | 'doesNotContain' | 'doesNotStartWith' | 'doesNotEndWith' | 'isNull' | 'isNotNull' | 'regex', required
            - `value` string, required
            - `error` string, nullable
          - `experiencesList` string[], nullable
          - `type` 'elementViewed', required
          - `settings` object, required
            - `selectors` string[], required
        - object
          - `id` string, uuid, required
          - `identifier` string, required
          - `name` string, required
          - `description` string, nullable
          - `eventCountLastDay` number, nullable
          - `lastEventTs` number, nullable
          - `error` string, nullable
          - `createdAtTs` number, required
          - `lastUpdateTs` number, required
          - `archivedAtTs` number, nullable
          - `applyToUrls` object[], nullable
            - `matchBy` 'equals' | 'contains' | 'startsWith' | 'endsWith' | 'doesNotEqual' | 'doesNotContain' | 'doesNotStartWith' | 'doesNotEndWith' | 'isNull' | 'isNotNull' | 'regex', required
            - `value` string, required
            - `error` string, nullable
          - `experiencesList` string[], nullable
          - `type` 'scrollDepth', required
          - `settings` object, required
            - `mobile` object, required
              - …
            - `desktop` object, required
              - …
        - object
          - `id` string, uuid, required
          - `identifier` string, required
          - `name` string, required
          - `description` string, nullable
          - `eventCountLastDay` number, nullable
          - `lastEventTs` number, nullable
          - `error` string, nullable
          - `createdAtTs` number, required
          - `lastUpdateTs` number, required
          - `archivedAtTs` number, nullable
          - `applyToUrls` object[], nullable
            - `matchBy` 'equals' | 'contains' | 'startsWith' | 'endsWith' | 'doesNotEqual' | 'doesNotContain' | 'doesNotStartWith' | 'doesNotEndWith' | 'isNull' | 'isNotNull' | 'regex', required
            - `value` string, required
            - `error` string, nullable
          - `experiencesList` string[], nullable
          - `type` 'javascriptEvent', required
          - `settings` object, required
            - `code` string, required
        - object
          - `id` string, uuid, required
          - `identifier` string, required
          - `name` string, required
          - `description` string, nullable
          - `eventCountLastDay` number, nullable
          - `lastEventTs` number, nullable
          - `error` string, nullable
          - `createdAtTs` number, required
          - `lastUpdateTs` number, required
          - `archivedAtTs` number, nullable
          - `applyToUrls` object[], nullable
            - `matchBy` 'equals' | 'contains' | 'startsWith' | 'endsWith' | 'doesNotEqual' | 'doesNotContain' | 'doesNotStartWith' | 'doesNotEndWith' | 'isNull' | 'isNotNull' | 'regex', required
            - `value` string, required
            - `error` string, nullable
          - `experiencesList` string[], nullable
          - `type` 'javascriptImportedEvent', required
          - `settings` object, required
            - `registered` boolean, required
    - `experienceKeyMetrics` object[], required: Business metrics (revenue, conversion, AOV, etc.) used to evaluate test performance. One must be primary.
      - `id` string, uuid, required: Server-generated. Read-only.
      - `experienceId` string, uuid, required: References the parent experience.
      - `order` integer, required: Display position in the analytics dashboard. 0-indexed.
      - `isPrimary` boolean, required: The primary metric determines the main success signal for the test. Exactly one per experience.
      - `standardEventId` 'conversionRate' | 'addToCartRate' | 'abandonedCartRate' | 'abandonedCheckoutRate' | 'checkoutBeginRate' | 'checkoutEnterContactInfoRate' | 'checkoutAddressSubmittedRate' | 'viewProductPageRate' | 'viewCollectionPageRate' | 'netRevenuePerVisitor' | 'netProductRevenuePerOrder' | 'netRevenuePerOrder' | 'avgUnitsPerOrder' | 'avgProductRevenuePerUnit' | 'profitPerVisitor' | 'profitPerOrder' | 'pctOrdersFreeShipping' | 'netShippingRevenuePerOrder' | 'subscriptionOrdersPerVisitor' | 'subscriptionRevenuePerVisitor' | 'subscriptionProfitPerVisitor' | 'subscriptionProductRevenuePerOrder' | 'avgDiscountPerDiscountedOrder' | 'avgDiscountPerAllOrders' | 'pctSubscriptionOrders' | 'subscriptionRevenuePerOrder' | 'pctOrdersWithPostPurchaseOffer' | 'netRevenueFromPostPurchaseOffer' | 'pctOrdersWithUpsell' | 'netRevenueFromUpsell' | 'pctOrdersWithOnsiteUpsell' | 'netRevenueFromOnsiteUpsell', nullable: Standard e-commerce event (e.g., revenue, conversion). Mutually exclusive with experienceCustomMetricId.
      - `experienceCustomMetricId` string, uuid, nullable: References a custom event metric. Mutually exclusive with standardEventId. Exactly one of these must be set.
    - `currency` object, nullable: Currency settings for price display and analytics calculations. Null inherits store default.
      - `code` string, required: ISO 4217 currency code used for analytics and price calculations.
      - `country` string: ISO country code for locale-specific formatting.
      - `options` unknown
      - `symbol` string, required: Display symbol prepended to amounts (e.g., '$', '€').
      - `suffix` string: Text appended after amounts for postfix currencies (e.g., 'kr' in '100 kr').
    - `variations` object[], required: Test variants including the control. One must be control; traffic percentages must sum to 100.
      - `id` string, uuid, required: Server-generated. Read-only.
      - `experienceId` string, uuid, required: References the parent experience.
      - `name` string, required: Display name (e.g., 'Control', 'Variant A'). Unique within the experience.
      - `percentage` number, required: Traffic allocation weight. All percentages across sibling variations must sum to 100.
      - `isControl` boolean, required: The baseline variation all others are measured against. Exactly one per experience.
      - `order` integer, required: Display order in the analytics dashboard. 0-indexed.
      - `priceChange` string, nullable: Price adjustment amount for pricing-type experiences. Positive increases price, negative discounts. Use priceChange for simple price A/B tests; use offer for structured discount campaigns (tiered, BOGO, free shipping).
      - `priceChangeUnit` 'percent' | 'dollar', nullable: How priceChange is applied: as a percentage of the original price or a fixed monetary amount.
      - `priceRoundingType` 'none' | 'nearest' | 'up' | 'down', nullable: Rounding strategy applied after priceChange (e.g., round up, round down, charm pricing).
      - `priceRoundingAmount` string, nullable: Target value for rounding (e.g., 0.99 for charm pricing like $X.99).
      - `onsiteEdits` object[], required: DOM content modifications (text, HTML, image swaps, element removal). For CSS styling changes, use onsiteInjections instead.
        - `id` string, uuid, required: Server-generated. Read-only.
        - `onsiteEditType` 'html' | 'text' | 'image' | 'hide', nullable: Content modification strategy (html, text, image, or hide).
        - `variationId` string, uuid, required: References the parent variation.
        - `find` string, nullable, required: Pattern to locate on the page. Interpreted as regex when isRegex is true.
        - `title` string, nullable: Dashboard label for identifying this edit.
        - `isRegex` boolean, required: When true, 'find' is treated as a regular expression.
        - `replace` string, required: Replacement content. Interpretation depends on onsiteEditType: HTML markup, plain text, or image URL.
        - `querySelectors` string[], required: CSS selectors scoping which DOM elements this edit targets (e.g., '.product-title').
        - `skip` boolean, required: When true, this edit is temporarily disabled without being deleted.
        - `remove` boolean, required: When true, the matched element is removed from the DOM instead of having its content replaced.
        - `groupId` string: Groups related edits together so they can be managed as a unit.
        - `isHtml` boolean, required
        - `isImage` boolean, required
        - `insertType` 'beforebegin' | 'afterbegin' | 'beforeend' | 'afterend', nullable, required: DOM insertion position relative to the target (beforebegin, afterbegin, beforeend, afterend). Null means content replacement.
        - `createdAtUrl` string, nullable: Server-generated. Read-only. Storefront URL where this edit was originally created via the visual editor.
        - `createdAtTs` number, nullable: Server-generated. Read-only. Unix timestamp in seconds.
        - `imageSearchUrl` string, nullable: URL pathname for locating images to replace. When set, images are found by URL match; when null, querySelectors is used instead.
        - `source` 'ai', nullable
      - `onsiteInjections` object, nullable: CSS styling and custom JS injection. At most one per variation. For DOM content changes (text, images, HTML), use onsiteEdits instead.
        - `id` string, uuid, required: Server-generated. Read-only.
        - `variationId` string, uuid, required: References the parent variation.
        - `customCss` string, nullable: CSS injected globally on the page when this variation is active.
        - `customJs` string, nullable: JavaScript executed on the page. Execution timing controlled by jsInjectionMode.
        - `jsInjectionMode` object, required: Controls when customJs runs: immediately on load, after window load, or after a configurable delay.
          - `type` 'immediately' | 'onWindowLoad' | 'timeout', required: Execution timing for injected JS. When 'timeout', the timeout field specifies the delay.
          - `timeout` union: Delay in milliseconds before JS execution. Only relevant when type is 'timeout'.
            - number
            - string
        - `source` 'ai', nullable
      - `offer` object, nullable: Structured discount configuration (tiered volume discounts, cart-level discounts, gift-with-purchase, free shipping). Use offer for campaign/discount experiences; use priceChange for simple price A/B tests.
        - `id` string, uuid, required: Server-generated. Read-only.
        - `variationId` string, uuid, required: References the parent variation this offer belongs to.
        - `enabled` boolean, required: Whether the offer is actively applying discounts to customers on the storefront.
        - `isTest` boolean, required: Set on some offers the app copied between test groups. It doesn't mean draft and doesn't change who gets the discount; an offer saved with it true is renamed 'Volume Offer Test Group'. The external API always saves false.
        - `isArchived` boolean, required: Whether the offer has been archived and is no longer active.
        - `name` string, required: Internal label for identifying the offer in dashboards.
        - `unitType` 'unit' | 'dollar', required: Threshold basis for tiered discounts: per-item quantity or monetary amount spent.
        - `discountType` 'percentage' | 'dollar', required: How the discount value is calculated (e.g., percentage off, fixed amount off).
        - `tiers` object[], required: Volume discount tiers ordered by threshold ascending (e.g., buy 2 = 10% off, buy 3 = 15% off).
          - `id` string, uuid, required
          - `minimumUnits` number, required
          - `maximumUnits` number, required
          - `unitDiscount` number, required
          - `bxgyGetQuantity` integer, required
          - `discountTitle` string, nullable, required
          - `giftWithPurchaseTitle` string, nullable, required
          - `isFreeShipping` boolean, required
          - `isGiftWithPurchase` boolean, required
          - `giftWithPurchaseProductId` string, nullable
          - `giftWithPurchaseVariantId` string, nullable
          - `giftWithPurchaseVariantIds` string[], required
          - `autoAddGiftWithPurchase` boolean, required
          - `giftWithPurchaseHandle` string, nullable
        - `maximumDollarDiscount` number, nullable: Hard cap on the total dollar discount. Null means no cap is applied.
        - `discountApplicationType` 'tieredDiscount' | 'cartDiscount' | 'freeGift' | 'freeShipping' | 'buyXGetY' | '', required: Core discount mechanic (tiered volume, flat cart-level, gift-with-purchase, or free shipping).
        - `discountApplicationMethod` 'perItem' | 'perOrder', required: Whether the discount applies per individual item or to the entire order.
        - `combinesWithIntelligems` boolean, required: Whether this offer stacks with other active Intelligems discounts.
        - `combinesWithShopify` boolean, required: Whether this offer stacks with native Shopify discount codes.
        - `shouldRejectCodes` boolean, required: When true, manual discount codes entered at checkout are rejected while this offer is active.
        - `shippingDiscount` object, nullable, required: Shipping discount details. Only present when discountApplicationType is freeShipping.
          - `id` string, uuid, required
          - `discountType` 'percentage' | 'dollar', required
          - `unitDiscount` number, required: Percent off the shipping rate. 100 is free shipping.
          - `rateFilter` union, required
            - object
              - …
            - object
              - …
          - `countryFilter` object, nullable, required
            - `allow` string[]
            - `exclude` string[]
          - `discountLabel` string, nullable, required
        - `requireSameItem` boolean, required: For tiered discounts: when true, only multiples of the same product count toward thresholds.
        - `bxgyGetProductScope` 'all' | 'list', nullable: For Buy X Get Y: where the free units come from. Null means the products bought; 'list' means the offer's get products; 'all' means any product.
        - `subscriptionApplicationType` 'oneTime' | 'firstSub' | 'oneTimeAndFirstSub', required: Controls which purchase types this offer applies to: 'oneTime' (one-time purchases only), 'firstSub' (first subscription orders only), or 'oneTimeAndFirstSub' (both one-time and first subscription orders). Free shipping offers (discountApplicationType 'freeShipping') always apply to both and are saved as 'oneTimeAndFirstSub'.
      - `offerId` string, uuid, nullable: Server-generated. Read-only. References the associated offer. Populated when offer is set.
      - `shippingRateGroups` object[]: Shipping rate overrides. Only populated for shipping test experiences.
        - `id` string, uuid, required
        - `groupType` 'flatRate' | 'flatRateWithThreshold' | 'thresholdOnly' | 'tieredByPriceOrWeight' | 'custom', required
        - `position` number, required
        - `rates` object[], required
          - `id` string, uuid
          - `name` string, required
          - `amount` number, required
          - `rateCode` string, nullable
          - `rateType` 'amount' | 'threshold' | 'tier', required
          - `currency` 'AED' | 'AFN' | 'ALL' | 'AMD' | 'ANG' | 'AOA' | 'ARS' | 'AUD' | 'AWG' | 'AZN' | 'BAM' | 'BBD' | 'BDT' | 'BGN' | 'BIF' | 'BMD' | 'BND' | 'BOB' | 'BRL' | 'BSD' | 'BWP' | 'BZD' | 'CAD' | 'CDF' | 'CHF' | 'CLP' | 'CNY' | 'COP' | 'CRC' | 'CVE' | 'CZK' | 'DJF' | 'DKK' | 'DOP' | 'DZD' | 'EGP' | 'ETB' | 'EUR' | 'FJD' | 'FKP' | 'GBP' | 'GEL' | 'GIP' | 'GMD' | 'GNF' | 'GTQ' | 'GYD' | 'HKD' | 'HNL' | 'HRK' | 'HTG' | 'HUF' | 'IDR' | 'ILS' | 'INR' | 'ISK' | 'JMD' | 'JPY' | 'KES' | 'KGS' | 'KHR' | 'KMF' | 'KRW' | 'KYD' | 'KZT' | 'LAK' | 'LBP' | 'LKR' | 'LRD' | 'LSL' | 'MAD' | 'MDL' | 'MGA' | 'MKD' | 'MMK' | 'MNT' | 'MOP' | 'MUR' | 'MVR' | 'MWK' | 'MXN' | 'MYR' | 'MZN' | 'NAD' | 'NGN' | 'NIO' | 'NOK' | 'NPR' | 'NZD' | 'PAB' | 'PEN' | 'PGK' | 'PHP' | 'PKR' | 'PLN' | 'PYG' | 'QAR' | 'RON' | 'RSD' | 'RUB' | 'RWF' | 'SAR' | 'SBD' | 'SCR' | 'SEK' | 'SGD' | 'SHP' | 'SLL' | 'SRD' | 'STD' | 'SZL' | 'THB' | 'TJS' | 'TOP' | 'TRY' | 'TTD' | 'TWD' | 'TZS' | 'UAH' | 'UGX' | 'USD' | 'UYU' | 'UZS' | 'VND' | 'VUV' | 'WST' | 'XAF' | 'XCD' | 'XOF' | 'XPF' | 'YER' | 'ZAR' | 'ZMW', required
          - `condition` object, nullable
            - `id` string, uuid
            - `min` union, required
              - …
            - `max` union
              - …
            - `conditionType` 'currency' | 'weight', required
            - `unit` 'g' | 'kg' | 'lb' | 'oz', nullable
          - `description` string, nullable
        - `variationId` string, uuid, required
        - `scopes` object[], nullable
          - `marketId` string, required
          - `collectionIds` string[], nullable, required
          - `originLocationIds` string[], required
      - `excludeProducts` boolean: When true, specific products are excluded from price changes. Use excludeProducts when most products should be tested and only a few excluded. Mutually exclusive with includeProducts.
      - `includeProducts` boolean: When true, only specific products receive price changes. Use includeProducts when only a few products should be tested. Mutually exclusive with excludeProducts.
      - `testExperienceId` string, nullable: Links to another experience for advanced multi-experience configurations.
      - `functionSyncError` boolean, required: Server-generated. Read-only. Indicates a sync failure with Shopify Functions for this variation's discount.
      - `redirects` object[]: URL redirect rules for content/url experiences.
        - `id` string, uuid, required: Server-generated. Read-only.
        - `group` number, required: Numeric group for organizing related redirects. Redirects sharing an originUrl should share a group number.
        - `variationId` string, uuid, required: References the parent variation.
        - `originUrl` string, required: URL pattern matched against visitor page URLs. Matching behavior depends on the 'filter' field.
        - `destinationUrl` string, nullable: Target URL visitors are sent to. Used when redirectType is 'fullReplacement'.
        - `queryParams` object[], required: Key-value pairs appended to the destination URL as query parameters.
          - `key` string, required: Query parameter name appended to the destination URL.
          - `value` string, required: Query parameter value.
        - `skip` boolean, required: When true, this redirect is temporarily disabled.
        - `isThemeTest` boolean, required: True when this redirect tests alternate Shopify themes. Used with content/theme experiences.
        - `isTemplateTest` boolean, required: True when this redirect tests alternate Shopify templates. Used with content/template experiences.
        - `templateType` '404' | '' | 'article' | 'blog' | 'cart' | 'collection' | 'index' | 'list-collections' | 'page' | 'password' | 'product' | 'search', nullable: Shopify template type being tested (e.g., product, collection).
        - `templateSuffixes` string[], nullable, required: Alternate Shopify template suffixes being tested (e.g., 'alternate', 'new-layout').
        - `redirectOnce` boolean, required: When true, the redirect fires only once per visitor session to avoid redirect loops.
        - `filter` 'matchesExactly' | 'contains' | 'endsWith' | 'matchesRegex' | 'none', required: Matching strategy for originUrl (e.g., exact match, contains, endsWith, regex).
        - `find` string, nullable: Pattern to locate within the URL for partial replacement. Only used when redirectType is 'partialReplacement'.
        - `redirectType` 'fullReplacement' | 'partialReplacement', required: fullReplacement navigates to destinationUrl; partialReplacement swaps only the 'find' match within the current URL.
      - `userInterfaces` object[]: UI widget configurations displayed for this variation.
        - `id` string, uuid, required
        - `isEnabled` boolean
        - `isArchived` boolean, required
        - `widget` object
          - `id` string, uuid, required
          - `name` string, required
          - `enabledSitewide` boolean, required
          - `parentId` string, uuid, nullable
          - `widgetType` 'messageBoxPopup' | 'messageBoxSlideOut' | 'quantityButtons' | 'discountProgressBar' | 'shippingProgressBar' | 'gwpVariantPicker', required
          - `config` object, required
            - `desktop` unknown
            - `mobile` unknown
        - `widgetId` string, required
        - `category` 'quantityButtons' | 'progressBar' | 'messageBox' | 'gwpVariantPicker'
        - `variationId` string, uuid, nullable
        - `desktopVariables` unknown
        - `mobileVariables` unknown
        - `styleOverrides` unknown
      - `checkoutBlocks` union[]: Shopify checkout extensibility block configurations for this variation.
        - union
          - object
            - `id` string, uuid, required: Server-generated. Read-only.
            - `variationId` string, uuid, required: References the parent variation.
            - `locationId` string, required: Shopify checkout extensibility target location where the block renders.
            - `blockType` 'trustBadge', required
            - `blockTemplate` 'badgeList' | 'badgeTiles' | 'callOut' | 'grid' | 'header' | 'images' | 'brandLogo' | 'textOnly', nullable: The template preset this block was created from, within its block type. Null on blocks saved before templates were persisted, which callers must treat as unknown rather than assuming a default.
            - `name` string, required: Display name for identifying this block in the dashboard.
            - `displayConditions` object: Optional cart-based conditions; the block renders only when the expression evaluates true against the current cart.
              - …
            - `variables` object, required: Configurable content for the trust badge (e.g., badge images, guarantee text).
              - …
            - `styles` object, required: CSS styling overrides for the trust badge appearance.
              - …
          - object
            - `id` string, uuid, required: Server-generated. Read-only.
            - `variationId` string, uuid, required: References the parent variation.
            - `locationId` string, required: Shopify checkout extensibility target location where the block renders.
            - `blockType` 'upsell', required
            - `blockTemplate` 'productTiles' | 'productList' | 'singleProduct' | 'singleProductCheckbox', nullable: The template preset this block was created from, within its block type. Null on blocks saved before templates were persisted, which callers must treat as unknown rather than assuming a default.
            - `name` string, required: Display name for identifying this block in the dashboard.
            - `displayConditions` object: Optional cart-based conditions; the block renders only when the expression evaluates true against the current cart.
              - …
            - `variables` object, required: Configurable content for the upsell block (e.g., product selection, heading text, CTA label).
              - …
            - `styles` object, required: CSS styling overrides for the upsell block appearance.
              - …
            - `upsellProductRules` object[], required: Product selection and recommendation rules that determine which products to show in this upsell block.
              - …
            - `agenticLogicPlacementId` string, uuid, nullable: Agentic Logic placement this block evaluates through. Absent means the legacy rule engine serves it — clearing the mapping is the per-surface rollback.
            - `agenticLogicRuleId` string, uuid, nullable: WRITE-SIDE intent: the Agentic Logic rule this block should serve. The experience save upserts the placement and the (placement, variation) assignment from it and stamps `agenticLogicPlacementId`, so callers never assemble that pair themselves. Null detaches the block and returns it to the legacy engine. Reads echo the rule currently assigned.
          - object
            - `id` string, uuid, required: Server-generated. Read-only.
            - `variationId` string, uuid, required: References the parent variation.
            - `locationId` string, required: Shopify checkout extensibility target location where the block renders.
            - `blockType` 'shippingProgressBar', required
            - `blockTemplate` 'minimal' | 'milestones', nullable: The template preset this block was created from, within its block type. Null on blocks saved before templates were persisted, which callers must treat as unknown rather than assuming a default.
            - `name` string, required: Display name for identifying this block in the dashboard.
            - `displayConditions` object: Optional cart-based conditions; the block renders only when the expression evaluates true against the current cart.
              - …
            - `variables` object, required
              - …
            - `styles` object, required
              - …
          - object
            - `id` string, uuid, required: Server-generated. Read-only.
            - `variationId` string, uuid, required: References the parent variation.
            - `locationId` string, required: Shopify checkout extensibility target location where the block renders.
            - `blockType` 'timer', required
            - `blockTemplate` 'textCountdown' | 'digitalClock' | 'inlinePill', nullable: The template preset this block was created from, within its block type. Null on blocks saved before templates were persisted, which callers must treat as unknown rather than assuming a default.
            - `name` string, required: Display name for identifying this block in the dashboard.
            - `displayConditions` object: Optional cart-based conditions; the block renders only when the expression evaluates true against the current cart.
              - …
            - `variables` object, required
              - …
            - `styles` object, required
              - …
          - object
            - `id` string, uuid, required: Server-generated. Read-only.
            - `variationId` string, uuid, required: References the parent variation.
            - `locationId` string, required: Shopify checkout extensibility target location where the block renders.
            - `blockType` 'faqs', required
            - `blockTemplate` 'faqsAccordion', nullable: The template preset this block was created from, within its block type. Null on blocks saved before templates were persisted, which callers must treat as unknown rather than assuming a default.
            - `name` string, required: Display name for identifying this block in the dashboard.
            - `displayConditions` object: Optional cart-based conditions; the block renders only when the expression evaluates true against the current cart.
              - …
            - `variables` object, required
              - …
            - `styles` object, required
              - …
          - object
            - `id` string, uuid, required: Server-generated. Read-only.
            - `variationId` string, uuid, required: References the parent variation.
            - `locationId` string, required: Shopify checkout extensibility target location where the block renders.
            - `blockType` 'postPurchaseUpsell', required
            - `blockTemplate` unknown
            - `name` string, required: Display name for identifying this block in the dashboard.
            - `displayConditions` object: Optional cart-based conditions; the block renders only when the expression evaluates true against the current cart.
              - …
            - `variables` object, required
              - …
            - `styles` object, required
              - …
            - `upsellProductRules` object[], required: Product selection and recommendation rules that determine which products to show in this upsell block.
              - …
            - `agenticLogicPlacementId` string, uuid, nullable: Agentic Logic placement this block evaluates through. Absent means the legacy rule engine serves it — clearing the mapping is the per-surface rollback.
            - `agenticLogicRuleId` string, uuid, nullable: WRITE-SIDE intent: the Agentic Logic rule this block should serve. The experience save upserts the placement and the (placement, variation) assignment from it and stamps `agenticLogicPlacementId`, so callers never assemble that pair themselves. Null detaches the block and returns it to the legacy engine. Reads echo the rule currently assigned.
      - `cartTargeting` object[]: Cart-based targeting rules that determine when this variation is shown based on cart contents.
        - `id` string, uuid, required
        - `expression` object[], required
          - `query` object
            - `key` 'anything' | 'productId' | 'collection' | 'tag' | 'cartSubtotal' | 'cartItemCount' | 'subscription', required
            - `type` 'anything' | 'productId' | 'collection' | 'tag' | 'cartSubtotal' | 'cartItemCount' | 'subscription', required
            - `filter` 'includes' | 'doesNotInclude' | 'greaterThan' | 'lessThan' | 'equalTo' | 'greaterThanOrEqual' | 'lessThanOrEqual' | 'between', required
            - `value` union
              - …
          - `operator` 'and' | 'or' | 'start_paren' | 'end_paren'
      - `components` object[]: Onsite component configurations (e.g. onsite upsells) rendered on the storefront for this variation.
        - `id` string, uuid, required: Server-generated. Read-only.
        - `variationId` string, uuid, required: References the parent variation this component belongs to.
        - `config` union, required: The saved upsell: its type, look, products, targeting, and discount.
          - object
            - `type` 'onsiteUpsell', required: Discriminator for the component kind.
            - `placement` object, required: Where in the DOM the rendered upsell is injected.
              - …
            - `template` string, required: HTML for the upsell, including all static copy written inline. The per-product card is the markup between {{#each products}} and {{/each}}. May only reference declared slots: product.* data slots and the named slots (atc, variant-select); everything else is literal HTML.
            - `maxProductLimit` integer, required: Maximum number of products to render.
            - `excludeOutOfStock` boolean, required: Exclude products whose variants are all out of stock. Defaults to true.
            - `excludeItemsInCart` boolean, required: Exclude products already in the shopper's cart. Defaults to true.
            - `excludePdpProduct` boolean, required: On a PDP, exclude the product being viewed. Defaults to true; turn it off when the viewed product belongs in the result, e.g. a bundle built around it.
            - `discount` object: Optional discount applied to products added from this upsell.
              - …
            - `rules` object[], required: Prioritized list of rules. Each pairs an action (which products) with targeting (when to show). v1 ships a single rule.
              - …
            - `agenticLogicPlacementId` string, uuid, nullable: Agentic Logic placement this upsell evaluates through. Absent means the legacy rule engine serves it — clearing the mapping is the per-surface rollback.
            - `agenticLogicRuleId` string, uuid, nullable: WRITE-SIDE intent: the Agentic Logic rule this upsell should serve. The experience save upserts the placement and the (placement, variation) assignment from it and stamps `agenticLogicPlacementId`, so callers never assemble that pair themselves. Null detaches the component and returns it to the legacy engine. Reads echo the rule currently assigned; the field is never persisted in the stored config.
          - object
            - `type` 'bundleOnsiteUpsell', required: Discriminator for the component kind.
            - `placement` object, required: Where in the DOM the rendered bundle is injected.
              - …
            - `template` string, required: HTML for the bundle card. The per-product row is the markup between {{#each products}} and {{/each}}; the surrounding shell holds the copy slots ({{heading}}, {{subheading}}) and the footer the whole selection shares ({{bundle.price}}, {{bundle.comparePrice}}, {{bundle.atc}}). Each row holds {{checkbox}}, {{product.image}}, {{product.url}}, {{product.title}}, {{product.price}}, {{product.compareAtPrice}} and {{variant-select}}. Every slot is required, even when editing. May only reference declared slots; everything else is literal HTML. No `<script>` tags or inline JavaScript.
            - `copy` object, required: Shopper-facing text, edited in the panel rather than inline in the template.
              - …
            - `maxProductLimit` integer, required: Number of products the bundle offers.
            - `allowItemSelection` boolean, required: Whether the shopper can choose which of the bundle's products to add. When false every rendered product is included; exclusions can still trim how many render, so lower tiers stay reachable.
            - `excludeOutOfStock` boolean, required: Exclude products whose variants are all out of stock. Defaults to true.
            - `excludeItemsInCart` boolean, required: Exclude products already in the shopper's cart. Defaults to true.
            - `excludePdpProduct` boolean, required: On a PDP, exclude the product being viewed. Defaults to true; turn it off when the viewed product belongs in the result, e.g. a bundle built around it.
            - `discount` object: Optional count-tiered discount applied to the products added from this bundle.
              - …
            - `rules` object[], required: Prioritized list of rules. Each pairs an action (which products) with targeting (when to show).
              - …
            - `agenticLogicPlacementId` string, uuid, nullable: Agentic Logic placement this bundle selects its products through. Absent means the legacy rule engine serves it — clearing the mapping is the per-surface rollback. The engine chooses PRODUCTS only: a bundle's tiered discount always comes from `discount` below, never from the result envelope, which can only carry one flat value.
            - `agenticLogicRuleId` string, uuid, nullable: WRITE-SIDE intent: the Agentic Logic rule this bundle should serve. The experience save upserts the placement and the (placement, variation) assignment from it and stamps `agenticLogicPlacementId`, so callers never assemble that pair themselves. Null detaches the component and returns it to the legacy engine. Reads echo the rule currently assigned; the field is never persisted in the stored config. The engine chooses PRODUCTS only — a bundle's tiers always come from its own `discount`.
    - `createdAtTs` number, required: Server-generated. Read-only. Unix timestamp in milliseconds.
    - `isDeleted` boolean: Whether this experience has been soft-deleted and hidden from default listings.
    - `shippingTestMethodDefinitions` union[], required: Shipping rate configurations. Only populated for shipping test experiences.
      - union
        - object
          - `id` string, uuid
          - `shippingModel` 'legacy'
          - `deliveryProfileId` string, required
          - `deliveryLocationGroupId` string, required
          - `deliveryZoneId` string, required
          - `methodDefinitionId` string, nullable
          - `canonicalMethodId` string
          - `deleteTargetKind` 'canonical_method' | 'participant_method' | 'synthetic_free_condition' | 'synthetic_rate_definition'
          - `deleteTargetRateDefinitionId` string
          - `deleteTargetFreeCondition` object
            - `subject` string, required
            - `min` union
              - …
            - `max` union
              - …
        - object
          - `id` string, uuid
          - `shippingModel` 'markets', required
          - `marketTarget` union, required
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
    - `shippingCarrierProvider` 'intelligems' | 'custom', required: How shipping rates are sourced for this shipping test. Use "intelligems" for the managed carrier flow and "custom" to use custom provider settings.
    - `audience` object, nullable: Visitor segmentation rules. Null means all visitors are eligible.
      - `id` string, uuid, required: Server-generated. Read-only.
      - `experienceId` string, uuid, required: References the parent experience.
      - `enabled` boolean, required: When false, audience rules are ignored and all visitors are eligible.
      - `excludeCurrency` object, required: Currency and geo-based visitor exclusion configuration.
        - `exclude` boolean, required: Whether currency/geo-based exclusion is active.
        - `currency` string, nullable, required: ISO 4217 currency code to include. Null disables currency-based exclusion.
        - `country` string: ISO country code to include visitors from.
        - `region` string: Region or state code to include visitors from.
        - `city` string: City name to include visitors from.
      - `wholesale` boolean, required: Controls whether wholesale (B2B) customers are included in or excluded from the experience.
      - `audienceType` 'common' | 'custom' | 'advanced': Complexity level of the targeting rules: common (prebuilt), custom (simple), or advanced (full expression trees).
      - `elseAction` 'experienceInclude' | 'experienceExclude' | 'experienceUnassigned' | 'assignVariation' | 'randomVariation' | 'leaveUnassigned', nullable, required: Fallback for visitors matching no filter: 'randomVariation' assigns randomly across variations (most common), 'assignVariation' forces a specific variation (set elseVariationId), 'experienceExclude' removes them from the experience entirely, 'experienceUnassigned' leaves them unassigned for now ('leaveUnassigned' is the older spelling and is stored as experienceUnassigned).
      - `elseVariationId` string, uuid, nullable: Variation to force-assign when elseAction is 'assignVariation'. Typically set to the control variation to default non-targeted visitors to baseline.
      - `elseExcludeFromAnalytics` boolean, required: When true, visitors who match no filter are tracked but excluded from analytics calculations.
      - `filters` object[], required: Ordered filter rules evaluated from lowest priority value first (0-indexed). First matching filter determines visitor treatment.
        - `id` string, uuid, required: Server-generated. Read-only.
        - `priority` integer, required: Evaluation order. 0-indexed. Filters with lower values are evaluated first.
        - `action` 'experienceInclude' | 'experienceExclude' | 'experienceUnassigned' | 'assignVariation' | 'randomVariation' | 'leaveUnassigned', nullable, required: What happens when a visitor matches this filter: 'assignVariation' forces a specific variation (set variationId), 'experienceExclude' removes from the experience, 'randomVariation' assigns randomly. 'experienceInclude' shows a personalization to the visitor and is valid only on personalizations, whose filters use experienceInclude, experienceExclude or experienceUnassigned and never a traffic split.
        - `filterType` 'utm' | 'url' | 'urlPath' | 'device' | 'visitor' | 'purchaseLikelihood' | 'jsExpression' | 'trafficSource' | 'country' | 'referrer' | 'cookie' | 'klaviyo' | 'landingPage', required: Category of targeting rule (e.g., UTM parameters, device type, visitor type).
        - `expression` object[], nullable: Boolean expression tree. Each node has either a 'query' (leaf condition) or 'operator' (logical combinator), not both.
          - `query` object
            - `key` string, required: Visitor attribute or parameter name to match (e.g., 'utm_source', 'device_type').
            - `value` string, required: Expected value to compare against the visitor's actual value for this key. Constrained by `type`: when type is 'device' this must be exactly 'any', 'mobile', or 'desktop'.
            - `filter` 'equals' | 'contains' | 'startsWith' | 'endsWith' | 'doesNotEqual' | 'doesNotContain' | 'doesNotStartWith' | 'doesNotEndWith' | 'isNull' | 'isNotNull' | 'regex', nullable: Comparison operator (e.g., equals, contains, startsWith).
            - `type` 'utm' | 'url' | 'urlPath' | 'device' | 'visitor' | 'purchaseLikelihood' | 'jsExpression' | 'trafficSource' | 'country' | 'referrer' | 'cookie' | 'klaviyo' | 'landingPage', required: Category of the parameter being matched. Determines which keys are valid. Use 'device' for device targeting (pair with key 'device', filter 'equals', and value 'any' | 'mobile' | 'desktop'); 'utm'/'url' for query params; 'urlPath' for the path; and 'country', 'visitor', 'trafficSource', 'referrer', 'cookie', 'landingPage', 'klaviyo', or 'jsExpression' for the rest.
          - `operator` 'and' | 'or' | 'start_paren' | 'end_paren'
        - `expressionType` 'common' | 'custom', nullable: Whether this uses prebuilt common rules or custom expression logic.
        - `variationId` string, uuid, nullable: Variation to assign when action is 'assignVariation'. References a variation in the parent experience.
        - `excludeFromAnalytics` boolean, required: When true, visitors matching this filter are excluded from analytics even if included in the experience.
      - `evaluationFrequency` number, nullable: How often (in seconds) to re-evaluate audience rules for a returning visitor. Controls targeting freshness.
    - `lastUpdateTs` number, required: Server-generated. Read-only. Unix timestamp in milliseconds of the most recent modification.
    - `previewPath` string, nullable: Storefront URL path used when generating preview links (e.g., '/products/example').
    - `isExternal` boolean, nullable: True if this experience was created and is managed via the external API rather than the dashboard.
    - `startedAtTs` number, nullable, required: Server-generated. Read-only. Unix timestamp in milliseconds. Null if never started.
    - `pausedAtTs` number, nullable, required: Server-generated. Read-only. Unix timestamp in milliseconds. Null if not currently paused.
    - `archivedAtTs` number, nullable: Server-generated. Read-only. Unix timestamp in milliseconds. Null if not archived.
    - `requiresLink` boolean, required: When true, visitors must use a special link to enter the experience instead of being auto-assigned.
    - `linkBaseUrl` string, nullable, required: Base URL for generating access links. Only populated when requiresLink is true.
    - `endedAtTs` number, nullable, required: Server-generated. Read-only. Unix timestamp in milliseconds. Null if still active.
    - `productVariantCount` number, required: Server-generated. Read-only. Total product variants currently included in this experience.
    - `sourceExperienceId` string, uuid, nullable: Present when this experience was duplicated or rolled out from another. References the original.
    - `sourceAction` 'duplicate' | 'rollout', nullable: How this experience was derived from sourceExperienceId. Only present when sourceExperienceId is set.
    - `experienceAnalysis` object, required
      - `analyticsViewType` 'test_orders_only' | 'sitewide_orders' | 'none', required: Scope of orders included in analytics results. Determines whether only tested products or all store orders are counted.

## Other responses

- `429`: Too Many Requests

---

[API](https://skmtc.dev/intelligems/apis/intelligems-external-api-v25-10-beta.md) - [All operations](https://skmtc.dev/intelligems/apis/intelligems-external-api-v25-10-beta/llms.txt) - [OpenAPI document](https://skmtc.dev/intelligems/apis/intelligems-external-api-v25-10-beta/revisions/7b769b2f90b1?raw)
