Shipping API Integration: Rates, Labels and Tracking Across Carriers

31 Oct, 2026
19 min read

Shipping API integration connects your store, order management system or warehouse software to carriers so you can fetch live rates, buy labels and receive tracking updates without anyone copying data between screens. You can connect to each carrier's own API directly, or to an aggregator (multi-carrier) API that gives you one interface to many carriers.

Most of the pages that rank for this topic are carrier or aggregator documentation, which explains one product well but not the decision in front of you. This guide covers that decision and when a ready-made shipping app is enough. The rest deals with the design choices that decide whether the integration holds up once real orders flow through it.

What a shipping integration has to do

Whatever route you take, the integration usually covers five steps:

  1. Validate the address before you quote or buy anything.
  2. Get rates for the parcel's weight, dimensions, origin and destination, across the services you offer.
  3. Buy a label for the chosen rate, and store the tracking number and label file.
  4. Track the parcel until delivery, and update the order and the customer.
  5. Handle the exceptions: voided labels, returns, failed deliveries and customs paperwork for international shipments.

Aggregator APIs follow the same shape. In Shippo's documented flow, for example, you create a shipment with from and to addresses and parcels, the response lists available rates, and calling the transaction endpoint with a chosen rate purchases the label.

Direct carrier APIs vs aggregator APIs

This is the first decision, and it shapes the rest of the build.

Direct carrier APIs Aggregator (multi-carrier) API
What you integrate One API per carrier, each with its own auth, data model and error codes One API that translates to many carriers
Carrier coverage Only the carriers you build Whatever the aggregator supports
Features Full access to carrier-specific services and options Common features first; niche options may lag or be missing
Rates Your account's rates with each carrier Your own carrier accounts, the aggregator's rates, or both, depending on the provider
Ongoing work You track every carrier's API changes and retirements The aggregator absorbs most carrier changes
Dependency On each carrier On the aggregator as well as the carriers
Cost model Development and maintenance time Usually per-label or subscription fees, plus less development

Carrier APIs do change underneath you. USPS, for example, retired its Web Tools API platform on January 25, 2026 and pointed users to its newer USPS APIs. With direct integrations, migrations like that land on your team. With an aggregator, they mostly land on the aggregator.

A rough rule: start with an aggregator if you ship standard parcels with mainstream carriers and want to go live quickly. Go direct when you need carrier features an aggregator does not expose, when you ship enough volume that per-label fees matter, or when a regional or freight carrier is not covered. Many teams mix the two: an aggregator for most parcels and one direct connection for a carrier that matters.

Custom integration or a ready-made shipping app

Ecommerce platforms and shipping software vendors sell ready-made apps that connect a store to carriers with little or no code. These apps also give staff a screen for printing labels and handling returns. Some store platforms build this in, and Shopify merchants can buy and print shipping labels from the Shopify admin.

A ready-made app usually fits when:

  • Orders come from one store platform, or from channels the app already supports.
  • You ship ordinary parcels with a few carriers and pick rates by simple rules.
  • Staff print labels in batches from the app's own screen.

A custom ecommerce shipping API integration usually fits when:

  • Orders come from several systems, such as a store, an ERP and a B2B portal, and shipping has to behave the same way for all of them.
  • Your rate rules, packing logic or carrier mix go beyond what the app lets you configure.
  • Shipping status has to drive other systems, such as customer emails and marketplace tracking uploads, with the failure handling described later in this guide.
  • Your volume is high enough that per-label or per-user fees cost more than owning the integration.

There is also a middle path, where the rules live in a shipping tool and your code calls them. ShipStation lets operations staff set up custom rate rules in its own screens, and the API then calls each rule by its ID. Staff can change a rule without a code release, but the rule is then tied to that vendor.

A useful check before you commit to a product is to run your own edge cases through a test account. Return labels are a good example. Shippo's scan-based return labels work only on USPS, FedEx and UPS, and only with the same carrier as the outbound shipment. A seller who ships through a regional carrier cannot use them, so the returns section below covers the alternative.

Many teams start with an app and move to a custom build once one of these limits costs them money or staff time. The limit that triggered the move is worth recording, because the new build should be tested against it.

Design one contract for every carrier

Whether you go direct or not, put your own interface in front of the carriers. Your order system should ask for "rates for this shipment" and "buy this rate," not speak UPS, FedEx or an aggregator's format directly.

A useful shipping contract usually defines:

  • Shipment: addresses, parcels (weight and dimensions with explicit units), declared value, reference numbers.
  • Rate: carrier, service, price, currency, estimated delivery, and an ID you can use to buy it.
  • Label: tracking number, label file or URL, format, cost.
  • Tracking event: a status from your own list (for example: label created, in transit, out for delivery, delivered, exception) plus the carrier's raw status for reference.
  • Error: a small set of categories your code can act on, such as invalid address, service unavailable, auth failure, carrier down.

