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 getOrder response. 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:

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 items has a packageId field that maps it to a specific package.
  • The tracking.carrier.trackingNumber lives at the package level, not the shipment level.
  • To get granular carrier tracking events, call getShipmentTracking with the tracking.carrier.trackingNumber and tracking.carrier.carrierCode from 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 statusShipments available?Packages and tracking available?
PROCESSING
Order received.
Yes — shipments appear with PROCESSING statusYes
COMPLETE
All items fulfilled.
YesYes — all shipments are SHIPPED
COMPLETE_PARTIAL
Some items fulfilled, others cancelled/unfulfillable
YesYes for shipped items; cancelled/unfulfillable items have no tracking
CANCELLED
Seller cancels.
NoNo
UNFULFILLABLE
No sellable inventory found.
NoNo
INVALID
Invalid order.
NoNo

Shipment status transitions

Each shipment within the order has its own lifecycle.

Shipment statusPackages available?Tracking available?
PROCESSING
Shipment created, pick started
YesYes
SHIPPED
All packages in shipment left the FC
YesYes
CANCELLED
Cancelled by fulfiller or seller
NoNo

What to expect at each stage

  1. Order is PROCESSING, shipment is PROCESSING: The items array shows which items are assigned to this shipment, the packages array is populated with one or more packages. Each package will have a tracking.carrier.carrierCode and tracking.carrier.trackingNumber. The packageId on items is updated to reference the correct package.
  2. Shipment transitions to SHIPPED: all packages within each shipment are shipped.
  3. Split shipment timing: In a split shipment scenario, shipments transition independently. One shipment may be SHIPPED while another is still PROCESSING. The order-level status remains PROCESSING until all shipments have shipped or reached a terminal state.
  4. Order reaches COMPLETE or COMPLETE_PARTIAL: All fulfillable items have been shipped. COMPLETE_PARTIAL indicates 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:

  1. Iterate through packages[].
  2. For each package, extract tracking.carrier.carrierCode, tracking.carrier.trackingNumber, and deliveryInterval.
  3. Use packageId to correlate items in items[] 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

  1. Subscribe to the FULFILLMENT_ORDER_STATUS notification type using the Notifications API. Refer to Set up notifications using the Amazon Simple Queue Service workflow for more information.
  2. Receive a notification to your SQS queue destination whenever the fulfillment order status changes.
  3. When you receive a notification indicating a status change (for example, from Processing to Complete), call getFulfillmentOrder to 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 status for each shipment before accessing packages.
  • A PROCESSING shipment may have an empty packages array.
  • The tracking.carrier.trackingNumber is available when the shipment status is PROCESSING.
  • Continue monitoring (via notifications or subsequent API calls) until all packages reach in transit state and shipment is in a terminal state (SHIPPED or CANCELLED).

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.


Did this page help you?