Docs menu

Reference

REST API

Prices

What a customer pays for a SKU at a quantity, and exactly which rule set that price.

TradeCatalog works out every customer price in one place, the same way for the app, the trade portal, MCP and the API. You never calculate prices yourself.

How prices are worked outLink to this section#

The most specific rule wins, and discounts never stack:

  1. Agreed price. If the customer has an agreed (fixed) price for the product, that’s the price.
  2. Otherwise the list price minus one percentage, the first that applies:
    1. the customer’s discount for the product’s category
    2. the customer’s discount for the product’s brand
    3. the customer’s own account discount
  3. Otherwise the list price.

A category rule of 10% and an account discount of 5% give 10% off, not 15%.

The discounted unit price is rounded half up to a whole minor unit. The line total is unit × qty, so a line never has fractions of a penny.

List prices and agreed prices are versioned by date. The API always gives the price valid now. Future prices from a scheduled price change apply from their date.

The price objectLink to this section#

Every product’s price has this shape. GET /prices returns the same fields at the top level of data.

json
{
  "unit": 1573,
  "line": 15730,
  "list": 1850,
  "discountBp": 1500,
  "source": "brand",
  "label": "Brand discount −15%"
}
FieldTypeDescription
unitinteger or nullPrice for one unit, in minor units. null if the product has no price.
lineinteger or nullunit × qty.
listinteger or nullThe list price now.
discountBpintegerThe discount applied, in basis points. 0 for agreed and list prices.
sourcestringWhich rule set the price: see below.
labelstringWording buyers see next to the price.
sourceMeaningExample label
fixedThe customer’s agreed priceAgreed price
categoryCategory discountCategory discount −12.5%
brandBrand discountBrand discount −15%
accountThe customer’s own discountYour discount −5%
listList price, no discount(empty)
unpricedThe product has no price yet(empty)

Check a customer priceLink to this section#

GET/api/v1/prices

What a customer pays for one SKU at a quantity, and why. Use it to answer “what does Oakfield pay for 10 boxes of HX-8510?”.

NameTypeRequiredDescription
customerstringyesCustomer id or account code.
skustringyesThe SKU, ignoring case.
qtyintegerno1 to 1,000,000. Default 1.
bash
curl "https://tradecatalog.app/api/v1/prices?customer=OAK01&sku=HX-8510&qty=10" \
  -H "Authorization: Bearer $TRADECATALOG_API_KEY"
js
const params = new URLSearchParams({
  customer: 'OAK01',
  sku: 'HX-8510',
  qty: '10',
})
const res = await fetch(`https://tradecatalog.app/api/v1/prices?${params}`, {
  headers: { Authorization: `Bearer ${process.env.TRADECATALOG_API_KEY}` },
})
const { data: price, currency } = await res.json()
json
{
  "data": {
    "customer": {
      "id": "7d2e4f0a-1b3c-4d5e-8f90-a1b2c3d4e5f6",
      "accountCode": "OAK01",
      "name": "Oakfield Joinery"
    },
    "sku": "HX-8510",
    "name": "Hex bolt M10 x 50 zinc",
    "qty": 10,
    "unit": 1573,
    "line": 15730,
    "list": 1850,
    "discountBp": 1500,
    "source": "brand",
    "label": "Brand discount −15%"
  },
  "currency": "GBP"
}
StatusCodeWhen
400validation_errorcustomer or sku missing, or qty out of range.
404not_foundNo such customer, or no product with that SKU.

This endpoint checks the price only. It doesn’t check whether the customer can see the product. For that, use GET /products/{id}?customer=….

Prices for many productsLink to this section#

To price a whole page of products for one customer, use GET /products?customer=OAK01. Every row’s price is that customer’s price, and customer-only products for other customers are left out. See Products.

Changing pricesLink to this section#

  • List prices change through price changes, so customers get notice. Send new prices with PUT /products; they go into a draft that you publish in the app.
  • Discounts and agreed prices are set per customer in the app. Read them with GET /customers/{id}.
  • A customer’s account discount can be set with PUT /customers (discountBp).