Then write one connector per carrier or aggregator that maps to and from that contract. Keep request mapping, response parsing and HTTP transport separate inside each connector. That way you can test the mapping with recorded responses and no live carrier call.

A detail that catches teams out: carrier responses do not all return the same fields. When you save a purchased label, merge the response into the shipment you already have. Do not overwrite it, or a carrier that omits parcel weight in its response will wipe the weight you already recorded.

Rate shopping and carrier selection rules

Rate shopping means requesting rates from several carriers for the same shipment and choosing one of them. Aggregators make the request itself simple. ShipStation's API returns rates for one or more carrier accounts in a single call. Your code can pick a service from the response or show the options to the buyer at checkout. EasyPost can limit rating to the carrier accounts you name.

The harder part is the rule that picks the winning rate, because the cheapest rate is rarely the whole rule. A selection rule usually applies its checks in this order:

  • Services that cannot carry the parcel because of its size, weight or contents, such as hazardous goods, drop out.
  • Services that cannot deliver to the address, such as a PO box or an area the carrier does not serve, drop out.
  • Services whose estimated delivery date misses the date promised at checkout drop out.
  • Business rules apply next, such as a preferred carrier for a region or a customer who requires a named carrier.
  • The lowest cost among the services left wins, with a set tie-breaker for equal prices.

Providers can run part of this rule for you. For US domestic shipments, ShipStation's API typically tags the first rates as best value, cheapest and fastest. It sorts the list from cheapest to most expensive.

Its custom Rate Shopper rules go further. A rule can limit services to a delivery estimate within a set number of business days. Any service without a carrier estimate is then left out. A rule can also prefer a service whose price is within a set amount of the cheapest. When nothing matches, the API returns a 404 error with the message "Rate Shopper could not find a matching service." Checkout needs a planned answer for that error, such as a wider rule or a default carrier.

The rate a customer sees at checkout and the label bought later often come from different calls. EasyPost has a rates endpoint that returns prices without creating a shipment, for showing or comparing rates. EasyPost lists it as a beta feature that is subject to change, so its status is worth checking before checkout depends on it. The rates it returns carry no IDs. To buy a label, you create a shipment and name one of its rates. When the service is already known, EasyPost's one-call buy creates the shipment and buys the label in one request. An order that waits days before packing should be rated again at label time and the price compared with the checkout quote.

Each shipment should store the chosen rate, the reason it won and the rates it beat. Provider responses supply most of that record. An EasyPost rate includes the delivery days and whether the delivery date is guaranteed. It also shows retail and list prices beside the rate itself. The record answers the customer who asks why a parcel was slow and the finance team that asks why shipping costs rose. The rule itself is easier to audit when it lives in one configuration that your operations team can read. When a carrier is down, the rule chooses from the carriers that answered, as the section on carrier downtime below describes.

Address validation

Bad addresses cause failed deliveries, carrier correction fees and support tickets, so validate early:

  • At checkout, to let the customer fix a typo while they are still there.
  • Before rating, so you quote for the right zone and residential or commercial status.
  • Before label purchase, as a last check for orders imported from other channels.

Decide what happens when validation suggests a change. For B2B shipments to known sites, you may accept the stored address. For new consumer addresses, you might ask the customer to confirm. Keep the original and the corrected version so you can explain any later problem.

Tracking: webhooks vs polling

There are two ways to get tracking updates, and most production setups use both.

Webhooks push updates to you. Shippo's documentation says it automatically creates a tracking webhook when you buy a label through it, and that you can expect updates within two hours of an event, with timing varying by carrier. EasyPost sends events by HTTP POST to your configured URL, signs them with an HMAC signature in the X-Hmac-Signature header, and warns that endpoints which repeatedly return failures may be automatically disabled.

That last point matters. If your webhook endpoint goes down for a while, you may stop getting updates without any error on your side. Verify every signature, return a success code quickly and do the processing in a background job, and monitor the subscription itself.

Polling asks the carrier or aggregator for status on a schedule. It is slower and uses more API calls, but it does not depend on someone else reaching your server. A sensible pattern is webhooks for speed, plus a scheduled job that polls any parcel which has not had an update for longer than you would expect.

Either way, treat tracking events as possibly duplicated or out of order. Store each event, and only move the shipment status forward if the new event is later than the last one you recorded.

Carrier downtime, retries and idempotent label purchase

