Tracking API

The Tracking API provides real-time shipment tracking information across all carriers. Get detailed tracking events, delivery status, and location updates for your shipments.

Overview

The Tracking API provides:

  • Real-time tracking across 7+ carriers
  • Detailed event history with timestamps and locations
  • Delivery confirmation with proof of delivery
  • Exception handling for delivery issues
  • Estimated delivery updates

Endpoints

MethodEndpointDescription
GET/trackingGet shipments in transit
GET/tracking/lookup/{loadId}Track by load ID
POST/track/shipmentTrack single shipment
POST/track/shipmentsTrack multiple shipments
POST/track/detailsGet tracking details
POST/track/updateUpdate tracking status

Track Single Shipment

Get tracking information for a single shipment.

Request

POST /track/shipmenthttp
POST https://ship.flashamericas.com/api/v1/track/shipment
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
Track shipment requestjson
{
"trackingNumber": "1234567890"
}

Response

Tracking responsejson
{
"success": true,
"data": {
  "shipmentId": "660e8400-e29b-41d4-a716-446655440001",
  "trackingNumber": "1234567890",
  "proNumber": "PRO123456",
  "provider": "FEDEX",
  "service": "FEDEX_GROUND",
  "status": "IN_TRANSIT",
  "statusDescription": "Package is in transit to destination",
  "estimatedDelivery": "2025-02-21T17:00:00Z",
  "actualDelivery": null,
  "weight": 25.5,
  "origin": {
    "city": "Dallas",
    "state": "TX",
    "country": "US"
  },
  "destination": {
    "city": "Houston",
    "state": "TX", 
    "country": "US"
  },
  "events": [
    {
      "eventId": "evt_001",
      "timestamp": "2025-02-21T09:15:00Z",
      "status": "IN_TRANSIT",
      "description": "On FedEx vehicle for delivery",
      "location": {
        "address": "HOUSTON, TX",
        "city": "Houston",
        "state": "TX",
        "postalCode": "77001",
        "country": "US",
        "coordinates": {
          "latitude": 29.7604,
          "longitude": -95.3698
        }
      },
      "facilityType": "DELIVERY_VEHICLE"
    },
    {
      "eventId": "evt_002", 
      "timestamp": "2025-02-21T06:30:00Z",
      "status": "IN_TRANSIT",
      "description": "At local FedEx facility",
      "location": {
        "address": "7001 GOVERNOR BILL DANIEL PKWY, HOUSTON, TX 77041",
        "city": "Houston",
        "state": "TX",
        "postalCode": "77041",
        "country": "US"
      },
      "facilityType": "DELIVERY_FACILITY"
    },
    {
      "eventId": "evt_003",
      "timestamp": "2025-02-20T14:30:00Z", 
      "status": "PICKED_UP",
      "description": "Picked up at origin",
      "location": {
        "address": "123 MAIN STREET, DALLAS, TX 75201",
        "city": "Dallas",
        "state": "TX",
        "postalCode": "75201",
        "country": "US"
      },
      "facilityType": "PICKUP_LOCATION"
    }
  ],
  "lastUpdated": "2025-02-21T09:15:00Z"
}
}

Track by Shipment ID

Get tracking information using your internal shipment ID.

Request

GET /shipments/{id}/trackhttp
GET https://api.flashamericas.com/api/v1/shipments/660e8400-e29b-41d4-a716-446655440001/track
Authorization: Bearer YOUR_API_KEY

Response

Same format as tracking by number, but includes additional shipment metadata:

Shipment tracking responsejson
{
"success": true,
"data": {
  "shipmentId": "660e8400-e29b-41d4-a716-446655440001",
  "trackingNumber": "1234567890",
  "reference": "ORDER-12345",
  "status": "IN_TRANSIT",
  // ... same tracking data as above
  "shipmentInfo": {
    "totalCost": 12.45,
    "currency": "USD",
    "createdAt": "2025-01-15T10:30:00Z",
    "estimatedDelivery": "2025-02-21T17:00:00Z"
  }
}
}

List Tracking Events

Get tracking events for multiple shipments or filter by criteria.

Request

GET /tracking/eventshttp
GET https://api.flashamericas.com/api/v1/tracking/events?shipmentIds=123,456&status=DELIVERED&limit=50
Authorization: Bearer YOUR_API_KEY

Query Parameters

ParameterTypeDescription
shipmentIdsstringComma-separated shipment IDs
trackingNumbersstringComma-separated tracking numbers
statusstringFilter by tracking status
eventTypestringFilter by event type
afterstringEvents after timestamp (ISO 8601)
beforestringEvents before timestamp (ISO 8601)
limitintegerMaximum events to return (default: 25, max: 100)
pageintegerPage number for pagination

