Skip to content
Guide

Replace a contract next year

Acme Building Supply (ACME-BUILD) pays 41.50 for the valve VLV-304 this year. From Jan 1, 2027 its new contract price is 39.90. Enter the new price today: this year's rule keeps applying until the end of Dec 31, and next year's takes over on Jan 1, with nothing to deploy.

Time zone

Dates are whole days in your workspace's time zone (Settings → Time zone), so Jan 1 starts at midnight there. Check it before you start.

In the dashboard

  1. 1

    End this year's rule

    In Customer Pricing, search for ACME-BUILD and edit "Acme contract 2026". Set Until to Dec 31, 2026 and save. It stays In effect until the end of that day.

  2. 2

    Add next year's rule

    Click Add Pricing Override: customer ACME-BUILD, product VLV-304, fixed price 39.90, the same minimum quantity and priority as this year's rule, and From Jan 1, 2027. Leave Until empty unless the contract already has an end date. Once saved it shows as Scheduled.

  3. 3

    Check the switch

    In the Pricing Sandbox, price ACME-BUILD and VLV-304 with As of set to Dec 31, 2026 (41.50, this year's rule), then to Jan 1, 2027 (39.90, next year's).

  4. 4

    Clean up later

    From Jan 1 this year's rule shows as Expired. It no longer applies, but it counts toward your plan until you delete it: filter the rules list by Expired.

By CSV

The same change from a file. A re-import updates the rule with the same customer, product, minimum quantity, priority and start date, and creates a rule for anything else, so one file can end this year's contract and add next year's.

pricing-rules.csvCSV
name,code,sku,type,value,minimum_quantity,priority,status,valid_from,valid_to
Acme contract 2026,ACME-BUILD,VLV-304,fixed,41.50,,1,true,,2026-12-31
Acme contract 2027,ACME-BUILD,VLV-304,fixed,39.90,,1,true,2027-01-01,
  • Row 1 has this year's rule's identity (no start date), so that rule is updated: it now ends on Dec 31, 2026.
  • Row 2 starts on Jan 1, 2027, a different start date, so it is a new rule, scheduled until then. Its blank valid_to means no end date.
  • Dates are YYYY-MM-DD only. On re-import a blank valid_to keeps the stored end date and "-" removes it.
  • A different valid_from in a file creates a new rule rather than moving the old one's start: that is what lets both contracts exist side by side.

How re-imports match rules

Check with the API

To confirm what an integration gets on the first day, send as_of with the request:

Price Jan 1, 2027 todayShell
curl -X POST https://pricerules.app/api/v1/pricing/resolve \
  -H "Authorization: Bearer $PRICERULES_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "ACME-BUILD",
    "products": [
      {
        "sku": "VLV-304",
        "quantity": 1
      }
    ],
    "as_of": "2027-01-01"
  }'
Node SDKTypeScript
import { PriceRules } from "pricerules";

const pricerules = new PriceRules({ apiKey: process.env.PRICERULES_API_KEY });

const { data } = await pricerules.resolve({
  customerId: "ACME-BUILD",
  products: [{ sku: "VLV-304", quantity: 1 }],
  asOf: "2027-01-01",
});

for (const item of data.items) {
  console.log(item.sku, item.final_price, item.applied_rule?.name, item.match_reason);
}
data.items[0] for as_of 2027-01-01JSON
{
"sku": "VLV-304",
"product_group": null,
"base_price": 48,
"quantity": 1,
"final_price": 39.9,
"applied_rule": {
"id": "rule_acme_vlv_2027",
"name": "Acme contract 2027",
"type": "fixed",
"value": 39.9,
"constraints": {
"minimum_quantity": null,
"valid_from": "2027-01-01",
"valid_to": null
},
"target": {
"customer": {
"type": "customer",
"code": "ACME-BUILD"
},
"product": {
"type": "sku",
"code": "VLV-304"
}
}
},
"match_reason": "MOST_SPECIFIC_RULE",
"pricing_summary": {
"savings": 8.1,
"message": "Customer saved 8.10 due to active pricing rules"
}
}

The response's as_of and time_zone say which day was priced, and applied_rule.constraints carries the rule's dates, so a portal can show "contract price until Dec 31".

Rule dates and as_of in the API reference