Skip to content
BLOG

Carrier Rate Shopping with FedEx, UPS and USPS APIs

By · October 6, 2026

shippingintegration

Rate shopping means asking the carriers what a specific shipment will cost, at the moment you are about to ship it, and then choosing between the answers. It sounds obvious. Most warehouses do not do it, because the alternative is easier: default to the carrier the floor is used to, use the service the customer selected at checkout, and move on.

That default is where the money goes. Not much on any single parcel, but consistently, on every parcel, in a direction nobody is measuring.

What rate shopping actually involves

The mechanics are straightforward. At the point of shipment, you have a package: dimensions, weight, origin and destination. You call the FedEx, UPS and USPS APIs with those details, each returns what it would charge across its services, and you select from the results.

The important word is “live”. Calling the carriers at the point of shipment, rather than once at setup, means the rate reflects current pricing and service availability. A rate table built six months ago is a snapshot of pricing that has since changed, and it cannot tell you that a particular service is unavailable to a particular destination today.

It also means the comparison is specific to the actual package. The cheapest carrier for a two-pound parcel going a short distance is frequently not the cheapest for a thirty-pound parcel crossing the country, and a default carrier cannot distinguish between them.

Compare every service tier, not just carriers

A common half-implementation compares carriers but only at one service level, usually ground. That leaves the more interesting comparisons out.

Comparing ground, expedited and freight options automatically, rather than defaulting to whichever carrier the warehouse is used to, surfaces cases that look counterintuitive. An expedited service from one carrier can undercut a ground service from another on certain lanes, particularly where dimensional weight is involved. You cannot find those cases by reasoning about them. You find them by asking.

Once the options are in front of you, selection becomes a rule rather than a judgement: the lowest-cost option that meets the delivery requirement is selected without a person choosing manually per order.

Delivery commitments change the arithmetic

Cheapest is only the right answer when the delivery promise is still met, which is why a rate comparison on its own is not enough.

If a customer has been promised a date, or a marketplace channel sets a delivery commitment, the selection has to consider which services can actually make it to that destination in time. A service that cannot meet the date is not a cheaper option; it is not an option. Transit expectations vary by lane and carriers revise their service definitions and guarantees over time, so check the current spec for the services you rely on rather than treating transit assumptions as fixed.

In practice this means the rule has two parts: filter to the services that meet the commitment for this destination, then take the lowest cost among those. Reversing the order produces shipments that are cheap and late.

Negotiated rates versus public rates

If you have negotiated rates with a carrier, rate shopping against public rates tells you very little. The comparison has to run against the rates you actually pay, which means the API credentials used for rating have to be the account with your negotiated pricing attached.

This catches people out in two ways. An integration built with test credentials, or with an account that does not carry the negotiated agreement, returns list pricing and makes a carrier look more expensive than it is for you. And negotiated agreements get renegotiated, so an integration that was validated once is worth re-checking after a contract change.

The useful consequence of rating live against your own account is that your negotiated discounts are reflected automatically in every comparison, without anyone maintaining a rate sheet.

Log every response, not just the winner

This is the part most implementations skip, and the part that pays off later.

Logging every carrier response for a shipment, rather than only the selected one, means you can answer questions afterwards. Why did this parcel go FedEx when the customer expected UPS? What did the other carriers quote that day? Did the cheapest service get excluded because it could not meet the date, or because it was not offered for that destination at all?

Without those records, every one of those questions becomes speculation. With them, it is a lookup. It also makes carrier performance reviewable: patterns in who wins which lanes are visible in the log, and that is the basis for a sensible renegotiation conversation.

Labels close the loop. Shipping labels are generated directly from the selected rate and carrier, with tracking numbers flowing back into the order record, so the shipment, the rate that was chosen and the tracking are all attached to the same order rather than living in a carrier portal.

Where this belongs in the system

Rate shopping touches the order, the pack and the shipment, so it belongs where those records already are.

Run inside the ERP, the rate call happens against the real pack data, the selection is written to the shipment record, and the tracking number lands on the order without a second system to reconcile. Run outside it, you have shipping data in one place and orders in another, and the join between them becomes someone’s weekly export.

The dependency worth being honest about is pack data. Rating needs real dimensions and weights, because a rate quoted against estimated dimensions is a guess, and dimensional weight adjustments are where that guess gets expensive. If your carton data is approximate, that is the first thing to fix, and it is custom ERP development work rather than integration work.

For a US consumer electronics brand, the shipping integration sits in the same ERP as the orders and inventory it serves, alongside marketplace channels integrated over APIs. Keeping shipping in the same system as the order is what makes the rate decision explainable after the fact.

Getting started

If you are shipping on a default carrier today, the first step is measurement rather than integration: rate a sample of recent shipments across carriers and services and see what the comparison would have chosen. That tells you whether this is worth building before you build it.

If it is, start with the rate call and the logging, and add automatic selection once you trust the comparison. Running the selection in advisory mode first, where it records what it would have chosen while people still decide, is a cheap way to validate the rules against real shipments.

We build this as shipping API integration inside the ERP, with every carrier response retained. Where it needs to extend across sales channels as well, that is marketplace integration work on the same records. If you want to work out what rate shopping would change for your shipment mix, get in touch with how you ship today.

Common questions

Why call the carriers per order instead of using a rate table?

A table is a snapshot. Rates, surcharges and service availability change, and availability depends on the destination. Calling at the point of shipment means the comparison reflects what is actually offered for that package to that address.

Does rate shopping always pick the cheapest carrier?

It picks the cheapest option that still meets the delivery requirement. If a service cannot make the committed date for that destination, price is not the deciding factor.

What should be logged from a rate call?

Every carrier response for the shipment, not only the winning one. Without the options that were rejected, you cannot explain later why a particular carrier was chosen.