Response

Tracking events responsejson
{
"success": true,
"data": [
  {
    "eventId": "evt_001",
    "shipmentId": "660e8400-e29b-41d4-a716-446655440001",
    "trackingNumber": "1234567890",
    "timestamp": "2025-02-21T16:45:00Z",
    "status": "DELIVERED",
    "description": "Delivered to recipient",
    "location": {
      "address": "456 OAK AVENUE, HOUSTON, TX 77001",
      "city": "Houston",
      "state": "TX",
      "postalCode": "77001",
      "country": "US"
    },
    "recipient": "J. DOE",
    "signature": "https://api.flashamericas.com/documents/signature_123.png"
  },
  {
    "eventId": "evt_002",
    "shipmentId": "770e8400-e29b-41d4-a716-446655440002", 
    "trackingNumber": "0987654321",
    "timestamp": "2025-02-21T15:30:00Z",
    "status": "EXCEPTION",
    "description": "Delivery attempted - no one available",
    "location": {
      "address": "789 ELM STREET, AUSTIN, TX 78701",
      "city": "Austin",
      "state": "TX",
      "postalCode": "78701",
      "country": "US"
    },
    "exceptionCode": "001",
    "exceptionReason": "RECIPIENT_NOT_AVAILABLE"
  }
],
"meta": {
  "pagination": {
    "page": 1,
    "limit": 50,
    "total": 150,
    "hasNext": true,
    "hasPrev": false
  }
}
}

Tracking Status Values

Shipments progress through standardized status values:

StatusDescription
LABEL_CREATEDShipping label has been created
PICKUP_SCHEDULEDPickup has been scheduled
PICKED_UPPackage has been picked up
IN_TRANSITPackage is in transit
OUT_FOR_DELIVERYPackage is out for delivery
DELIVEREDPackage has been delivered
EXCEPTIONDelivery exception occurred
RETURNEDPackage is being returned to sender

Event Types

Different types of tracking events provide specific information:

Event TypeDescription
PICKUPPackage pickup events
TRANSITIn-transit updates
DELIVERY_ATTEMPTDelivery attempt made
DELIVERYSuccessful delivery
EXCEPTIONException or delay
CUSTOMSCustoms processing (international)
RETURNReturn to sender events

Exception Handling

Common delivery exceptions and their meanings:

