Platform Overview
Quantaprice answers one question: "what is the right price for this SKU, for this customer, right now?" It answers it correctly and in under 10 milliseconds at p99, however deep your pricelist hierarchy, however many rules and bundles you have. Any past price can be looked up again with as_of.
This page introduces the building blocks and how they combine into the price you get back.
Core Entities
Articles (SKUs)
An Article is the catalog record for a product: its SKU code, display name, and a metadata map (key → list of values) for any attributes relevant to your business, such as brand, category or product line. Price rules can use article metadata to target product segments without touching any pricelist.
An Article can also be a bundle: a SKU made up of component SKUs and quantities. How a bundle is priced is set per pricelist; see Bundles.
Pricelists
A Pricelist is a pricing context: its currency, whether its prices include VAT (GROSS) or not (NET), its metadata, its price rules, and an optional parent pricelist. Every pricelist sets its own currency and VAT mode.
Pricelists form a tree: each has at most one parent. A pricelist without its own price for a SKU inherits its parent's price, and its own rules apply to that price, so discounts on several levels compound: 10 % off on a segment and another 10 % off on a customer under it turn 100 into 81. A price set on the pricelist itself always takes precedence. See Inheritance.
Prices
A Price binds a SKU to a Pricelist. It holds one or more named price fields, such as fixed, cost or catalog, and optionally quantity breaks. Without price rules, the fixed field is the sales price; with rules, the rules compute the sales price from the fields.
Every price has a start date. Writing a new price keeps the previous one as history; a query selects the version in force at its as_of (default: now). A price with a future start date is a scheduled change and takes effect on its own. See Scheduled Updates and Historical Pricing.
Price Rules
Price rules are CEL expressions on a pricelist, such as prices.cost * 1.35 or sales * 0.9. An optional filter on article metadata decides which articles a rule applies to. The first matching rule sets the sales price. Because rules live on the pricelist, one rule covers every SKU on it. See Price Rules.
Bundles
A bundle's price on a pricelist comes from its bundle rule:
sum_of_parts: the sum of each component's price on that pricelist times its quantity, optionally with a percentage or absolute discount. A customer with negotiated component prices automatically gets a bundle price built from them.fixed: an explicit price, whatever the components cost. VAT is still computed per component, so bundles with mixed VAT classes are taxed correctly.
Currencies and Exchange Rates
Each pricelist holds prices in one currency. A query can ask for any currency; prices are converted with the exchange rate in force at the query's as_of. Rates come from the European Central Bank's daily feed, with EUR as the base, and you can also set your own. See Exchange Rates.
VAT
VAT is determined by three entities:
- Tax Areas: jurisdictions, for example
SE,DE,US-CA. A query names the tax area whose VAT applies. - VAT Classes: product tax categories, for example
STANDARD,REDUCED,EXEMPT. Each article has a VAT class per tax area, so a product can be standard-rated in one country and reduced-rated in another. - VAT Rates: the percentage for a (tax area, VAT class) pair, with start dates so rate changes can be scheduled.
A new tenant comes with currencies and a VAT baseline already set up. See VAT.
Rounding
Rounding profiles round the final price by price range, optionally with a charm offset such as -0.01 for prices ending in .99. A profile can be the global default, the default for a currency, or chosen per request. See Rounding.
Entity Relationships
┌────────────────────────────┐
│ Pricelist │
│ code, currency, vat_mode │
│ parent_code (→ Pricelist) │
│ price_rules (CEL[]) │
└──────────┬─────────┬────────┘
│ │
has prices ────┘ └──── bundle rules
│
┌────▼─────┐
│ Price │
│ sku ────┼──► Article (SKU)
│ fields │ │
│ breaks │ │ VAT class per tax area
│ start │ ▼
└──────────┘ ┌──────────────┐
│ Tax Area │
│ VAT Class │◄── VAT Rate (rate, start)
└──────────────┘
Currency ◄── FX Rate (EUR base, ECB daily, by date)
Rounding Profile (tier ranges, charm offset) ── global, per currency, or per request
How a Price Is Calculated
Every price you get back is built in the same order:
- Price rules: the pricelist's rules applied to the price fields give the sales price, in the pricelist's own currency.
- Currency conversion: if the query asks for another currency, the price is converted with the exchange rate in force at
as_of. - VAT: the article's VAT class in the query's tax area gives the VAT rate in force at
as_of. On aNETpricelist VAT is added; on aGROSSpricelist it is extracted. - Rounding: the applicable rounding profile rounds the final amount.
Rules come first because they are written in the pricelist's own currency. Conversion comes before VAT so tax is computed on the amount in the currency you show. Rounding comes last so it applies to the number your customer sees.
When a query selects several pricelists that price the same SKU, all candidates are compared excluding VAT in the requested currency, and the lowest wins. Each result also lists the pricelist's quantity breaks, converted and with VAT, so you can apply the right one for an order quantity. See Querying Prices.
Tracking Changes
Every change to your data can be read from a change log, by polling with a cursor, so your other systems stay in step. Webhooks, which push changes to you as they happen, depend on your plan. See Change Events.
Learn more
- Querying Prices: how to call the price API.
- Price Rules: writing rules and when they take effect.
- Bundles: bundle rules and the component breakdown.
- VAT: tax areas, VAT classes and article VAT classes.
- Rounding: rounding profiles.
- API Reference: every endpoint.