Features

Everything behind one B2B pricing API.

The rules engine, CSV imports and the API your portal, quoting tool or integration calls. Each section starts with a problem B2B projects run into, shows how PriceRules handles it, and links to the docs.

Pricing rules engine

Contract prices and volume breaks as rules, not if-statements.

The problem
Contract prices, account discounts and quantity breaks end up hard-coded in checkout code or kept in per-customer spreadsheets, so changing one means hunting down every copy.
How PriceRules handles it
Every price adjustment is a rule: a fixed unit price, a percentage discount, or a fixed amount off the base price. A rule is for specific customers, a customer group or everyone, and for specific SKUs, a product group or all products. Rules can require a minimum quantity and carry a priority.
  • Customer groups and product groups: put customers and products in a group once (by hand, in bulk or from a CSV column), and one rule covers every member, including ones added later.
  • Rules are tried in 9 scopes, most specific first: this SKU before the product's group before all products, and on each, this customer before the customer's group before everyone. The first scope with a rule that applies sets the price. Without groups, that leaves four scopes: 1, 3, 7 and 9, in that order.
  • Within a scope, the highest qualifying minimum quantity wins — that's how volume breaks work. An amount off larger than the price is skipped, and the next rule applies.
  • Contract dates: give a rule a start and an end date, and it takes over on its first day and stops after its last, in your time zone. Enter next year's prices today; there's nothing to deploy.
  • Priorities, then the later start date, then the lowest price, settle any remaining tie, so the same input always gets the same price.
  • Rules can be paused without being deleted; inactive rules are never applied.

Why it matters: One rule change updates the price everywhere it's requested, and anyone can see which rule produced a price.

How customer-specific rule matching works
Pricing rules · sample workspace
RuleCustomerProductEffect
Acme volume price 100+ACME-BUILDVLV-304fixed $39.50, 100+ units
Acme contract priceACME-BUILDVLV-304fixed $42.00
Contractor fastener priceGroup CONTRACTORSGroup FASTENERS12% off
Nordic account discountNORDIC-FABAll10% off
Trade discountAllAll5% off

For ACME-BUILD buying 120 × VLV-304 (base $48.00), the 100+ volume price applies: $39.50 per unit.

CSV imports & validation

Bring existing price lists in without cleaning them by hand first.

The problem
Pricing data lives in exports and spreadsheets with inconsistent headers, decimal formats and the odd typo — and a bad row shouldn't silently produce a bad price.
How PriceRules handles it
Import products, customers and pricing rules from CSV. PriceRules suggests a column mapping and validates every row before saving anything: if a row is wrong, nothing is saved and each rejected row comes back with a specific reason.
  • Accepts common number formats such as 12.5, 12,5, 1,750.00 and 1.750,00.
  • Rules must reference existing customers, SKUs and groups, so typos are caught instead of creating rules that never match.
  • A group column puts customers and products in groups as they're imported, creating the groups it names.
  • Large files are processed in the background in batches; a failed import can be retried without saving rows twice.
  • Plan capacity is checked before rows are saved, so an import can't push you past your limits.

Why it matters: You can move an existing spreadsheet-driven process into PriceRules in an afternoon and know exactly which rows need fixing.

Read the CSV import reference
Import validation · illustrative result

1,240

Rows read

1,237

Valid

3

Rejected

  • Row 4SKU: Product not found
  • Row 9VALUE: Invalid
  • Row 12PRICING_RULE: Duplicate in import

Messages shown are real validation messages from the import reference; the counts are an example.

Pricing API

Resolve one SKU or a whole cart in one request.

The problem
Each application that shows or charges a price needs the customer's price — and reimplementing the rules in every codebase is how they drift apart.
How PriceRules handles it
Send a customer code and a list of SKUs with quantities. PriceRules returns the final unit price for each line, the rule that was applied, why it matched, and how much of your monthly quota remains.
  • Single resolution: up to 500 SKUs for one customer per request.
  • Bulk resolution: up to 10 customers per request, each with up to 500 SKUs.
  • A best_price mode returns the lowest qualifying price instead of the most specific rule.
  • Every response says whether the customer was found. An unknown or deleted customer code still gets prices (rules for everyone), flagged with CUSTOMER_NOT_FOUND.
  • Responses name the customer's group and each product's group, and say whether the winning rule was for the customer, its group or everyone.
  • Authenticated with workspace API keys. One error format with documented codes for invalid input, over-limit requests, rate limits and quota, and a request id to quote to support; unknown SKUs come back per line, not as an error.

