Documentation

Pricing rules

Per-channel price overrides, promotions, and competitor-based dynamic pricing.

The base price for a SKU lives in Storefront. Channel listings often need a different price — to cover marketplace fees, run a channel-specific promo, or react to competitor pricing. Pricing rules express that translation.

Pricing rules

A pricing rule transforms the base price for a (channel, SKU) pair. Rules can scope by category, brand, or specific SKUs, and they layer — multiple matching rules apply in priority order.

GET/sales-channel/pricing/rulesJWT
List rules. Filter with ?channel=amazon.

POST/sales-channel/pricing/rulesJWT
Create or update a rule.

curl -X POST https://appengine.appmint.io/sales-channel/pricing/rules \
  -H "Authorization: Bearer $JWT" -H "orgid: $ORG" \
  -d '{
    "id": "amazon-fee-uplift",
    "name": "Cover Amazon referral fee",
    "channel": "amazon",
    "scope": { "type": "all" },
    "adjustment": { "type": "markup_percent", "value": 15 },
    "priority": 100,
    "active": true
  }'
FieldTypeDescription
channel*string

Channel ID — amazon, ebay, shopify, etc.

scope*object

What to apply to. { "type": "all" }, { "type": "category", "categoryId": "..." }, { "type": "brand", "brand": "..." }, { "type": "skus", "skus": [...] }.

adjustment*object

Transformation. markup_percent, markup_fixed, set_price, discount_percent, discount_fixed, match_competitor, floor, ceiling.

prioritynumber

Higher applies later. Use to layer category overrides on top of channel-wide rules.

activeboolean

Disable without deleting.

DELETE/sales-channel/pricing/rules/:ruleIdJWT
Delete.

Calculate a price

POST/sales-channel/pricing/calculate/:channelIdJWT

Resolve what the channel should charge for a product. Useful for previewing rule behavior before pushing.

curl -X POST https://appengine.appmint.io/sales-channel/pricing/calculate/amazon \
  -H "Authorization: Bearer $JWT" -H "orgid: $ORG" \
  -d '{"sku": "SKU-100", "price": 19.99, "cost": 8.00, "categoryId": "electronics"}'

Returns the calculated channel price plus the chain of rules that contributed.

POST/sales-channel/pricing/calculate/allJWT
Calculate across every connected channel in one call.

Push prices

POST/sales-channel/pricing/sync/:channelIdJWT

Push the calculated prices to the channel listings. Pass skus to target specific products, omit to sync everything.

curl -X POST https://appengine.appmint.io/sales-channel/pricing/sync/shopify \
  -H "Authorization: Bearer $JWT" -H "orgid: $ORG" \
  -d '{"skus": ["SKU-100", "SKU-200"]}'

Promotions per channel

A promotion is a time-bounded pricing rule with startsAt and endsAt:

{
  "id": "black-friday-amazon",
  "name": "Black Friday — Amazon only",
  "channel": "amazon",
  "scope": { "type": "all" },
  "adjustment": { "type": "discount_percent", "value": 20 },
  "priority": 200,
  "active": true,
  "startsAt": "2026-11-27T00:00:00Z",
  "endsAt": "2026-11-30T23:59:59Z"
}

The pricing service activates and deactivates the rule automatically on its boundaries. Pair with POST /sales-channel/pricing/sync/:channelId to push the new prices when the promo opens.

Competitor-driven pricing

Save observed competitor prices and reference them in rules.

POST/sales-channel/pricing/competitorJWT
Record a competitor price.
GET/sales-channel/pricing/competitor/:skuJWT
Read all competitor prices for a SKU.
GET/sales-channel/pricing/compare/:skuJWT
Full comparison across master, channels, and competitors.

A match_competitor adjustment uses the lowest stored competitor price as the target, optionally floored at cost+margin:

{
  "adjustment": {
    "type": "match_competitor",
    "undercutPercent": 1,
    "minMarginPercent": 15
  }
}

The rule undercuts the lowest competitor by 1%, but never drops below 15% margin over cost.

Price history

GET/sales-channel/pricing/history/:skuJWT

Audit log of price changes per SKU. Filter by ?channel=amazon&limit=50.

Pricing rules are stored per org and evaluated at calculation time, not at write time. Updating a rule changes future calculations but does not retroactively re-push live channel prices — call POST /sales-channel/pricing/sync/:channelId after rule changes.