1. The rate_quote object
Rate fields that need explaining
2. Get live rates
Request
A cross-border request that rates FedEx with an indirect signature and UPS with its defaults:
Response
200 with a rate_quote. Rates are sorted by total_in_account_currency ascending (so mixed-currency quotes sort correctly), then by delivery.days.
Partial failure is not failure. If at least one connection was attempted, the response is 200 and the failed connections appear in errors[]. If every connection fails, the response is still 200 with an empty rates[] and a populated errors[]. A non-2xx status is reserved for problems with the request itself (400), credentials (401, 403), or the implementer (5xx). This is the single most important difference from carrier-native APIs, where one carrier’s outage would otherwise take down checkout.
The fan-out, with one carrier missing the timeout_ms deadline:
Streaming (optional capability rates.stream)
POST /v1/rates with Accept: text/event-stream returns Server-Sent Events as carriers respond:
3. Retrieve a rate quote
4. Expiry and caching
expires_atis set by the implementer, no shorter than 15 minutes and SHOULD be 30 minutes. A carrier that publishes a shorter validity (Amazon Shipping’srequestToken) caps it.- Implementers MAY cache carrier responses. A cached rate MUST carry the cache age in
messages[](code: "rate_cached") and MUST NOT outlive the carrier’s own validity. - Rates are bound to their request. Purchasing
rate_...buys exactly the contacts (includingbill_to), billing, handling_units, order, customs declaration andrate.carrier_configsin the quote. To change anything, re-rate.
5. Rate mismatch at purchase
Carriers sometimes re-price at label time (dimensional reweighs, surcharges recalculated at ship time). On purchase:- If the label’s actual total is equal or lower, the purchase succeeds and the shipment records the actual amount.
- If it is higher by no more than
purchase.max_increase(default0), the purchase succeeds, and the shipment carries arate_adjustedmessage. - Otherwise the implementer MUST void the just-created label and return
422 carrier_error/rate_mismatchwitherror.details[0] = { quoted, actual }. The client re-rates or raisesmax_increase.
6. What rating MUST NOT do
- It MUST NOT create a shipment, reserve a tracking number, or charge money.
- It MUST NOT emit webhook events. Quotes are high-volume and noisy.
- It MUST NOT require
customs_declarationfor domestic shipments, ordimensionsfor flat-rate packaging. - It MUST NOT return a rate for a service that cannot carry an item’s
dangerous_goods.