Official Node SDK

  • TypeScript types
  • 0 dependencies
  • Node 18+ · Edge

Typed responses, retries where they're safe, and a timeout. Node 18+ and edge runtimes.

server.tsTypeScript
// npm install pricerules
const { data } = await pricerules.resolve({
  customerId: "ACME-BUILD",
  products: [{ sku: "VLV-304", quantity: 120 }],
});

Why it matters: Developers integrate once; pricing changes after that are made in PriceRules, not in code.

Open the API reference
RequestJSONPOST /api/v1/pricing/resolve
{
  "customer_id": "ACME-BUILD",
  "products": [
    {
      "sku": "VLV-304",
      "quantity": 120
    }
  ]
}
ResponseJSON200 OK · sample data
{
  "mode": "business",
  "success": true,
  "data": {
    "customer": {
      "id": "ACME-BUILD",
      "found": true,
      "group": "CONTRACTORS"
    },
    "warnings": [],
    "items": [
      {
        "sku": "VLV-304",
        "product_group": "VALVES",
        "base_price": 48,
        "quantity": 120,
        "final_price": 39.5,
        "applied_rule": {
          "id": "rule_acme_vlv_100",
          "name": "Acme volume price 100+",
          "type": "fixed",
          "value": 39.5,
          "constraints": {
            "minimum_quantity": 100,
            "valid_from": null,
            "valid_to": "2026-12-31"
          },
          "target": {
            "customer": {
              "type": "customer",
              "code": "ACME-BUILD"
            },
            "product": {
              "type": "sku",
              "code": "VLV-304"
            }
          }
        },
        "match_reason": "MOST_SPECIFIC_RULE",
        "pricing_summary": {
          "savings": 8.5,
          "message": "Customer saved 8.50 due to active pricing rules"
        }
      }
    ]
  },
  "billing": {
    "limit": 2000,
    "usage": 194,
    "remaining": 1806
  },
  "meta": {
    "request_id": "req_…",
    "processing_ms": "…"
  }
}

Pricing sandbox

Check a price before a customer sees it.

The problem
When a price looks wrong, someone has to work out which spreadsheet, override or code path produced it.
How PriceRules handles it
The in-app pricing sandbox resolves any customer, SKU and quantity with your live rules and shows a calculation trace — the base price, the rule that was applied, and the resulting unit and total price — without using your API quota.
  • Same resolution logic as the API.
  • Useful for verifying a new import or rule before your applications rely on it.
  • Onboarding can load a sample dataset so you can try it before importing your own data.

Why it matters: Pricing questions get answered by looking at the rule, not by debugging an integration.

Getting started guide
How the winning rule was found · sample data
Customer
ACME-BUILD
SKU
VLV-304
Quantity
120
  1. 1This customer + this SKUAcme volume price 100+ → $39.50
  2. 2This customer's group + this SKUnot needed
  3. 3Everyone + this SKUnot needed
  4. 4This customer + this product's groupnot needed
  5. 5This customer's group + this product's groupnot needed
  6. 6Everyone + this product's groupnot needed
  7. 7This customer + all productsnot needed
  8. 8This customer's group + all productsnot needed
  9. 9Everyone + all productsnot needed

Usage, limits & access

Know where you stand on volume, capacity and access.

The problem
Usage-based pricing APIs are hard to budget for when you can't see consumption until something stops working.
How PriceRules handles it
The usage page shows monthly price resolutions and workspace capacity against your plan. Workspace owners get an email at 90% and at 100% of the monthly resolution quota.
  • Each product line resolved counts as one resolution, for single and bulk requests alike.
  • Per-minute rate limits by plan (20 to 1,000 requests per minute), with Retry-After headers.
  • Multiple API keys per workspace on paid plans, with an activity log of key, product, customer and rule changes.

Why it matters: Usage is visible before it becomes a problem, and every change to pricing data is traceable.

See limits by plan
Usage · illustrative
Price resolutions this month1,820 / 2,000
Pricing rules74 / 200
Products61 / 100

Meters use the Free plan's real limits; usage figures are an example.

Call the API with your own data.

Start on the Free plan, import a few products, customers and rules, and resolve prices over the API or in the sandbox.

Free planNo credit card