Carrier APIs time out and go down. Plan for it in three places.

Rating. Call carriers in parallel with a short timeout. If one carrier fails, show the rates you have instead of failing the whole checkout. Some teams keep stored rate tables as a fallback for quoting, clearly marked as estimates.

Label purchase. This is the step where retries can cost money. If a purchase request times out, you do not know whether the label was bought. Retrying blindly can buy two labels. To make purchase safe to retry:

  • Give each purchase attempt a unique key and store it before calling out. Use the provider's idempotency mechanism if it has one.
  • Mark the shipment as purchased in your own database, and refuse a second purchase on a shipment already marked that way.
  • After a timeout, look the shipment up with the provider before you retry.
  • Save the purchased label before you start follow-up steps such as creating a tracker or generating documents. If those later steps fail, you retry them on their own without touching the label.

Everything else. Queue requests that do not need an instant answer, such as tracker creation, pickups and manifests. Use retries with backoff, and alert a person when a queue keeps growing. Keep the raw request and response for each carrier call with the shipment, so support can see what happened without searching logs.

Returns and return labels

A return starts with an approval step, and the refund should wait until the warehouse has the item back and has checked it. A typical flow runs in this order:

  • The customer asks for a return, and your order system or returns tool approves it with a return authorization (RMA) number.
  • The integration creates a return label linked to that RMA and to the original shipment.
  • The customer gets the label by email or download link, or finds it already in the box.
  • Tracking events on the return update the RMA, so support can see the parcel moving.
  • The warehouse receives and inspects the item, and the order system then issues the refund or exchange.

Each aggregator marks a return in its own way, which is one more reason for your own contract. Shippo uses the extra.is_return flag on the shipment. On USPS, FedEx and UPS returns, its API also swaps the addresses for you. EasyPost marks a shipment as a return when its is_return field is set to true. ShipStation's API, formerly ShipEngine, can create a return label on its own or from an existing outbound label. It supports return labels for domestic shipments only, and not every carrier and service can use them.

When you pay differs too, and that decides whether a label can go in every box. Shippo's return labels on those three carriers are scan-based, which means they are free to print and charged only if used. ShipStation's API asks for a charge event on each return label. By default it charges on creation for USPS through Stamps.com and ShipStation Carriers, and when the carrier scans the parcel for most other carriers. A label charged on creation costs money even if the customer never sends anything back.

Shippo creates scan-based return labels only on the same carrier as the outbound shipment. For other carriers, it suggests a normal label with the addresses swapped. Because normal labels have a limited shipping window, Shippo advises sending them on request instead of putting them in the box.

Return labels also expire, and Shippo's table gives 100 days for UPS, one year for USPS and two years for FedEx. A carrier may still accept an older label. Shippo warns that the parcel can then be flagged, returned or destroyed with no refund. Storing the expiry date with each label lets support replace one before it lapses.

Failed deliveries come back as well. Shippo lets an outbound shipment carry a return address that differs from the sender address. A parcel that cannot be delivered can then go to a returns facility instead of the site that shipped it.

In your own shipping contract, a return can be a shipment with a direction flag and a link to its RMA. That keeps return labels out of outbound reports and lets support find every label issued for one return. The link matters most when a customer loses a prepaid label and asks for another. Whether the lost label costs money depends on when it is charged. With ShipStation's API, an unused label charged on creation is refunded only after it is voided. For that kind of label, support should void the lost one when it issues the replacement. A scan-based label is charged only if the carrier scans it, and ShipStation says such labels do not need voiding.

Testing with sandboxes

Most carriers and aggregators offer a test environment. EasyPost gives you separate test and production API keys, and notes that negotiated rates are only available in production mode. Shippo says calls made with a test token are free, and its test responses are marked with a "test": true field.

Sandboxes are useful but not a copy of production. Test rates may differ from your real ones, and some services or error cases may not be available. So:

  • Unit-test each connector's mapping against recorded real responses, including error responses.
  • Run the full flow (rate, buy, track, void) in each sandbox.
  • Test your own failure handling by forcing timeouts and duplicate webhooks in staging.
  • Before going live, buy and void a small number of real labels per carrier and service to confirm production behaviour.

Examples from our own work

In our multi-carrier rates, labels and tracking case study, we put one common interface in front of several carriers. Rate requests call the suitable connections at the same time, and live quotes and stored rate sheets land in one comparison with configured markups and fees. A purchase checks access and shipment state, and a shipment already marked as created is turned away. The carrier response is merged into the existing shipment so a narrower response can add identifiers without replacing recorded parcel details, and the merged purchase is saved before tracker creation begins. Webhook delivery to connected apps counts failures and can switch off a subscription after repeated misses, so operators have to watch and restore those subscriptions.

