Simplio3D

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