Pricing & CPQ
Configure pricing with base prices, price groups, lookup tables, unique modular prices, and variables. Build formulas that combine pricing blocks with mathematical operators. Calculate real-time prices based on user selections.
Pricing Block Types
base-price — Fixed starting price (one per project)
price-group — Logical folder for grouping pricing items
price-table — Lookup table mapping selections to price adjustments
unique-price — Enterprise Modular quantity lookup with per-column default fallback
variable — Named numeric parameter (e.g. width, quantity)
List Pricing Blocks
GET/projects/:id/pricing-blocks
const response = await fetch(BASE_URL + '/projects/proj_123/pricing-blocks', {
headers: { 'Authorization': 'Bearer ' + accessToken }
});
const data = await response.json();
// {
// "success": true,
// "blocks": [
// { "id": "pb_1", "type": "base-price", "name": "Base Price",
// "basePrice": 499.99, "baseCurrency": "USD", "enabled": true },
// { "id": "pb_2", "type": "variable", "name": "Width",
// "variableKey": "width", "variableDefaultValue": 120,
// "variableMin": 80, "variableMax": 200, "variableStep": 10, "variableUnit": "cm" },
// { "id": "pb_3", "type": "price-table", "name": "Material Upcharge",
// "tableColumns": [
// { "id": "col_1", "label": "Material", "type": "option-ref" },
// { "id": "col_2", "label": "Price", "type": "number" }
// ],
// "tableRows": [
// { "id": "row_1", "cells": { "col_1": "oak", "col_2": 0 }, "priceAdjustment": 0 },
// { "id": "row_2", "cells": { "col_1": "walnut", "col_2": 89 }, "priceAdjustment": 89 },
// { "id": "row_3", "cells": { "col_1": "marble", "col_2": 299 }, "priceAdjustment": 299 }
// ]
// },
// { "id": "pb_4", "type": "unique-price", "name": "Connect Full Wall Unique Price",
// "uniquePriceModularBlockId": "blk_roof_parts",
// "uniquePriceVariantId": "mod_connect_full_wall",
// "uniquePriceColumnOptionBlockId": "blk_treatment",
// "uniquePriceQuantities": [1, 2],
// "uniquePriceCellPrices": { "1::natural": 249, "2::natural": 699 },
// "uniquePriceDefaultCellPrices": { "natural": 399, "painted": 549 }
// }
// ]
// }Create Pricing Block
POST/projects/:id/pricing-blocks
// Create a variable for "Width" dimension
const response = await fetch(BASE_URL + '/projects/proj_123/pricing-blocks', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + accessToken,
'Content-Type': 'application/json'
},
body: JSON.stringify({
type: 'variable',
name: 'Width',
variableKey: 'width',
variableDefaultValue: 120,
variableMin: 80,
variableMax: 200,
variableStep: 10,
variableUnit: 'cm'
})
});Update Pricing Block
PUT/projects/:id/pricing-blocks/:blockId
// Update a price table with new rows
const response = await fetch(BASE_URL + '/projects/proj_123/pricing-blocks/pb_3', {
method: 'PUT',
headers: {
'Authorization': 'Bearer ' + accessToken,
'Content-Type': 'application/json'
},
body: JSON.stringify({
tableRows: [
{ id: 'row_1', cells: { col_1: 'oak', col_2: 0 }, priceAdjustment: 0 },
{ id: 'row_2', cells: { col_1: 'walnut', col_2: 120 }, priceAdjustment: 120 },
{ id: 'row_new', cells: { col_1: 'carbon-fiber', col_2: 450 }, priceAdjustment: 450 }
]
})
});Set Pricing Formula
PUT/projects/:id/pricing-formula
Define the formula that combines pricing blocks. Uses token-based format with block references, numbers, and operators.
const response = await fetch(BASE_URL + '/projects/proj_123/pricing-formula', {
method: 'PUT',
headers: {
'Authorization': 'Bearer ' + accessToken,
'Content-Type': 'application/json'
},
body: JSON.stringify({
formulaTokens: [
{ type: 'block', blockId: 'pb_1' }, // @Base_Price
{ type: 'operator', value: '+' },
{ type: 'block', blockId: 'pb_3' }, // @Material_Upcharge
{ type: 'operator', value: '+' },
{ type: 'paren', value: '(' },
{ type: 'block', blockId: 'pb_2' }, // @Width
{ type: 'operator', value: '*' },
{ type: 'number', value: '2.5' }, // per-cm cost
{ type: 'paren', value: ')' }
]
// Human readable: @Base_Price + @Material_Upcharge + (@Width * 2.5)
})
});Calculate Price
POST/projects/:id/pricing-blocks/calculate
Calculate the final price given a set of option block selections and variable values.
const response = await fetch(BASE_URL + '/projects/proj_123/pricing-blocks/calculate', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + accessToken,
'Content-Type': 'application/json'
},
body: JSON.stringify({
selections: {
dropdownSelections: { 'blk_wood': 'walnut' },
selectMaterialSelections: {},
checkboxSelections: { 'blk_accessories': ['cup-holder'] },
toggleSwitchSelections: { 'blk_armrests': 'with' },
carouselSelections: {}
},
variables: {
width: 160,
quantity: 2
}
})
});
const data = await response.json();
// {
// "success": true,
// "basePrice": 499.99,
// "adjustments": [
// { "blockId": "pb_3", "blockName": "Material Upcharge", "amount": 120 },
// { "blockId": "pb_2", "blockName": "Width", "amount": 400 }
// ],
// "totalPrice": 1019.99,
// "currency": "USD",
// "subtotal": 1019.99,
// "tax": 203.998,
// "totalWithTax": 1223.988,
// "taxRate": 20,
// "taxMode": "exclusive",
// "taxLabel": "VAT",
// "taxEnabled": true,
// "formatted": "$1,223.99",
// "formattedSubtotal": "$1,019.99",
// "formattedTax": "$204.00"
// }Continue reading
Contact FormsBuild and read contact forms and their 12 field types for lead capture and add-to-cart flows.3D ViewerDrive the 3D viewer — camera, lighting, scene presets, and runtime configuration selections.AnimationsCreate and play animation blocks: move, rotate, float, scale-pulse, swing, and orbit.Project SettingsRead and update the 140+ project settings covering display, branding, AR, e-commerce, email, and PDF.