If your shipping includes your own delivery routes as well as parcel carriers, our routing and travel time API case study covers the other side: a service that works out road journeys and travel-time matrices between chosen points, while capacity and delivery windows stay with the surrounding application.

Where shipping fits in your wider system

A shipping integration rarely stands alone. It usually sits between an order system and a warehouse, and its status updates feed customer emails, marketplace tracking uploads and support tools. If orders arrive through several channels, only one system should own shipment status, either the order system or the shipping layer. That choice is best made before the build starts, because two owners will send the customer conflicting updates. Our overview of the main types of API integration helps if you are still choosing between direct connections, middleware and unified APIs.

FAQ

What is shipping API integration?

It means connecting your ecommerce, order or warehouse software to carrier APIs, directly or through an aggregator, so rates, labels and tracking flow automatically.

Should I integrate carriers directly or use an aggregator?

Use an aggregator if you want broad carrier coverage quickly and your shipments are standard. Integrate directly when you need carrier-specific features, a carrier the aggregator lacks, or when per-label fees outweigh the extra development work.

How do I avoid buying duplicate labels?

Use a unique key per purchase attempt, mark the shipment as purchased in your database, refuse a second purchase on the same shipment, and check with the provider after a timeout before retrying.

Are webhooks enough for tracking?

Usually not on their own. Webhook endpoints can be disabled after repeated failures, so add scheduled polling for parcels that go quiet.

Do I need shipping API integration services, or can my team build it?

A team comfortable with API work can build an aggregator integration. Outside help tends to pay off when you need several direct carrier connections, custom rate logic, or a shipping layer shared by multiple order systems.

How long does a shipping API integration take?

Scope decides the timeline more than the API does. An aggregator integration for one store shipping standard parcels is the shortest case. Each direct carrier connection, each extra order source and each custom rate rule adds work. Returns, customs documents for international orders, and the failure handling and testing described in this guide add more.

Most of the build can run against test accounts. EasyPost marks every object as test or production mode, and ShipStation's API accepts a sandbox key for its rate requests. The final checks still need real labels in production. Some waits sit outside your control. For charge-on-scan return labels, ShipStation notes that the carrier must first turn on that option for your account, and that this "can take the carrier 3-4 weeks".

How much does shipping API integration cost?

The total has two parts, the one-time build and the ongoing spend on running it. The build follows the same drivers as the timeline. It grows with the number of carriers and order sources, and with the depth of your rate rules, returns flow and monitoring.

Running costs include carrier rates and any aggregator per-label or subscription fees. Return labels add their own billing choice, because some are charged when created and others only when the carrier scans them. Hosting adds to the running costs, and so does keeping up with carrier API changes such as the USPS Web Tools retirement mentioned above. A list of your carriers, order sources and failure cases gives any estimate a firmer base.

Next step

Our API integration and development services page explains how we approach carrier and marketplace integrations, and our logistics and supply chain software page shows the wider systems we work on. If you have a list of carriers, order sources and the failure cases you care about, you can get an estimate for your shipping integration.

Tags:

Share:

Saqib Tasneem
Founder & CEO, Vortex Web Innovate

Saqib Tasneem

Saqib Tasneem is the founder and CEO of Vortex Web Innovate, a software and web development company in Easthampton, Massachusetts. He has more than 10 years of experience across technology, taxation, accounting, retail operations and business development, and leads the delivery of custom software, ERP and enterprise systems, web and mobile apps, cloud and DevOps, and AI solutions. He holds an MBA from Government College University, Lahore.

Working on this yourself?

Tell us what you're trying to build or fix. If it isn't a fit, we'll say so on the first call.

Book a Technical Discovery Call

Related work

FHIR Integration for Clinical Data: Access Policies and a Local Message Queue

A FHIR-based application backend with record access policies, version history and links to existing clinical systems.

Read the case study

Long-Running Workflow Automation and API Integration

A visual workflow platform that saves execution progress, waits for external input and resumes work from its recorded state.

Read the case study

Payment Orchestration: Provider Routing with Recoverable Follow-Up Work

A shared payment interface with provider selection, status tracking and scheduled recovery work.

Read the case study
Industries

Industries we serve

Healthcare & Life Sciences

EHR integration, HL7/FHIR, telehealth, clinical workflow, PHI handling

Explore this industry

Financial Services & FinTech

Payments, reconciliation, risk models, audit trails

Explore this industry

Something on your own site not working?

Tell us what you're trying to build or fix. We'll put someone on the call who can actually assess it - and if it's not a fit, we'll tell you on the first call rather than the third.