Create experience
Changed onCreates a new experience.
The experience will be created in a draft state and must be activated separately before it will be served to visitors.
Required Fields
- name - A unique name for the experience
- type - The type of test (content, redirect, onsiteUpsell, etc.), or "personalization" for a personalization
- variations - At least one variation must be provided
Optional Fields
- audience — Audience targeting rules
- excludeCurrency — Currency/geo-based visitor targeting. When exclude is true, only visitors matching the given currency (ISO 4217 code) are included in the experience; everyone else is excluded. Set currency to null (with exclude: false) to disable.
Volume discounts
A volume discount (tieredDiscount) needs at least two tiers, the same as in the Intelligems app. For a single threshold, like buy 10, save 15%, send an amount off offer (cartDiscount) with one tier: its minimumUnits is the threshold, and discountApplicationMethod: "perItem" takes the discount off each item. One tier on a new volume discount returns a 400. An update can send back a one-tier volume discount the experience already has, as long as its tiers are unchanged.
Offer products
An offer covers every product unless its products lists the ones it applies to. Each entry is one product:
- id — The Shopify product id: the number the Shopify admin shows, or gid://shopify/Product/<n>. Titles, variants and prices are read from your store's catalog, so only ids are sent.
- set — buy (the default) for a product the offer applies to. On a Buy X Get Y offer, get lists the products shoppers get at the discount.
- variants — Optional. Leave it out to cover every variant, including ones added to the product later. List variants marked include to cover only those, or list variants marked exclude to cover every other variant.
The variation's includeProducts follows the list, so leave it out; a value that disagrees with the list returns a 400.
On a Buy X Get Y offer, bxgyGetProductScope says where the discounted units come from: null for the products shoppers buy, list for the get products, or all for any product. Sending get products without it sets list.
- An offer covers only the products it lists. There's no way yet to cover every product except a few, so list the products to include.
- A free shipping offer always covers the whole order and can't take a list.
- On a free gift offer, products is what shoppers buy to qualify, not the gift. The gift goes on a tier: isGiftWithPurchase: true and giftWithPurchaseProductId, the gift's product id: the number the Shopify admin shows, or gid://shopify/Product/<n>. A free gift with no gift tier returns a 400. See the free gift personalization example.
- A product id that isn't in your store's catalog, a variant of a different product, or a product with every variant excluded returns a 400.
- Read the list back with GET /experiences/{experienceId}/offer-products.
Onsite upsells
An onsite upsell recommends products on the product page or in the cart. It is one entry in a variation's components, and its config carries all of it: placement (where it renders: location pdp or cart, with either an anchorKey for the Intelligems Content theme block or a selector plus insertType; send location alone for the spot the app starts a new upsell with, right after the add-to-cart form on a product page or just above the cart footer), template (the HTML; omit it for the default), maxProductLimit, the exclusion flags, an optional discount, and rules. Each rule pairs an action (which products: shopifyRecommendations, a collection, a tag, or productId with the product objects listed, each with its variants, not bare ids) with a targeting (when it shows: a cart expression over the cart, or a product expression over the viewed product). Rules are tried in priority order; a rule with an empty expression always matches.
- A test carrying one has type: "onsiteUpsell". The control normally has no components; put the upsell on the variant.
- A personalization carries one on its one variation, with type: "personalization".
- The store needs a storefront access token (refresh its Shopify permissions in the app if it has none) and your plan needs the onsite upsell scope.
- A bundle (config.type bundleOnsiteUpsell) is in beta and can't be created here yet.
- A template may only reference the slots the renderer knows (product.image, product.url, product.title, product.price, product.compareAtPrice, atc, variant-select), with the per-product card between {{#each products}} and {{/each}}; one that references anything else is rejected.
- The cartTargeting and upsellProductRules seen on checkout blocks are not part of an onsite upsell: its rules and cart conditions live inside its config.
Personalizations
A personalization shows one experience to the visitors you target, with no control split. Send type: "personalization" with exactly one variation, the control at 100%, and an audience whose filter actions and elseAction are experienceInclude (show it), experienceExclude (hide it) or experienceUnassigned. The response comes back with category: "personalization".
- A personalization can carry content edits, custom CSS/JS, a URL, theme or template redirect, an onsite upsell, or one offer: amount off, volume discount, free shipping, free gift or buy X get Y. The offer takes products the same way an offer test does (see Offer products). When the variation has an offer the stored type is personalization/offer. Sending personalization/offer with a traffic split creates an offer test, not a personalization.
- A post-purchase upsell is added after the personalization exists, as a checkout block on its one variation. The store has to be set up for post-purchase upsells, and the personalization can't also carry an offer. Once the upsell is on, the audience is turned on and limited to the store's currency, as it is for a post-purchase test.
- A personalization can lower prices: send a negative priceChange on its one variation (e.g. "-10" with priceChangeUnit: "percent" for 10% off). Raising prices isn't supported on a personalization. The prices themselves are attached afterwards through the Intelligems MCP's price tools, as they are for a price test. A price change can't share a personalization with an offer, checkout blocks or an onsite upsell, and a store that runs price tests by duplicating products can't use it.
- An onsite upsell can't share a personalization with an offer, a price change or a checkout block.
- A theme redirect and a template redirect can't share one personalization. Page targeting is dropped when the personalization has a URL or theme redirect, since the redirect's originUrl already says where it applies.
- A theme redirect names its theme in queryParams: [{ "key": "preview_theme_id", "value": "<theme id>" }]. A template redirect names its template there too, and that is what the server checks: [{ "key": "view", "value": "<templateType>.<suffix>.json" }], with templateType set and templateSuffixes listing the template visitors are on and the one they're sent to. See the template personalization example.
- The API sets analyticsViewType from the personalization's content: test_orders_only (only the personalization's own orders, or for an offer limited to products, only orders containing those products) when it changes prices or its offer is limited to products, sitewide_orders (every store order) otherwise. A buy X get Y offer whose only products are the get ones still counts every order.
- Your plan needs the personalization scope.
Rate Limit: 50 requests per 30s window, refilling 25 tokens every 30s.
Request
- Base URLhttps://api.intelligems.io
- AuthAPI key in header intelligems-access-token
- TypeScriptA function with typed inputs. Its response is checked against the schema.
Request body
Response
OK
Changes
- breaking
added the new required request property
/////// - breaking
the request property
///became required - breaking
the
request property const valuepercentagewas added - breaking
removed the enum value
of the request property///// - breaking
removed the enum value
dollarof the request property/////// - breaking
removed the enum value
percentageof the request property/////// - breaking
request property
/list-of-types was narrowed by removing typesnullfrom media typeapplication/json - breaking
request property
/list-of-types was narrowed by removing typesnullfrom media typeapplication/json - breaking
request property
/////list-of-types was narrowed by removing typesnullfrom media typeapplication/json - breaking
request property
///////list-of-types was narrowed by removing typesnullfrom media typeapplication/json - breaking
request property
///////list-of-types was narrowed by removing typesnullfrom media typeapplication/json - breaking
request property
///////list-of-types was narrowed by removing typesnullfrom media typeapplication/json - breaking
request property
///////list-of-types was narrowed by removing typesnullfrom media typeapplication/json - breaking
request property
///////list-of-types was narrowed by removing typesnullfrom media typeapplication/json - breaking
request property
///////list-of-types was narrowed by removing typesnullfrom media typeapplication/json - breaking
request property
/////list-of-types was narrowed by removing typesnullfrom media typeapplication/json - breaking
request property
/////list-of-types was narrowed by removing typesnullfrom media typeapplication/json - breaking
request property
/////list-of-types was narrowed by removing typesnullfrom media typeapplication/json - breaking
request property
/////list-of-types was narrowed by removing typesnullfrom media typeapplication/json - breaking
request property
/////list-of-types was narrowed by removing typesnullfrom media typeapplication/json - breaking
request property
//////list-of-types was narrowed by removing typesstringfrom media typeapplication/json - breaking
request property
/////list-of-types was narrowed by removing typesnullfrom media typeapplication/json - breaking
request property
/////list-of-types was narrowed by removing typesnullfrom media typeapplication/json - breaking
the
///request property's minLength was increased from0to1 - breaking
the
/request property type changed fromobjectto no type - breaking
the response property
/became nullable for the status - breaking
the response property
///became nullable for the status - breaking
the response property
////became nullable for the status - breaking
the response property
/became nullable for the status - breaking
the response property
/became nullable for the status - breaking
the response property
//////became nullable for the status - breaking
the response property
/became nullable for the status - breaking
the response property
/became nullable for the status - breaking
the response property
/became nullable for the status - breaking
the response property
/became nullable for the status - breaking
the response property
/////became nullable for the status - breaking
the response property
///////became nullable for the status - breaking
the response property
///////became nullable for the status - breaking
the response property
///////became nullable for the status - breaking
the response property
///////became nullable for the status - breaking
the response property
///////became nullable for the status - breaking
the response property
///////became nullable for the status - breaking
the response property
/////became nullable for the status - breaking
the response property
/////became nullable for the status - breaking
the response property
/////became nullable for the status - breaking
the response property
/////became nullable for the status - breaking
the response property
/////became nullable for the status - breaking
the response property
/////became nullable for the status - breaking
the response property
/////became nullable for the status - breaking
the response property
///became nullable for the status - breaking
the response property
///became nullable for the status - breaking
the response property
/////became nullable for the status - breaking
the response property
/////became nullable for the status - breaking
the response property
/////////became nullable for the status - breaking
the response property
/////////became nullable for the status - breaking
the response property
///////became nullable for the status - breaking
the response property
///////became nullable for the status - breaking
the response property
///became nullable for the status - breaking
added
subschema #1subschema #2to the//response propertyoneOflist for the response status - breaking
added
subschema #1subschema #2subschema #3subschema #4subschema #5subschema #6to the////response propertyoneOflist for the response status - breaking
added
subschema #1subschema #2subschema #3subschema #4subschema #5subschema #6subschema #7subschema #8to the///response propertyoneOflist for the response status - breaking
the
/////////response's property type changed from no type tonumberstringnullfor status - breaking
the
/////////response's property type changed from no type tonumberstringnullfor status - breaking
removed the required property
///from the response with the status - breaking
removed the required property
///from the response with the status - breaking
removed the required property
///from the response with the status - warning
the
///////request property's exclusiveMinimum was set to0.00 - warning
the
///////request property's max was set to100.00 - warning
removed the request property
// - warning
removed the request property
// - warning
removed the request property
// - warning
removed the request property
// - warning
removed the request property
// - warning
removed the request property
// - warning
removed the request property
// - warning
removed the request property
///// - warning
removed the optional property
///from the response with the status - warning
removed the optional property
///from the response with the status - warning
added the new
MetaAdsenum value to the////response property for the response status - warning
added the new
UPSenum value to the////response property for the response status - warning
added the new
buyXGetYenum value to the/////response property for the response status - warning
added the new
gwpVariantPickerenum value to the/////response property for the response status - warning
added the new
gwpVariantPickerenum value to the//////response property for the response status - warning
added the new
netRevenueFromOnsiteUpsellenum value to the////response property for the response status - warning
added the new
netRevenueFromPostPurchaseOfferenum value to the////response property for the response status - warning
added the new
netRevenueFromUpsellenum value to the////response property for the response status - warning
added the new
onsiteUpsellenum value to the/response property for the response status - warning
added the new
pctOrdersWithOnsiteUpsellenum value to the////response property for the response status - warning
added the new
pctOrdersWithPostPurchaseOfferenum value to the////response property for the response status - warning
added the new
pctOrdersWithUpsellenum value to the////response property for the response status - warning
added the new
postPurchaseenum value to the/response property for the response status - warning
added the new
purchaseLikelihoodenum value to the/////////response property for the response status - warning
added the new
purchaseLikelihoodenum value to the/////response property for the response status - warning
added the new
purchaseLikelihoodenum value to the///////response property for the response status - info
api operation id
postExperiencewas added - info
added the new optional request property
/// - info
added the new optional request property
/ - info
added the new optional request property
/// - info
added the new optional request property
/// - info
added the new optional request property
/// - info
added the new optional request property
///// - info
added the new optional request property
///// - info
added the new optional request property
///// - info
added the new optional request property
/////// - info
added the new optional request property
///// - info
added the new optional request property
///// - info
added the new optional request property
/// - info
added the new optional request property
/// - info
added the new optional request property
/// - info
added the new optional request property
/// - info
added
subschema #1subschema #2to the/request propertyanyOflist - info
the request property
/became nullable - info
the request property
/became nullable - info
the request property
/////became nullable - info
the request property
///////became nullable - info
the request property
///////became nullable - info
the request property
///////became nullable - info
the request property
///////became nullable - info
the request property
///////became nullable - info
the request property
///////became nullable - info
the request property
/////became nullable - info
the request property
/////became nullable - info
the request property
/////became nullable - info
the request property
/////became nullable - info
the request property
/////became nullable - info
the request property
/////became nullable - info
the request property
/////became nullable - info
the request property
/////became optional - info
the request property
///////became optional - info
the request property
/////became optional - info
the request property
/////became optional - info
the
request property default valueUSDwas removed - info
the
request property default valuewas removed - info
the
request property default value$was removed - info
the
request property default valuewas removed - info
added the new
buyXGetYenum value to the request property///// - info
added the new
checkoutBlockenum value to the request property/ - info
added the new
netRevenueFromOnsiteUpsellenum value to the request property//// - info
added the new
netRevenueFromPostPurchaseOfferenum value to the request property//// - info
added the new
netRevenueFromUpsellenum value to the request property//// - info
added the new
onsiteUpsellenum value to the request property/ - info
added the new
pctOrdersWithOnsiteUpsellenum value to the request property//// - info
added the new
pctOrdersWithPostPurchaseOfferenum value to the request property//// - info
added the new
pctOrdersWithUpsellenum value to the request property//// - info
added the new
postPurchaseenum value to the request property/ - info
added the new
pricingenum value to the request property/ - info
added the new
purchaseLikelihoodenum value to the request property/////// - info
added the optional property
///to the response with the status - info
added the optional property
////to the response with the status - info
added the optional property
///to the response with the status - info
added the optional property
///to the response with the status - info
added the optional property
/////to the response with the status - info
added the optional property
/////to the response with the status - info
added the optional property
/////to the response with the status - info
added the optional property
/////to the response with the status - info
removed
subschema #1subschema #2from the/////////response propertyanyOflist for the response status - info
removed
subschema #1subschema #2from the/////////response propertyanyOflist for the response status - info
response property
experience/archivedAtTslist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/audience/anyOf[subschema #1]/evaluationFrequencylist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/audience/anyOf[subschema #1]/excludeCurrency/currencylist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/descriptionlist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/endedAtTslist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/experienceIntegrations/items/integration/apis/items/descriptionlist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/experienceProductTargeting/items/expression/anyOf[subschema #1]/items/query/valuelist-of-types was narrowed by removing typesnumberfrom media typeapplication/jsonof response200 - info
response property
experience/linkBaseUrllist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/pausedAtTslist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/previewPathlist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/startedAtTslist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/variations/items/offer/anyOf[subschema #1]/maximumDollarDiscountlist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/variations/items/offer/anyOf[subschema #1]/shippingDiscount/anyOf[subschema #1]/discountLabellist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/variations/items/offer/anyOf[subschema #1]/tiers/items/discountTitlelist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/variations/items/offer/anyOf[subschema #1]/tiers/items/giftWithPurchaseHandlelist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/variations/items/offer/anyOf[subschema #1]/tiers/items/giftWithPurchaseProductIdlist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/variations/items/offer/anyOf[subschema #1]/tiers/items/giftWithPurchaseTitlelist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/variations/items/offer/anyOf[subschema #1]/tiers/items/giftWithPurchaseVariantIdlist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/variations/items/onsiteEdits/items/createdAtTslist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/variations/items/onsiteEdits/items/createdAtUrllist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/variations/items/onsiteEdits/items/findlist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/variations/items/onsiteEdits/items/imageSearchUrllist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/variations/items/onsiteEdits/items/titlelist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/variations/items/onsiteInjections/anyOf[subschema #1]/customCsslist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/variations/items/onsiteInjections/anyOf[subschema #1]/customJslist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/variations/items/onsiteInjections/anyOf[subschema #1]/jsInjectionMode/timeoutlist-of-types was narrowed by removing typesstringfrom media typeapplication/jsonof response200 - info
response property
experience/variations/items/priceChangelist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/variations/items/priceRoundingAmountlist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/variations/items/redirects/items/destinationUrllist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/variations/items/redirects/items/findlist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/variations/items/shippingRateGroups/items/rates/items/descriptionlist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/variations/items/shippingRateGroups/items/rates/items/rateCodelist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
response property
experience/variations/items/testExperienceIdlist-of-types was narrowed by removing typesnullfrom media typeapplication/jsonof response200 - info
removed
subschema #1subschema #2from the////response propertyoneOflist for the response status - info
removed
subschema #1subschema #2subschema #3subschema #4subschema #5subschema #6subschema #7subschema #8from the///response propertyoneOflist for the response status - info
added the required property
/to the response with the status - info
added the required property
//to the response with the status - info
added the required property
//to the response with the status - info
added the required property
/////to the response with the status - info
added the required property
///////to the response with the status - info
added the required property
///////to the response with the status
- breaking