Bundles
A bundle is a SKU sold as a single unit but composed of multiple component SKUs. Quantaprice prices bundles deterministically and integrates them into the standard pricing pipeline — a bundle price is read exactly like any other price, with no special handling by the caller.
A bundle is defined at the article/catalog level (its component list), while its pricing rule is defined per pricelist and follows the normal inheritance hierarchy.
Defining a bundle
A bundle article carries a list of components, each a (sku, quantity):
{
"sku": "BUNDLE-START-KIT",
"components": [
{ "sku": "COMP-A", "quantity": 2 },
{ "sku": "COMP-B", "quantity": 1 }
]
}
Validation:
- At least one component.
- Each component quantity is positive (fractional quantities allowed).
- A component cannot be the bundle itself.
- A component cannot itself be a bundle (no nesting).
- A component article must already exist.
Pricing methods
The bundle's price on a pricelist is determined by its bundle pricing rule (method):
sum_of_parts
The price is the sum of each component's effective price × its quantity, optionally adjusted by a discount:
base = Σ ( component.quantity × effectivePrice(component) )
discount_type = "percentage" → price = base × (1 − discount_value/100)
discount_type = "absolute" → price = base − discount_value (never below 0)
none → price = base
effectivePrice(component) resolves each component using normal pricelist inheritance (the
component's own price on this pricelist, else inherited from a parent). So a customer with negotiated
component prices automatically gets a bundle priced from their component prices.
fixed
The bundle has an explicit fixed_price; component prices do not affect it. The response still
includes a per-component VAT breakdown (derived proportionally from the components) so tax is
computed correctly across mixed VAT classes.
Inheritance
The rule is inherited, not the resolved price. Resolving a bundle rule for a pricelist:
- If the pricelist has its own bundle rule, use it.
- Otherwise inherit the rule from the nearest parent pricelist that has one.
- For
sum_of_parts, component prices are then resolved at the requesting pricelist level (which itself follows normal inheritance).
A child pricelist may override the rule (switch method, change the discount, set a fixed price). There are no per-component overrides at the pricelist level — components are defined on the article.
Scheduling
Bundle pricing is time-aware. Both rules and component prices can be future-dated, and the bundle reflects them automatically at the scheduled moment — no manual activation.
- Scheduled fixed price — set a
fixedrule with a futureeffective_from; the bundle switches to that price at that time. - Scheduled discount / method change — schedule a future
sum_of_partsdiscount change (e.g. 10% today, 25% from Black Friday) or a method switch. - Scheduled component prices — a future-dated price change on any component (its own or inherited) is reflected in the bundle from the moment it takes effect.
Bundle prices show scheduled changes up to 90 days or 25 changes ahead, whichever comes first.
Changes further out still take effect on time, but a query with an as_of beyond that window does
not show them yet.
Historical pricing
Because each change produces a new effective-dated version, bundle prices support "as of" evaluation for past dates just like regular prices.
Reading a bundle price
A bundle price is requested and returned exactly like a regular price, with is_bundle: true and
a per-component breakdown in bundle:
{
"sku": "BUNDLE-START-KIT",
"is_bundle": true,
"sales_price_ex_vat": 180.00,
"sales_price_inc_vat": 225.00,
"vat_amount": 45.00,
"vat_rate": 25.0,
"price": { "pricelist": "RETAIL", "currency_code": "SEK", "sales": 180.00, "fields": {}, "quantity_breaks": [], "meta": { "inherited": false } },
"bundle": [
{ "sku": "COMP-A", "quantity": 2, "price": 120.00, "vat_rate": 25.0, "vat_amount": 30.00, "pricelist": "RETAIL" },
{ "sku": "COMP-B", "quantity": 1, "price": 60.00, "vat_rate": 25.0, "vat_amount": 15.00, "pricelist": "RETAIL" }
]
}
bundle is present only for bundles. Each component entry reports the pricelist its price comes
from and its own VAT, since VAT is computed per component; bundles with mixed VAT classes are taxed
correctly.
If a sum_of_parts component cannot be resolved anywhere in the hierarchy, the bundle is treated as
unavailable (no price) rather than returning a partial sum.
Bundle Rules API
Bundle rules are managed under /bundle-rules.
Set or update a rule
PUT /bundle-rules/{bundleSku}/{pricelistCode}
{
"method": "sum_of_parts",
"discount_type": "percentage",
"discount_value": 10,
"effective_from": "2026-11-27T00:00:00Z"
}
{
"method": "fixed",
"fixed_price": "499.00"
}
effective_from is optional and defaults to now; a future value schedules the rule. The rule
applies to this pricelist and to the pricelists below it that have no bundle rule of their own.
Validation: discount_value is 0–100 for percentage and ≥ 0 for absolute; fixed_price is
required and ≥ 0 for fixed.
Get the effective rule
GET /bundle-rules/{bundleSku}/{pricelistCode}
Returns the rule effective now, resolving inheritance up the parent chain. The response includes
inherited: true|false, the method, discount/fixed fields, and effective_from.
List rule versions
GET /bundle-rules/{bundleSku}
Lists every pricelist/version that has an explicit rule for the bundle.
Remove a rule
DELETE /bundle-rules/{bundleSku}/{pricelistCode}?effective_from=...
Removes a rule version (defaults to the version effective now). The bundle then inherits from the parent, or becomes unavailable if no rule remains anywhere in the hierarchy.
See also
- Pricelist Inheritance — how bundle rules are inherited through the pricelist hierarchy.
- VAT — how per-component VAT is resolved for bundles with mixed VAT classes.
- Querying Prices — reading bundle prices via the query API.
- API Reference — full spec for the
/bundle-rulesendpoints.
Summary
Bundles are SKUs composed of component SKUs, priced per pricelist by an inherited rule
(sum_of_parts with an optional discount, or a fixed price). Rules and component prices are
time-aware, so fixed prices, discounts, and component price changes can all be scheduled and are
reflected automatically. A bundle price is queried like any other price and comes with a
per-component breakdown.