Scheduling
Developer Guide
Set it up once. It switches automatically.
Carrier rates aren't static. Peak season surcharges, promotional free shipping weekends, new-year tariff increases, planned carrier downtime — every ecommerce business faces moments where shipping rates need to change on a specific date and revert on another. Managing this manually means logging in at midnight, hoping you don't forget, and logging back in again to switch it back.
ShipRateAPI's Scheduling feature lets you configure those changes in advance. Every rate table has a validFrom and validTo datetime window. When a quote request is received, the quote service filters rate tables in SQL against the quote datetime and automatically includes or excludes each table — no manual intervention required.
You can have your entire Christmas pricing setup prepared weeks in advance. The moment the window opens, customers start seeing peak-period rates. The moment it closes, standard rates resume — automatically, reliably, at exactly the second you specified.
How scheduling works
Every rate table has two optional datetime fields that define its active window. A table with no window set is always eligible. A table with both fields set is only evaluated when the current datetime falls within the range — inclusive of both bounds.
| Field | Type | Behaviour |
|---|---|---|
validFrom | ISO 8601 datetime | Table becomes eligible at this datetime (inclusive). Null = no lower bound. |
validTo | ISO 8601 datetime | Table expires at this datetime (inclusive). Null = no upper bound. |
Both fields are stored as naive datetimes — no timezone is retained — and are compared against the current UTC datetime. Express your windows in UTC. A Z suffix is safe (2024-12-25T00:00:00Z) only because a zero offset changes nothing when it is dropped. Do not use a non-zero offset: 2024-12-25T00:00:00+01:00 is stored as 00:00:00 and behaves as midnight UTC, not midnight BST — the offset is discarded, not converted. To schedule midnight BST, convert it yourself and store 2024-12-24T23:00:00.
A window on its own isn't enough
The window is only one of the conditions a rate table has to satisfy. Every one of the following must also hold before a table contributes a rate — a schedule on a disabled table never activates, however correct its dates are.
- The rate table is enabled —
isActivemust be true on the table itself. Disabling a table removes it from every quote regardless of its window. - Its carrier is enabled —
isActivemust also be true on the carrier the table belongs to. Disabling a carrier removes every one of its scheduled tables along with it. - Both windows contain the quote datetime — carriers have their own
validFromandvalidTo, and the carrier's window is checked alongside the table's. A perfectly scheduled table still returns nothing if its carrier's window excludes the date.
The validFrom / validToreported on each rate in the quote response are the table's window, falling back to the carrier's when the table has none.
What you can do with scheduling
Scheduling applies to any rate type, any carrier, and any zone — which makes it one of the most versatile features in ShipRateAPI. Any rate table can be given a window, and multiple scheduled tables can coexist in the same zone. Windows are not required to be mutually exclusive — nothing validates them against each other. If two windows overlap, both tables match and both rates are returned, ordered by your quote strategy.
- Peak season surcharges — create a rate table with higher amounts and set a
validFrom/validTowindow covering the peak delivery period. Your standard table'svalidToshould close just before the peak window opens. When the window closes, standard rates resume without any action on your part. - Promotional free shipping — set a
freerate table with a window covering a sale weekend or campaign period. When the window ends, standard tables resume automatically — no risk of forgetting to turn it off. - Planned tariff increases — prepare next year's rates now by creating new rate tables with a
validFromset to the date the new tariff takes effect. Both tables sit in the admin simultaneously; only the correct one is ever evaluated. No last-minute changes, no midnight logins. - Carrier downtime windows — temporarily deactivate a carrier's rate table during a known maintenance or non-collection window without deleting any configuration.
- Flash sale shipping — limited-time flat-rate or free shipping offers for specific hours. Set a tight window and the offer is live precisely when you need it.
Example — Christmas / Thanksgiving surcharge window
The most common scheduling pattern: a standard rate table that covers most of the year, a peak-period table that takes over during the holiday season, and the standard table resuming in the new year. Aim for windows that meet exactly: a gap leaves the carrier with no rate at all, while an overlap is accepted and returns both tables' rates side by side. Examples shown for UK, US, and EU carriers.
UK — Royal Mail Tracked 48
// Standard — active all year except the Christmas window
{
"name": "Royal Mail Tracked 48 — Standard",
"type": "weight",
"validFrom": null,
"validTo": "2024-12-14T23:59:59Z"
}
// Christmas surcharge — Royal Mail peak period pricing
{
"name": "Royal Mail Tracked 48 — Christmas",
"type": "weight",
"validFrom": "2024-12-15T00:00:00Z",
"validTo": "2025-01-05T23:59:59Z"
}
// Standard resumes in January
{
"name": "Royal Mail Tracked 48 — Standard",
"type": "weight",
"validFrom": "2025-01-06T00:00:00Z",
"validTo": null
}US — UPS Ground
// Standard — active all year except peak season
{
"name": "UPS Ground — Standard",
"type": "weight",
"validFrom": null,
"validTo": "2024-11-24T23:59:59Z"
}
// Peak surcharge — UPS applies peak fees Thanksgiving through New Year
{
"name": "UPS Ground — Holiday Peak",
"type": "weight",
"validFrom": "2024-11-25T00:00:00Z",
"validTo": "2025-01-05T23:59:59Z"
}
// Standard resumes after peak period
{
"name": "UPS Ground — Standard",
"type": "weight",
"validFrom": "2025-01-06T00:00:00Z",
"validTo": null
}EU — DHL Paket
// Standard — active all year except Christmas window
{
"name": "DHL Paket — Standard",
"type": "weight",
"validFrom": null,
"validTo": "2024-12-15T23:59:59Z"
}
// Christmas surcharge — DHL peak period across DE / AT / CH
{
"name": "DHL Paket — Weihnachten",
"type": "weight",
"validFrom": "2024-12-16T00:00:00Z",
"validTo": "2025-01-06T23:59:59Z"
}
// Standard resumes after Epiphany
{
"name": "DHL Paket — Standard",
"type": "weight",
"validFrom": "2025-01-07T00:00:00Z",
"validTo": null
}validTo and the peak table's validFrom don't meet exactly, there will be a period where neither is eligible and the zone returns no rates. The Coverage Scanner flags an expiring table with no replacement scheduled, and a quoteDate quote lets you check any changeover datetime directly.Testing a schedule before it goes live
You don't have to wait until December to find out whether the windows above behave the way you intended. A quote request takes an optional quoteDate — the datetime that scheduled rate tables and carriers are evaluated against. It defaults to now and accepts an ISO 8601 date or datetime.
POST /api/v1/quotes
x-api-key: YOUR_API_KEY
{
"quoteDate": "2024-12-20T14:30:00",
"destination": {
"country": "GB",
"postcode": "SW1A 1AA"
},
"items": [
{
"sku": "WIDGET-001",
"quantity": 1,
"unitPrice": 4999,
"weight": 2.5
}
]
}Every scheduled table and carrier is evaluated against that datetime, so the rates you get back are the rates that date would produce — and the response echoes the quoteDateit used. It also forms part of the cache key, so a test quote never returns another date's cached result or displaces it.
Setting schedules in the admin portal
validFrom and validTo are set per rate table under Carriers → Rate Tables → Edit. Both fields accept a date and time picker. Leave a field blank to set it to null — no lower or upper bound.
After saving any scheduled change, run the Coverage Scannerover your zones. Its schedule check warns when an active table's validTo falls within the next 30 days and no other active table for the same zone and carrieris scheduled to pick up (a gap of up to a day is tolerated), and when a carrier's window expires before one of its rate tables.
Scheduling works with every other feature
- Any rate type can be scheduled — schedule a
freetable for a promotional weekend, aflattable during a delay period, or aconfigurablepipeline for peak-season complexity. - Combine with tag routing — schedule a carrier restriction for tagged products during specific periods. Exclude a standard carrier from
dangerous-goodsorders only during the Christmas period when specialist handling is required. - Validate with the Coverage Scanner — run the Coverage Scanner after configuring scheduled windows. Its schedule check is narrow: an active table expiring within the next 30 days with no successor scheduled for the same zone and carrier, and a carrier expiring before its own rate table. It does not check windows for overlaps. To confirm coverage at any other point in the period, send a quote with
quoteDateset to that datetime.