Skip to content
Last updated

Tracking

With ShipStation V2 API, you can track shipments and receive real-time updates about package status and location.

Two Ways to Track Shipments

Event-driven, push-based tracking — ShipStation automatically notifies your application when tracking status changes occur.

Benefits:

  • Immediate notifications when tracking events happen
  • No polling loops or scheduled jobs needed
  • Reduces server load and API call volume
  • Simpler integration — just handle incoming webhook requests

How it works: Subscribe to the track_event_v2 webhook event, and ShipStation will POST tracking updates to your specified endpoint whenever a carrier reports new tracking information.

Learn more: Webhooks Overview

GET Endpoint

On-demand, pull-based tracking — Query tracking status whenever you need it using the /v2/labels/{label_id}/track endpoint.

Benefits:

  • Simple one-time lookups
  • No webhook infrastructure needed
  • Useful for customer service inquiries or manual checks

Trade-offs: Requires polling if you want to detect status changes, which can be inefficient for high-volume operations.

Advanced Plan Note

For Advanced plan users, tracking webhooks count toward your included API calls, while manual polling requests beyond your plan’s monthly limit will incur overage charges.


The rest of this guide covers the GET endpoint approach. If you’re using webhooks, see the Webhook Schemas guide for payload details.

Requirements

  • You must have the label_id of the label you wish to track.

Sample Request & Response

GET /v2/labels/:label_id/track

GET /v2/labels/se-324658/track HTTP/1.1
Host: api.shipstation.com
API-Key: __YOUR_API_KEY_HERE__
Cache-Control: no-cache

Sample Response

{
 "tracking_number": "1Z932R800390810600",
 "status_code": "DE",
 "status_description": "Delivered",
 "carrier_status_code": "D",
 "carrier_status_description": "DELIVERED",
 "shipped_date": "2024-10-25T11:59:03.289Z",
 "estimated_delivery_date": "2024-10-27T11:59:03.289Z",
 "actual_delivery_date": "2024-10-27T11:59:03.289Z",
 "exception_description": null,
 "events": [
   {
     "occurred_at": "2024-10-25T12:32:00Z",
     "carrier_occurred_at": "2024-10-25T05:32:00",
     "description": "Arrived at UPS Facility",
     "city_locality": "OCEANSIDE",
     "state_province": "CA",
     "postal_code": "92056",
     "country_code": "",
     "company_name": "",
     "signer": "",
     "event_code": "U1"
   }
 ]
}

About the Tracking Response

Event Timestamps:

  • carrier_occurred_at is the timestamp of the event received from the carrier. It is assumed to be the local time of where the event occurred. This event property is not yet fully supported across all carriers.
  • occurred_at is our best effort at converting the carrier_occurred_at field to UTC, based on the time of the event's occurrence.

Tracking Status Codes

Here's how the status_code and status_description fields correspond to each other and how they correspond to the tracking_status field of a label:

Status CodeStatus DescriptionTracking Status
ACAcceptedN/A
ITIn Transitin_transit
DEDelivereddelivered
EXExceptionerror
UNUnknownunknown
ATDelivery AttemptN/A
NYNot Yet in Systemin_transit
SPDelivered to the Collection Locationdelivered_to_service_point

Your integration should expect any of the above tracking events for any of the carriers you use.