Exception CodeReasonDescription
001RECIPIENT_NOT_AVAILABLENo one available to receive package
002INCORRECT_ADDRESS`Address incomplete or incorrect
003BUSINESS_CLOSED`Business closed during delivery attempt
004WEATHER_DELAY`Weather-related delay
005MECHANICAL_DELAY`Vehicle or equipment issue
006CUSTOMS_HOLD`Package held by customs
007REFUSED_BY_RECIPIENT`Recipient refused delivery
008DAMAGED_PACKAGE`Package damaged in transit

Real-time Updates

Polling vs Webhooks

Polling Approach:

  • Poll tracking endpoint every 15-30 minutes
  • Good for low-volume applications
  • Simple to implement

Webhook Approach:

  • Receive real-time push notifications
  • Better for high-volume applications
  • More efficient and immediate

Configure Tracking Webhooks

POST /tracking/webhookhttp
POST https://api.flashamericas.com/api/v1/tracking/webhook
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
Webhook configurationjson
{
"url": "https://your-app.com/webhooks/tracking",
"events": [
  "shipment.picked_up",
  "shipment.in_transit", 
  "shipment.delivered",
  "shipment.exception"
],
"secret": "your_webhook_secret_key"
}

Webhook Payload

Tracking webhook payloadjson
{
"eventId": "evt_550e8400-e29b-41d4-a716-446655440000",
"eventType": "shipment.delivered",
"timestamp": "2025-02-21T16:45:00Z",
"data": {
  "shipmentId": "660e8400-e29b-41d4-a716-446655440001",
  "trackingNumber": "1234567890",
  "status": "DELIVERED",
  "description": "Delivered to recipient",
  "location": {
    "city": "Houston",
    "state": "TX",
    "country": "US"
  },
  "recipient": "J. DOE",
  "deliveredAt": "2025-02-21T16:45:00Z"
},
"signature": "sha256=abc123..."
}

Examples

Basic Tracking

Track a packagejavascript
async function trackPackage(trackingNumber) {
const response = await fetch(`/api/v1/tracking/${trackingNumber}`, {
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY'
  }
});

const tracking = await response.json();

if (tracking.success) {
  console.log(`Status: ${tracking.data.status}`);
  console.log(`Last Update: ${tracking.data.lastUpdated}`);
  
  // Show latest event
  const latestEvent = tracking.data.events[0];
  console.log(`Latest: ${latestEvent.description}`);
  
  return tracking.data;
} else {
  throw new Error(tracking.error.message);
}
}

Track Multiple Shipments

Bulk trackingjavascript
async function trackMultipleShipments(shipmentIds) {
const events = await fetch(`/api/v1/tracking/events?shipmentIds=${shipmentIds.join(',')}`, {
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY'
  }
});

const trackingData = await events.json();

// Group events by shipment
const shipmentTracking = {};
trackingData.data.forEach(event => {
  if (!shipmentTracking[event.shipmentId]) {
    shipmentTracking[event.shipmentId] = [];
  }
  shipmentTracking[event.shipmentId].push(event);
});

return shipmentTracking;
}

Display Tracking Timeline

Create tracking timelinejavascript
function createTrackingTimeline(events) {
const timeline = events
  .sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp))
  .map(event => ({
    date: new Date(event.timestamp).toLocaleDateString(),
    time: new Date(event.timestamp).toLocaleTimeString(),
    status: event.status,
    description: event.description,
    location: event.location ? 
      `${event.location.city}, ${event.location.state}` : 
      'Unknown'
  }));

return timeline;
}

// Usage
const tracking = await trackPackage('1234567890');
const timeline = createTrackingTimeline(tracking.events);

timeline.forEach(event => {
console.log(`${event.date} ${event.time}: ${event.description} (${event.location})`);
});

Handle Delivery Exceptions

Exception handlingjavascript
function handleTrackingUpdate(trackingData) {
const { status, events } = trackingData;

switch (status) {
  case 'DELIVERED':
    // Package delivered successfully
    notifyCustomer('Your package has been delivered!');
    break;
    
  case 'EXCEPTION':
    const latestEvent = events[0];
    const exceptionReason = latestEvent.exceptionReason;
    
    switch (exceptionReason) {
      case 'RECIPIENT_NOT_AVAILABLE':
        notifyCustomer('Delivery attempted - please be available tomorrow');
        break;
      case 'INCORRECT_ADDRESS':
        notifyCustomer('Please verify your delivery address');
        requestAddressUpdate();
        break;
      case 'WEATHER_DELAY':
        notifyCustomer('Delivery delayed due to weather conditions');
        break;
      default:
        notifyCustomer('Delivery issue occurred - we're working to resolve it');
    }
    break;
    
  case 'OUT_FOR_DELIVERY':
    notifyCustomer('Your package is out for delivery today!');
    break;
}
}

Webhook Verification

Verify webhook authenticity using HMAC signatures:

Webhook verificationjavascript
const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload, 'utf8')
.digest('hex');

const expectedHeader = `sha256=${expectedSignature}`;

return crypto.timingSafeEqual(
Buffer.from(signature, 'utf8'),
Buffer.from(expectedHeader, 'utf8')
);
}

// Express.js webhook handler
app.post('/webhooks/tracking', express.raw({type: 'application/json'}), (req, res) => {
const signature = req.headers['x-flash-americas-signature'];
const payload = req.body;

if (!verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Unauthorized');
}

const event = JSON.parse(payload);
handleTrackingUpdate(event.data);

res.status(200).send('OK');
});

Error Handling

Common Errors

Tracking number not foundjson
{
"success": false,
"error": {
  "code": "TRACKING_NOT_FOUND",
  "message": "Tracking number not found",
  "details": {
    "trackingNumber": "1234567890",
    "provider": "FEDEX"
  }
}
}
Tracking not availablejson
{
"success": false,
"error": {
  "code": "TRACKING_NOT_AVAILABLE",
  "message": "Tracking information not yet available",
  "details": {
    "reason": "Package not yet in carrier system",
    "retryAfter": 3600
  }
}
}

Best Practices

  1. Handle delays - Tracking may not be immediately available after shipment creation
  2. Cache tracking data - Avoid excessive API calls by caching recent tracking data
  3. Use webhooks - Implement webhooks for real-time updates instead of constant polling
  4. Verify signatures - Always verify webhook signatures for security
  5. Handle exceptions gracefully - Provide clear messaging for delivery exceptions

Rate Limiting

Tracking API calls are rate limited:

  • Production: 1000 requests per minute
  • Sandbox: 100 requests per minute

For high-volume tracking, consider:

  • Using bulk tracking endpoints
  • Implementing webhook notifications
  • Caching tracking data appropriately

Next Steps