Once freight is booked, these endpoints retrieve it, download its paperwork, follow it in transit, and cancel it if plans change. See Quote & Book Freight for the booking itself.
GET /v2/freight/shipments
Return the freight shipments on your account, most recently created first.
- Productionhttps://api.shipstation.com/v2/freight/shipments
- curl
- JavaScript
- Node.js
- Python
- Java
- C#
- PHP
- Go
- Ruby
- R
- Payload
curl -i -X GET \
'https://api.shipstation.com/v2/freight/shipments?page=1&page_size=50' \
-H 'api-key: YOUR_API_KEY_HERE'Results are paginated with page and page_size. The default page size is 25 and the maximum is 500 — larger values are capped rather than rejected, and page values below 1 are treated as 1.
{
"shipments": [
{
"freight_shipment_id": "se-98765432",
"freight_provider_account_id": "se-4821",
"freight_provider_name": "UNISHIPPERS",
"status": "in_transit",
"bol_number": "BOL-20260417-4821",
"pro_number": "072-51293847",
"documents": [
{
"type": "bill_of_lading",
"url": "/v2/downloads/10/a1b2c3d4e5f6/bill_of_lading.pdf"
}
]
}
],
"total": 137,
"page": 1,
"page_size": 25,
"pages": 6
}Freight shipments are not eligible for the batch endpoints. Including one in a batch returns a 400 with error code freight_shipment_not_batchable, and the message lists the offending shipment IDs. Print freight paperwork from List freight shipment documents instead — the Bill of Lading and pallet labels are generated at booking, not by a batch process.
GET /v2/freight/shipments/:freight_shipment_id
Retrieve a single freight shipment with its current status, carrier reference numbers, and documents.
- Productionhttps://api.shipstation.com/v2/freight/shipments/{freight_shipment_id}
- curl
- JavaScript
- Node.js
- Python
- Java
- C#
- PHP
- Go
- Ruby
- R
- Payload
curl -i -X GET \
https://api.shipstation.com/v2/freight/shipments/se-98765432 \
-H 'api-key: YOUR_API_KEY_HERE'The status here is the stored status, updated as tracking is received. To pull fresh status from the carrier, use Get freight shipment tracking.
An unknown ID returns a 404 with error code invalid_identifier, and field_name set to freight_shipment_id.
This endpoint, List freight shipment documents, and Cancel a freight shipment report an unknown freight_shipment_id as invalid_identifier. Get freight shipment tracking reports the same condition as freight_shipment_not_found. Both are 404s; handle both if you branch on error_code.
GET /v2/freight/shipments/:freight_shipment_id/documents
List the paperwork for a shipment, with a download URL for each document.
- Productionhttps://api.shipstation.com/v2/freight/shipments/{freight_shipment_id}/documents
- curl
- JavaScript
- Node.js
- Python
- Java
- C#
- PHP
- Go
- Ruby
- R
- Payload
curl -i -X GET \
https://api.shipstation.com/v2/freight/shipments/se-98765432/documents \
-H 'api-key: YOUR_API_KEY_HERE'{
"documents": [
{
"type": "bill_of_lading",
"created_at": "2026-04-16T14:32:07Z",
"url": "/v2/downloads/10/a1b2c3d4e5f6/bill_of_lading.pdf"
},
{
"type": "pallet_label",
"created_at": "2026-04-16T14:32:07Z",
"url": "/v2/downloads/10/a1b2c3d4e5f6/pallet_label.pdf"
}
]
}Each url is a path relative to the API host — resolve it against https://api.shipstation.com and fetch it with your API key to get the PDF.
Documents appear as the shipment progresses. The Bill of Lading and pallet labels are generated at booking; a weight and inspection certificate appears if the carrier reweighs the freight; the proof of delivery only exists after delivery. Poll this endpoint, or watch tracking events, rather than expecting the full set up front.
Print the Bill of Lading before the driver arrives. LTL drivers will not collect freight without one, and pallet labels need to be affixed to each handling unit so the freight can be identified at every terminal it passes through.
| Type | Description |
|---|---|
bill_of_lading | The BOL — the contract of carriage and the document the driver signs at pickup. |
pallet_label, pallet_label_4x6 | Labels to affix to each handling unit. |
bol_pallet_label_combined | The BOL and pallet labels as a single PDF. |
proof_of_delivery | The signed delivery receipt, available after delivery. |
weight_and_inspection | The carrier's reweigh or reclassification certificate. Its arrival usually means a billing adjustment is coming. |
quote | A printable copy of the quote. |
packing_list | The packing list for the shipment. |
certificate_of_insurance, certificate_of_insurance_instructions | Cargo insurance paperwork, when insurance was purchased. |
certificate_of_origin_us, certificate_of_origin_usmca, certificate_of_origin_usmca_instructions | Origin certificates for cross-border freight. |
international_commercial_invoice | The commercial invoice for cross-border freight. |
GET /v2/freight/shipments/:freight_shipment_id/tracking
Retrieve live status and event history from the carrier for a booked shipment.
- Productionhttps://api.shipstation.com/v2/freight/shipments/{freight_shipment_id}/tracking
- curl
- JavaScript
- Node.js
- Python
- Java
- C#
- PHP
- Go
- Ruby
- R
- Payload
curl -i -X GET \
https://api.shipstation.com/v2/freight/shipments/se-98765432/tracking \
-H 'api-key: YOUR_API_KEY_HERE'The shipment is tracked by its PRO number when the carrier has assigned one, and by its BOL number otherwise.
{
"freight_shipment_id": "se-98765432",
"freight_provider_account_id": "se-4821",
"freight_provider_name": "UNISHIPPERS",
"carrier_scac": "FXFE",
"bol_number": "BOL-20260417-4821",
"pro_number": "072-51293847",
"status": "in_transit",
"tracking_status": "in_transit",
"estimated_delivery_date": "2026-04-22",
"tracking_url": "https://www.fedex.com/fedextrack/?trknbr=07251293847",
"last_event_at": "2026-04-20T14:05:00Z",
"events": [
{
"occurred_at": "2026-04-17T10:22:00Z",
"status": "at_pickup",
"carrier_code": "AP",
"description": "Freight picked up in Grand Rapids, MI",
"documents": []
},
{
"occurred_at": "2026-04-20T14:05:00Z",
"status": "in_transit",
"carrier_code": "AF",
"description": "Departed terminal in Grand Rapids, MI",
"documents": []
}
]
}Read status for a coarse state and tracking_status for the carrier's detail. Both are described in Statuses. estimated_delivery_date is a YYYY-MM-DD date, while occurred_at and last_event_at are timestamps; carriers that report only a date return midnight as the time.
Events can carry documents, most usefully a proof of delivery attached to the delivery event.
A shipment with neither a PRO nor a BOL number cannot be tracked, and returns:
{
"request_id": "4b8e2f4c-1f6f-4b1a-9c4a-8f5e6d7c8b9a",
"errors": [
{
"error_source": "shipengine",
"error_type": "business_rules",
"error_code": "freight_tracking_not_available",
"message": "Tracking is not yet available for this shipment. A PRO or BOL number is required."
}
]
}This is expected in the window right after booking. Treat it as "not yet" rather than as a failure, and retry later.
The other outcomes this endpoint can return:
Status / error_code | Meaning |
|---|---|
404 freight_shipment_not_found | No shipment with that freight_shipment_id exists on your account. |
400 freight_tracking_not_available | The shipment exists but has neither a PRO nor a BOL number yet. Retry later. |
400 freight_connection_inactive | The freight provider connection the shipment was booked through is no longer active, so the carrier cannot be queried. The stored shipment record is still readable with Get freight shipment by ID. |
404 freight_tracking_not_found | The carrier has no information for the number yet — also common before the freight is first scanned. |
A successful call also writes the carrier's status back to the stored shipment — its status, tracking status, and last-event timestamp — so Get freight shipment by ID reflects what tracking last returned. The write is best-effort: if it fails, you still get the tracking response. The PRO number is not updated this way, so a shipment tracked by BOL number keeps a null pro_number in the stored record.
GET /v2/freight/tracking
Track any freight shipment by its PRO or BOL number, whether or not it was booked through ShipStation. This is the endpoint to use for freight booked elsewhere, or when all you have is a number from a supplier.
- Productionhttps://api.shipstation.com/v2/freight/tracking
- curl
- JavaScript
- Node.js
- Python
- Java
- C#
- PHP
- Go
- Ruby
- R
- Payload
curl -i -X GET \
'https://api.shipstation.com/v2/freight/tracking?freight_provider_account_id=se-4821&tracking_number=072-51293847&tracking_type=pro_number&carrier_scac=FXFE' \
-H 'api-key: YOUR_API_KEY_HERE'GET /v2/freight/tracking?freight_provider_account_id=se-4821&tracking_number=072-51293847&tracking_type=pro_number&carrier_scac=FXFE| Parameter | Required | Description |
|---|---|---|
freight_provider_account_id | Yes | The freight provider account to track through, from List freight provider accounts. Omitting it, or sending a value that is not a valid account ID, returns a 400 with error code freight_provider_id_required. |
tracking_number | Yes | The PRO or BOL number. |
tracking_type | Yes | pro_number or bol_number. |
carrier_scac | Yes | The carrier's SCAC. The freight provider needs it to resolve a tracking number, so the request is rejected without it. |
The response is the same shape as shipment tracking, minus freight_shipment_id, status, and estimated_delivery_date, since the number may not correspond to a shipment on your account. Read tracking_status for the carrier's state, and take the estimated delivery date from the events if you need it.
Nothing is stored as a result of this call — it is a pass-through to the provider. Tracking a number that happens to belong to one of your own shipments does not update that shipment's stored status; use Get freight shipment tracking for that.
carrier_scac in the response is the SCAC the carrier reported back, not the one you sent, so it can be null even on a successful lookup.
Its failure modes:
Status / error_code | Meaning |
|---|---|
400 freight_provider_id_required | freight_provider_account_id was omitted, or is not a valid account ID. The message names the parameter seller_freight_provider_id, which is what it used to be called. |
400 field validation (field_value_required or unspecified) | tracking_number, tracking_type, or carrier_scac was omitted, or tracking_type was something other than pro_number or bol_number. field_name names the parameter. |
400 freight_connection_inactive | The freight_provider_account_id is not an active connection on your account. |
404 freight_tracking_not_found | The provider returned nothing for that number. Either the carrier has not scanned the freight yet, or the number and SCAC do not match a shipment the provider can see. |
DELETE /v2/freight/shipments/:freight_shipment_id
Cancel a booked shipment with the carrier.
- Productionhttps://api.shipstation.com/v2/freight/shipments/{freight_shipment_id}
- curl
- JavaScript
- Node.js
- Python
- Java
- C#
- PHP
- Go
- Ruby
- R
- Payload
curl -i -X DELETE \
https://api.shipstation.com/v2/freight/shipments/se-98765432 \
-H 'api-key: YOUR_API_KEY_HERE'{
"freight_shipment_id": "se-98765432",
"cancelled_transactions": [
"7f1c9a52-3d84-4f0e-9b3a-2c6d5e4f8a10",
"3ac81f60-92b7-4de1-8f04-5b9a7c2e6d13"
]
}cancelled_transactions lists what was actually cancelled at the provider — typically the booked shipment and the pickup request.
Cancellation windows are set by the carrier, not by ShipStation. Freight that has already been picked up generally cannot be cancelled, and the carrier's rejection comes back as a 400 Bad Request whose message is the provider's wording behind the fixed prefix A shipping carrier error occurred: — see Errors for the full shape. Cancel as early as you can, and treat a 400 here as "the carrier said no" rather than as a client error.