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
| Method | Endpoint | Description |
|---|---|---|
| GET | /tracking | Get shipments in transit |
| GET | /tracking/lookup/{loadId} | Track by load ID |
| POST | /track/shipment | Track single shipment |
| POST | /track/shipments | Track multiple shipments |
| POST | /track/details | Get tracking details |
| POST | /track/update | Update tracking status |
Track Single Shipment
Get tracking information for a single shipment.
Request
POST https://ship.flashamericas.com/api/v1/track/shipment
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json{
"trackingNumber": "1234567890"
}Response
{
"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 https://api.flashamericas.com/api/v1/shipments/660e8400-e29b-41d4-a716-446655440001/track
Authorization: Bearer YOUR_API_KEYResponse
Same format as tracking by number, but includes additional shipment metadata:
{
"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 https://api.flashamericas.com/api/v1/tracking/events?shipmentIds=123,456&status=DELIVERED&limit=50
Authorization: Bearer YOUR_API_KEYQuery Parameters
| Parameter | Type | Description |
|---|---|---|
shipmentIds | string | Comma-separated shipment IDs |
trackingNumbers | string | Comma-separated tracking numbers |
status | string | Filter by tracking status |
eventType | string | Filter by event type |
after | string | Events after timestamp (ISO 8601) |
before | string | Events before timestamp (ISO 8601) |
limit | integer | Maximum events to return (default: 25, max: 100) |
page | integer | Page number for pagination |
Response
{
"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:
| Status | Description |
|---|---|
LABEL_CREATED | Shipping label has been created |
PICKUP_SCHEDULED | Pickup has been scheduled |
PICKED_UP | Package has been picked up |
IN_TRANSIT | Package is in transit |
OUT_FOR_DELIVERY | Package is out for delivery |
DELIVERED | Package has been delivered |
EXCEPTION | Delivery exception occurred |
RETURNED | Package is being returned to sender |
Event Types
Different types of tracking events provide specific information:
| Event Type | Description |
|---|---|
PICKUP | Package pickup events |
TRANSIT | In-transit updates |
DELIVERY_ATTEMPT | Delivery attempt made |
DELIVERY | Successful delivery |
EXCEPTION | Exception or delay |
CUSTOMS | Customs processing (international) |
RETURN | Return to sender events |
Exception Handling
Common delivery exceptions and their meanings:
| Exception Code | Reason | Description |
|---|---|---|
001 | RECIPIENT_NOT_AVAILABLE | No one available to receive package |
002 | INCORRECT_ADDRESS` | Address incomplete or incorrect |
003 | BUSINESS_CLOSED` | Business closed during delivery attempt |
004 | WEATHER_DELAY` | Weather-related delay |
005 | MECHANICAL_DELAY` | Vehicle or equipment issue |
006 | CUSTOMS_HOLD` | Package held by customs |
007 | REFUSED_BY_RECIPIENT` | Recipient refused delivery |
008 | DAMAGED_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 https://api.flashamericas.com/api/v1/tracking/webhook
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json{
"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
{
"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
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
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
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
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:
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
{
"success": false,
"error": {
"code": "TRACKING_NOT_FOUND",
"message": "Tracking number not found",
"details": {
"trackingNumber": "1234567890",
"provider": "FEDEX"
}
}
}{
"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
- Handle delays - Tracking may not be immediately available after shipment creation
- Cache tracking data - Avoid excessive API calls by caching recent tracking data
- Use webhooks - Implement webhooks for real-time updates instead of constant polling
- Verify signatures - Always verify webhook signatures for security
- 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
- Set up webhooks for real-time tracking updates
- View integration examples for complete tracking implementations
- Monitor shipments for comprehensive shipment management
- Handle documents for proof of delivery
