Bundles
The 15 tools of the Bundles toolset in the Catalog area, with their permissions, approval rules and inputs.
Ezen az oldalon
Toolset bundles, 15 tools.
Records
bundle
A product bundle: a fixed set sold at one price, or an offer attached to a product, collection or category (add-on, frequently bought together, buy X get Y). Rows carry items, groups and the discount. Filter by product_id for the bundles linked to one product.
- Permission:
products.read - Tools:
bundle_list,bundle_get - Written by customers or third parties, so data and never instructions:
title,heading,subtext,badge_text
Filters on the list:
| Filter | Type | Required | Description |
|---|---|---|---|
status | string | one of "draft", "active", "inactive" | |
mode | string | one of "add_on", "fixed", "fbt", "bxgy" | |
product_id | string | Only the bundles linked to this product |
bundle_contribution_policy
The variable cost, fee and profit floor of one bundle in one currency. Rows carry the revision bundle_contribution_policy_set needs. A bundle without a policy returns nothing.
- Permission:
products.read - Tools:
bundle_contribution_policy_list
Filters on the list:
| Filter | Type | Required | Description |
|---|---|---|---|
bundle_id | string | yes | |
currency_code | string | yes | ISO 4217 currency code, e.g. huf |
bundle_cost_policy
What a variant costs you in one currency and the margin or profit floor bundles must keep above it. Rows carry the revision bundle_cost_policy_set needs. Variants without a policy are left out.
- Permission:
products.read - Tools:
bundle_cost_policy_list
Filters on the list:
| Filter | Type | Required | Description |
|---|---|---|---|
variant_ids | list of string | yes | 1 to 50 items |
currency_code | string | yes | ISO 4217 currency code, e.g. huf |
bundle_quantity_rule
The minimum, maximum and step quantity a variant can be bought in, as the bundle editor shows it next to a component quantity. One row per variant that has a rule.
- Permission:
products.read - Tools:
bundle_quantity_rule_list
Filters on the list:
| Filter | Type | Required | Description |
|---|---|---|---|
variant_ids | list of string | yes | 1 to 200 items |
bundle_rule
The cost and margin rules bundles are held to, either per item (kind item) or per bundle. Rows are complete records.
- Permission:
products.read - Tools:
bundle_rule_list
Filters on the list:
| Filter | Type | Required | Description |
|---|---|---|---|
kind | string | item by default. one of "item", "bundle" | |
currency_code | string | ISO 4217 currency code, e.g. huf |
Actions
bundle_contribution_policy_set
Save the variable cost, fee and profit floor of a bundle in one currency.
expected_revision comes from bundle_contribution_policy_list; use 0 when the bundle has no policy yet.
- Action key:
bundle_contribution_policy.set - Permission:
products.write - Approval: Waits for approval when the store requires it for this action.
- Effect: Changes the live store.
- Retries: safe to repeat with the same input.
| Field | Type | Required | Description |
|---|---|---|---|
bundle_id | string | yes | |
currency_code | string | yes | ISO 4217 currency code, e.g. huf |
expected_revision | integer | yes | at least 0 |
variable_cost | number | Packing and handling cost per bundle. at least 0 | |
fee_percent | number | Payment and platform fee on the bundle price. 0 to 99.99 | |
minimum_margin_percent | number | 0 to 99.99 | |
minimum_profit | number | at least 0 | |
enforce_contribution | boolean | Refuse prices below the floor | |
expires_at | string or null | format date-time |
Example input:
{
"bundle_id": "019bb1bc-889f-7ac7-9d08-13a449bd1bba",
"currency_code": "huf",
"expected_revision": 0,
"variable_cost": 500,
"fee_percent": 2.9
}bundle_cost_policy_set
Save the cost and margin floor of variants, many at once.
Up to 50 policies per call, one per variant and currency. Each needs the expected_revision from bundle_cost_policy_list so a concurrent change is not overwritten.
- Action key:
bundle_cost_policy.set - Permission:
products.write - Approval: Waits for approval when the store requires it for this action.
- Effect: Changes the live store.
- Retries: safe to repeat with the same input.
| Field | Type | Required | Description |
|---|---|---|---|
policies | list of object | yes | 1 to 50 items |
policies[].variant_id | string | yes | |
policies[].currency_code | string | yes | ISO 4217 currency code, e.g. huf |
policies[].expected_revision | integer | yes | The revision from bundle_cost_policy_list; 0 when the variant has no policy yet. at least 0 |
policies[].cost | object, one shape of: | yes | |
policies[].cost[source=manual].source | string | yes | always "manual" |
policies[].cost[source=manual].amount | number or null | yes | Cost of one unit; null clears it. at least 0 |
policies[].cost[source=estimated].source | string | yes | always "estimated" |
policies[].cost[source=estimated].net_price | number | yes | at least 0 |
policies[].cost[source=estimated].gross_margin_percent | number | yes | Typical gross margin on the net price. 0 to 99.99 |
policies[].minimum_margin_percent | number | 0 to 99.99 | |
policies[].minimum_profit | number | at least 0 | |
policies[].enforce_bundle_floor | boolean | Refuse bundle prices below the floor | |
policies[].expires_at | string or null | format date-time |
Example input:
{
"policies": [
{
"variant_id": "019bb7f3-10ac-7f8b-b47e-f5cd71dff2e1",
"currency_code": "huf",
"expected_revision": 0,
"cost": {
"source": "manual",
"amount": 2500
},
"minimum_margin_percent": 10
}
]
}bundle_create
Create a product bundle or an offer attached to products.
Percentage discounts need discount_percentage, free gifts need max_free_gift_items, fixed prices need fixed_prices (or fixed_price with its currency), and buy-X-get-Y needs both quantities. Non-fixed bundles need product_id, or target_kind with target_id. Items may be empty when a group is filled from a collection or category.
- Action key:
bundle.create - Permission:
products.write - Approval: Waits for approval when the store requires it for this action.
- Effect: Changes the live store.
- Retries: runs at most once; a repeat with the same idempotency key returns the first result.
| Field | Type | Required | Description |
|---|---|---|---|
title | string | yes | at least 1 characters |
mode | string | fixed: one bundle product; add_on, fbt and bxgy attach to product_id or a target. one of "add_on", "fixed", "fbt", "bxgy" | |
status | string | one of "draft", "active", "inactive" | |
product_id | string | Anchor product of add_on, fbt and bxgy bundles | |
bundle_product_id | string | The product a fixed bundle is sold as | |
target_kind | string or null | Attach the offer to every product of a collection or category. one of "collection", "category" | |
target_id | string or null | ||
discount_type | string | one of "percentage", "free_gift", "fixed_price" | |
discount_percentage | integer or null | 0 to 100 | |
fixed_price | number or null | Fixed bundle price, one currency. at least 0 | |
fixed_price_currency_code | string or null | ||
fixed_prices | list of object | Fixed prices per currency; takes the place of fixed_price. at most 50 items | |
fixed_prices[].currency_code | string | yes | |
fixed_prices[].amount | number | yes | at least 0 |
bxgy_buy_quantity | integer or null | at least 1 | |
bxgy_get_quantity | integer or null | at least 1 | |
allow_free_gift_selection | boolean | ||
max_free_gift_items | integer or null | at least 1 | |
heading | string or null | at most 120 characters | |
subtext | string or null | at most 500 characters | |
badge_text | string or null | at most 40 characters | |
display_style | string | one of "theme", "list", "cards", "expandable" | |
recommendation_settings | object or null | ||
recommendation_settings.strategy | string | one of "balanced", "profit", "price" | |
recommendation_settings.selection | string | one of "recommended", "customer" | |
recommendation_settings.suggestions | integer | 1 to 6 | |
recommendation_settings.rotate | boolean | ||
groups | list of object | at most 50 items | |
groups[].id | string | Existing group id (updates only) | |
groups[].label | string | yes | 1 to 120 characters |
groups[].min_distinct | integer | yes | 0 to 100 |
groups[].max_distinct | integer | yes | 1 to 100 |
groups[].source | object or null | Fill the group from a collection or category instead of listing items | |
groups[].source.kind | string | yes | one of "collection", "category" |
groups[].source.id | string | yes | |
groups[].source.excluded_product_ids | list of string | at most 100 items | |
groups[].source.compatibility_key | string or null | Handle of the attribute a candidate must share with the anchor product | |
items | list of object | yes | at most 100 items |
items[].product_id | string | yes | |
items[].variant_id | string or null | A single variant; leave out for any | |
items[].quantity | integer | yes | 1 to 100 |
items[].is_optional | boolean | The customer may leave this item out | |
items[].group_index | integer or null | Position in groups of the selection group the item belongs to. at least 0 | |
items[].group_id | string or null | Id of an existing group (updates only) |
Example input:
{
"title": "Console starter pack",
"mode": "fixed",
"discount_type": "percentage",
"discount_percentage": 10,
"items": [
{
"product_id": "019bb58e-0ec1-79c1-9f40-d39d8d07674b",
"quantity": 1
},
{
"product_id": "019bb596-4f49-7df2-8e43-087dbab6350c",
"quantity": 2
}
]
}bundle_delete
Delete a bundle.
The products in it stay.
- Action key:
bundle.delete - Permission:
products.write - Approval: Always waits for a person to approve it.
- Effect: Changes the live store.
- Destructive: in compact mode it runs with
run_destructive_action. - Retries: safe to repeat with the same input.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | Bundle id |
Example input:
{
"id": "019bb1bc-889f-7ac7-9d08-13a449bd1bba"
}bundle_economics_preview
Work out the price, cost and margin of a bundle without saving anything.
source saved takes variant ids and reads their stored cost policies; source inline takes the unit price and cost of every line yourself. The answer says whether the discount keeps the margin and profit floors.
- Action key:
bundle_economics.preview - Permission:
products.write - Approval: Runs without approval.
- Effect: Reads only.
- Retries: safe to repeat with the same input.
Takes no input.
Example input:
{
"source": "saved",
"currency_code": "huf",
"lines": [
{
"id": "a",
"variant_id": "019bb7f3-10ac-7f8b-b47e-f5cd71dff2e1",
"quantity": 1,
"unit_price": 9000
}
],
"discount": {
"type": "percentage",
"value": 10
}
}bundle_product_link
Link a fixed bundle to the product it is sold as.
- Action key:
bundle_product.link - Permission:
products.write - Approval: Waits for approval when the store requires it for this action.
- Effect: Changes the live store.
- Retries: safe to repeat with the same input.
| Field | Type | Required | Description |
|---|---|---|---|
bundle_id | string | yes | Bundle id |
product_id | string | yes | Product id |
Example input:
{
"bundle_id": "019bb1bc-889f-7ac7-9d08-13a449bd1bba",
"product_id": "019bb58e-0ec1-79c1-9f40-d39d8d07674b"
}bundle_product_unlink
Remove the link between a fixed bundle and its product.
- Action key:
bundle_product.unlink - Permission:
products.write - Approval: Always waits for a person to approve it.
- Effect: Changes the live store.
- Destructive: in compact mode it runs with
run_destructive_action. - Retries: safe to repeat with the same input.
| Field | Type | Required | Description |
|---|---|---|---|
bundle_id | string | yes | Bundle id |
product_id | string | yes | Product id |
Example input:
{
"bundle_id": "019bb1bc-889f-7ac7-9d08-13a449bd1bba",
"product_id": "019bb58e-0ec1-79c1-9f40-d39d8d07674b"
}bundle_recommendation_preview
Show which products a bundle would suggest next to a product, without saving anything.
- Action key:
bundle_recommendation.preview - Permission:
products.write - Approval: Runs without approval.
- Effect: Reads only.
- Retries: safe to repeat with the same input.
| Field | Type | Required | Description |
|---|---|---|---|
bundle_id | string | yes | |
product_id | string | yes | The product the shopper is looking at |
region_id | string | yes | Region the prices are taken from |
variant_id | string |
Example input:
{
"bundle_id": "019bb1bc-889f-7ac7-9d08-13a449bd1bba",
"product_id": "019bb58e-0ec1-79c1-9f40-d39d8d07674b",
"region_id": "019bb66a-289f-7fbe-ad8d-cd924c882647"
}bundle_update
Replace the definition of a bundle.
This replaces the whole bundle: send every field you want to keep, title and items included. Read the current definition with bundle_get first and change what you need.
- Action key:
bundle.update - Permission:
products.write - Approval: Waits for approval when the store requires it for this action.
- Effect: Changes the live store.
- Retries: safe to repeat with the same input.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | Bundle id |
title | string | yes | at least 1 characters |
mode | string | fixed: one bundle product; add_on, fbt and bxgy attach to product_id or a target. one of "add_on", "fixed", "fbt", "bxgy" | |
status | string | one of "draft", "active", "inactive" | |
product_id | string | Anchor product of add_on, fbt and bxgy bundles | |
bundle_product_id | string | The product a fixed bundle is sold as | |
target_kind | string or null | Attach the offer to every product of a collection or category. one of "collection", "category" | |
target_id | string or null | ||
discount_type | string | one of "percentage", "free_gift", "fixed_price" | |
discount_percentage | integer or null | 0 to 100 | |
fixed_price | number or null | Fixed bundle price, one currency. at least 0 | |
fixed_price_currency_code | string or null | ||
fixed_prices | list of object | Fixed prices per currency; takes the place of fixed_price. at most 50 items | |
fixed_prices[].currency_code | string | yes | |
fixed_prices[].amount | number | yes | at least 0 |
bxgy_buy_quantity | integer or null | at least 1 | |
bxgy_get_quantity | integer or null | at least 1 | |
allow_free_gift_selection | boolean | ||
max_free_gift_items | integer or null | at least 1 | |
heading | string or null | at most 120 characters | |
subtext | string or null | at most 500 characters | |
badge_text | string or null | at most 40 characters | |
display_style | string | one of "theme", "list", "cards", "expandable" | |
recommendation_settings | object or null | ||
recommendation_settings.strategy | string | one of "balanced", "profit", "price" | |
recommendation_settings.selection | string | one of "recommended", "customer" | |
recommendation_settings.suggestions | integer | 1 to 6 | |
recommendation_settings.rotate | boolean | ||
groups | list of object | at most 50 items | |
groups[].id | string | Existing group id (updates only) | |
groups[].label | string | yes | 1 to 120 characters |
groups[].min_distinct | integer | yes | 0 to 100 |
groups[].max_distinct | integer | yes | 1 to 100 |
groups[].source | object or null | Fill the group from a collection or category instead of listing items | |
groups[].source.kind | string | yes | one of "collection", "category" |
groups[].source.id | string | yes | |
groups[].source.excluded_product_ids | list of string | at most 100 items | |
groups[].source.compatibility_key | string or null | Handle of the attribute a candidate must share with the anchor product | |
items | list of object | yes | at most 100 items |
items[].product_id | string | yes | |
items[].variant_id | string or null | A single variant; leave out for any | |
items[].quantity | integer | yes | 1 to 100 |
items[].is_optional | boolean | The customer may leave this item out | |
items[].group_index | integer or null | Position in groups of the selection group the item belongs to. at least 0 | |
items[].group_id | string or null | Id of an existing group (updates only) |
Example input:
{
"id": "019bb1bc-889f-7ac7-9d08-13a449bd1bba",
"title": "Console starter pack",
"mode": "fixed",
"discount_type": "percentage",
"discount_percentage": 15,
"items": [
{
"product_id": "019bb58e-0ec1-79c1-9f40-d39d8d07674b",
"quantity": 1
}
]
}