Skip to main content

Poll tracking updates

Use GET /tracking/{id} to retrieve real-time shipment tracking data in a unified format. This guide covers the polling flow, how to interpret tracking statuses, and patterns for building customer notifications.

Retrieve tracking data

Use the id from the label creation response:
curl https://api.flexforward.com/tracking/f47ac10b-58cc-4372-a567-0e02b2c3d479 \
  -H "Authorization: Bearer YOUR_API_TOKEN"

Response

200 OK
{
  "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "trackingNumber": "YT2503010001CN",
  "tag": "InTransit",
  "subtag": "InTransit_001",
  "subtagMessage": "In transit",
  "slug": "yunexpress",
  "checkpoints": [
    {
      "checkpointTime": "2026-03-17T08:15:00Z",
      "city": "Los Angeles",
      "state": "CA",
      "countryRegion": "US",
      "location": "LAX Distribution Center",
      "message": "Arrived at destination country",
      "tag": "InTransit",
      "subtag": "InTransit_001",
      "subtagMessage": "In transit",
      "slug": "yunexpress"
    },
    {
      "checkpointTime": "2026-03-16T02:30:00Z",
      "city": "Shenzhen",
      "state": "Guangdong",
      "countryRegion": "CN",
      "location": null,
      "message": "Departed from sorting center",
      "tag": "InTransit",
      "subtag": "InTransit_001",
      "subtagMessage": "In transit",
      "slug": "yunexpress"
    },
    {
      "checkpointTime": "2026-03-15T10:30:00Z",
      "city": "Tokyo",
      "state": "Tokyo",
      "countryRegion": "JP",
      "location": null,
      "message": "Shipment information received",
      "tag": "InfoReceived",
      "subtag": "InfoReceived_001",
      "subtagMessage": "Shipment information received",
      "slug": "yunexpress"
    }
  ]
}
Checkpoints are ordered with the most recent event first.

Understand the tracking status

Use the top-level tag field for high-level status logic:
TagCustomer-facing meaningAction
PendingOrder is being processedNo notification needed
InfoReceivedShipment registered with courierNotify: “Your order has shipped”
InTransitPackage is on the wayNotify: “Your package is in transit”
DeliveredPackage deliveredNotify: “Your package has been delivered”
ExceptionDelivery issueNotify: “There’s an issue with your delivery” and investigate
CancelledShipment cancelledHandle internally
UnknownStatus unavailableNo notification — retry later

Polling pattern

Since webhooks are not currently available, poll GET /tracking/{id} at a reasonable interval to detect status changes.
async function pollTracking(labelId, token) {
  let lastTag = null;

  const interval = setInterval(async () => {
    const response = await fetch(
      `https://api.flexforward.com/tracking/${labelId}`,
      { headers: { 'Authorization': `Bearer ${token}` } }
    );
    const tracking = await response.json();

    if (tracking.tag !== lastTag) {
      lastTag = tracking.tag;
      await notifyCustomer(tracking); // Your notification logic
    }

    // Stop polling when shipment reaches a terminal state
    if (['Delivered', 'Cancelled'].includes(tracking.tag)) {
      clearInterval(interval);
    }
  }, 30 * 60 * 1000); // Every 30 minutes
}

Polling guidelines

Shipment stageRecommended interval
Pending / InfoReceivedEvery 4–6 hours
InTransitEvery 30–60 minutes
Delivered / CancelledStop polling
ExceptionEvery 15–30 minutes until resolved
Tracking data is fetched from the courier in near-real-time. Polling more frequently than every 15 minutes is unlikely to yield new data and counts against the recommended rate limit of 10 requests per second.

Error handling

StatusMeaningAction
200Tracking data retrievedProcess the tag and checkpoints
403Access deniedThe label belongs to a different account
404Label not foundVerify the label ID is correct
502Upstream service errorRetry with exponential backoff

Next steps