Retrieve multi-shipment package tracking details
Learn how to retrieve tracking information for all packages in a Multi-Channel Fulfillment order.
Learn how to retrieve tracking information for all packages in a Multi-Channel Fulfillment (MCF) order, including orders that are split across multiple packages.
When Amazon fulfills an MCF order, items may ship from different fulfillment centers or in separate packages. This results in split shipments, a single fulfillment order that contains multiple shipments, each with its own set of packages and tracking numbers.
Warning
A common integration mistake is retrieving only the first shipment or first package from the
getOrderresponse. To provide accurate tracking to your customers, you must iterate through all shipments and packages within each shipment.
Prerequisites
To complete this tutorial, you need:
- Authorization from the selling partner for whom you are making calls. Refer to Authorizing Selling Partner API Applications for more information.
- The Amazon Fulfillment role assigned to your developer profile.
- The Amazon Fulfillment role selected in the App registration page for your application.
- A
orderIdfor an existing MCF order. - (Optional) A subscription to the
FULFILLMENT_ORDER_STATUSnotification type.
Data model: Shipments and packages
The getOrder response contains a shipments array. Each element represents a shipment.
Key relationships
- Each shipment can contain multiple packages (
packages). - Each item in
itemshas apackageIdfield that maps it to a specific package. - The
tracking.carrier.trackingNumberlives at the package level, not the shipment level. - To get granular carrier tracking events, call
getShipmentTrackingwith thetracking.carrier.trackingNumberandtracking.carrier.carrierCodefrom the package.
Step 1: Retrieve the fulfillment order
Call the getOrder operation with your order's orderId.
Tracking information, such as carrier and tracking number, can appear in the API response while the shipment is still being processed, before the carrier has physically picked up the package. However, this information is not final until the shipment reaches SHIPPED status. The following status transitions describe when you can expect shipments, packages, and tracking numbers in the API response.
Fulfillment order status transitions
The following shows how order, shipment, and package statuses relate to each other, and when tracking information becomes available at each level.
| Order status | Shipments available? | Packages and tracking available? |
|---|---|---|
PROCESSINGOrder received. | Yes — shipments appear with PROCESSING status | Yes |
COMPLETEAll items fulfilled. | Yes | Yes — all shipments are SHIPPED |
COMPLETE_PARTIALSome items fulfilled, others cancelled/unfulfillable | Yes | Yes for shipped items; cancelled/unfulfillable items have no tracking |
CANCELLEDSeller cancels. | No | No |
UNFULFILLABLENo sellable inventory found. | No | No |
INVALIDInvalid order. | No | No |
Shipment status transitions
Each shipment within the order has its own lifecycle.
| Shipment status | Packages available? | Tracking available? |
|---|---|---|
PROCESSINGShipment created, pick started | Yes | Yes |
SHIPPEDAll packages in shipment left the FC | Yes | Yes |
CANCELLEDCancelled by fulfiller or seller | No | No |
What to expect at each stage
- Order is
PROCESSING, shipment isPROCESSING: Theitemsarray shows which items are assigned to this shipment, thepackagesarray is populated with one or more packages. Each package will have atracking.carrier.carrierCodeandtracking.carrier.trackingNumber. ThepackageIdon items is updated to reference the correct package. - Shipment transitions to
SHIPPED: all packages within each shipment are shipped. - Split shipment timing: In a split shipment scenario, shipments transition independently. One shipment may be
SHIPPEDwhile another is stillPROCESSING. The order-level status remainsPROCESSINGuntil all shipments have shipped or reached a terminal state. - Order reaches
COMPLETEorCOMPLETE_PARTIAL: All fulfillable items have been shipped.COMPLETE_PARTIALindicates that some items were cancelled or unfulfillable — only the shipped items will have tracking.
Step 2: Iterate through all shipments and packages
To retrieve tracking for every package in the order, iterate through the shipments array and then through each shipment's packages array. For each shipment:
- Iterate through
packages[]. - For each package, extract
tracking.carrier.carrierCode,tracking.carrier.trackingNumber, anddeliveryInterval. - Use
packageIdto correlate items initems[]to their respective packages.
Step 3: Retrieve full tracking event history
The getOrder response provides the tracking number and carrier, but does not include the full history of tracking events (scans, in-transit updates, delivery confirmation) or the customer tracking link. To retrieve the complete tracking event timeline for a specific package, retrieve the tracking.carrier.trackingNumber and tracking.carrier.carrierCode from getOrder, then call the getShipmentTracking operation from the Tracking API.
When to use this operation
- You need to display a detailed tracking timeline to your customer
- You need to confirm a carrier first-scan event occurred before sharing tracking with a selling channel that restricts tracking updates (refer to use case four).
- You need the delivery timestamp or additional delivery details.
Use notifications (Optional)
Instead of polling the getOrder operation to check when tracking numbers become available, you can subscribe to the FULFILLMENT_ORDER_STATUS notification. This event-driven approach reduces API calls and provides near-real-time updates.
How it works
- Subscribe to the
FULFILLMENT_ORDER_STATUSnotification type using the Notifications API. Refer to Set up notifications using the Amazon Simple Queue Service workflow for more information. - Receive a notification to your SQS queue destination whenever the fulfillment order status changes.
- When you receive a notification indicating a status change (for example, from
ProcessingtoComplete), callgetFulfillmentOrderto retrieve the updated shipment and package details.
Use cases
1. Partial shipping (some shipments shipped, others still pending)
A fulfillment order can have shipments in different states simultaneously. How to handle this:
- Check
statusfor each shipment before accessing packages. - A
PROCESSINGshipment may have an emptypackagesarray. - The
tracking.carrier.trackingNumberis available when the shipment status isPROCESSING. - Continue monitoring (via notifications or subsequent API calls) until all packages reach in transit state and shipment is in a terminal state (
SHIPPEDorCANCELLED).
2. Cancelled shipment with automatic retry
When a shipment has status of CANCELLED, Amazon may automatically create a replacement shipment. The new shipment appears as an additional entry in the shipments array. Always process the full array rather than assuming a fixed number of shipments.
3. Multiple packages in a single shipment
A single shipment can contain multiple packages (for example, when items are too large to fit in one box). Each package has its own trackingNumber. Always iterate through the entire packages array.
4. Tracking number or carrier changes
In some cases, a shipment package assigned trackingNumber and carrierCode can change. This happens when Amazon re-plans the shipment, for example, reassigning it to a different carrier or fulfillment center.
Recommendation: Subscribe to the FULFILLMENT_ORDER_STATUS notification using the Notifications API to retrieve the latest tracking number. Alternatively, regularly poll the getPackageTrackingDetails operation to get the same tracking information. Once the package is in the IN_TRANSIT state, tracking information will not change.
For selling channels that require carrier scan confirmation: Some selling channels require that tracking information is only submitted after the carrier has physically scanned and picked up the package. To confirm this, call getShipmentTracking and check trackingDetail.milestoneHistory for a milestone status.code that indicates the carrier has possession of the package (for example, an IN_TRANSIT milestone). Once that milestone is present, tracking is confirmed and safe to share with the selling channel.
5. Sharing the customer tracking link
The getOrder response includes a tracking.carrier.trackingUrl field on each package. This is a direct link to the carrier's tracking page for that package, which you can share with customers so they can view delivery status and estimated arrival. You can include this in:
- Order confirmation emails
- Your storefront's order status page
- Customer support communications
Retrieve the URL from packages[].tracking.carrier.trackingUrl in the getOrder response. The URL is available once the shipment package is created and a carrier tracking number has been assigned.
Updated about 2 hours ago

