Skip to content
Last updated

Freight (LTL)

Freight endpoints let you quote, book, track, and manage less-than-truckload (LTL) shipments — the freight that is too large to ship as a parcel but does not fill a trailer on its own. A pallet of furniture, a crate of machine parts, or a few drums of coating all travel as LTL.

LTL works differently from parcel shipping, and the API reflects that:

  • You quote before you book. LTL prices are not published rate cards; they are offers from carriers for your specific freight on a specific lane. Every booking references an offer returned by a quote.
  • You ship handling units, not packages. The carrier handles pallets, crates, or drums, and each one contains one or more commodities — the actual goods, each with its own freight class.
  • Extra services are priced in. Liftgates, inside delivery, and appointment scheduling are accessorials, and they change the price of the quote.
  • The Bill of Lading is the shipping document. Booking generates a Bill of Lading (BOL) rather than a label, along with pallet labels and other paperwork.

The Workflow

  1. List freight provider accounts — look up the freight_provider_account_id of the freight provider connection to work through.
  2. Get freight quotes — describe the freight and receive offers from the carriers available through your freight provider.
  3. Book a freight shipment — book one of those offers and get back a BOL number and documents.
  4. Download the documents — print the Bill of Lading and pallet labels for the driver.
  5. Track the shipment — follow it from pickup to delivery.

Requirements

  • An active freight provider connection. Freight is quoted and booked through a freight provider account connected to your account, identified by a freight_provider_account_id. Every freight request requires one, and requests that reference an inactive or unknown connection return a 400 Bad Request.
  • An API key. All requests are authenticated with your API key, included in the API-Key header of every request.
Finding your freight_provider_account_id

Freight provider connections are set up in the ShipStation API dashboard. Call List freight provider accounts to retrieve the freight_provider_account_id of each active connection. Like most ShipStation API identifiers, it is an se- prefixed string such as se-4821.

Two Ways to Describe a Shipment

Both Get freight quotes and Book a freight shipment accept the shipment in one of two ways.

ModeHow you use itWhat you send
InlineYou are quoting freight that does not yet exist as a shipment in ShipStation API.ship_from, ship_to, and handling_units. Booking inline creates a shipment record for you and marks it as shipped.
Linked to a shipmentThe freight already exists as a shipment on your account, created through Create a Shipment or an order source.shipment_id. The origin comes from the shipment's ship-from warehouse and the destination from the order's ship-to address, so ship_from and ship_to must be omitted.

In the linked mode, the freight details you send when quoting — handling_units, accessorials, and insurance — are saved as the shipment's freight configuration. Booking that shipment reuses the saved configuration, so handling_units must be omitted when booking. Quote a shipment before you book it: booking a shipment_id that has no saved freight configuration returns a 400 Bad Request.

Units of Measure

The freight endpoints use a single fixed unit for each measurement. There are no unit fields to set.

MeasurementUnit
Dimensions (length, width, height)Inches
Weight (weight)Pounds
Money (total_charges, insured_value)US dollars
Temperature (flashpoint_temperature)Degrees Fahrenheit

Handling Units and Commodities

A handling unit is what the carrier physically moves and counts. A commodity is a line of goods inside it.

{
  "handling_units": [
    {
      "type": "pallet",
      "quantity": 2,
      "length": 48,
      "width": 40,
      "height": 52,
      "stackable": false,
      "commodities": [
        {
          "description": "Assembled oak dining chairs",
          "quantity": 24,
          "weight": 310,
          "freight_class": "125",
          "packaging_type": "carton"
        }
      ]
    }
  ]
}

This describes two identical pallets, each 48 × 40 × 52 inches, each holding 24 cartons of chairs weighing 310 lb in total. Dimensions, weight, and commodities always describe one handling unit — the carrier multiplies by quantity.

stackable matters more than it looks: non-stackable freight occupies trailer height that cannot be sold to anyone else, and carriers price accordingly.

Freight Class

Every commodity needs a freight_class — an NMFTA classification from 50 (dense, durable, cheap to ship) to 500 (light, bulky, or fragile). Class is derived from density, stowability, handling, and liability, and it is one of the largest factors in the price of an LTL shipment.

Valid values are 50, 55, 60, 65, 70, 77.5, 85, 92.5, 100, 110, 125, 150, 175, 200, 250, 300, 400, and 500. Send them as strings.

Understating freight class is the most common cause of a post-delivery invoice adjustment. Carriers reweigh and reclassify freight, and the corrected charge is billed back to you. If you are unsure of a class, check with your carrier or freight provider before quoting.

Accessorials

Accessorials are extra services, and they are priced into the quote. You send them only on the quote request — there is no accessorials field on the booking request. The offer you book already carries the accessorials it was priced with, which is why offer_id and quote_request_id are all the booking needs to identify what you are buying.

So get them right before you quote. Adding a liftgate after the fact means requesting fresh quotes and booking a new offer; there is no way to attach an accessorial to an offer that was priced without it.

AccessorialWhen you need it
liftgate_pickup, liftgate_deliveryThe location has no loading dock, so the driver needs a liftgate to raise or lower the freight.
inside_pickup, inside_deliveryThe freight must be moved into or out of the building rather than left at the dock or curb.
appointment_deliveryThe consignee requires a scheduled delivery appointment.
notify_before_deliveryThe carrier must call ahead before delivering.
hold_at_terminalThe consignee collects the freight from the destination terminal.
carrier_terminal_pickupYou drop the freight at the carrier's terminal instead of having it collected.
sort_and_segregateThe carrier must sort or separate the freight at delivery.
protection_from_cold, protection_from_heatThe freight must not freeze or overheat in transit.
grocery_consolidation_pickup, grocery_consolidation_deliveryThe origin or destination is a grocery consolidation facility.
tradeshow_pickup, tradeshow_deliveryThe freight is collected from or delivered to a tradeshow. Provide the tradeshow name and booth_number.

Location Type

Also set location_type when the location is not a plain commercial address. Residential, limited-access, construction, and similar locations carry their own surcharges, and declaring them up front keeps the quote accurate. It appears in three places: on ship_from and ship_to when quoting, and on pickup_details when booking.

airport, carrier_terminal, commercial, construction, container_freight_station, distribution_center, government_facility, limited_access, pier_port_wharf, residential, secured_access, trade_show

The value is validated against that list, so a typo is rejected with a 400 Bad Request rather than quietly dropped. Omitting the field entirely is always allowed.

pickup_details.location_type on a linked shipment

When you book with a shipment_id, ship_from is not part of the request, so pickup_details.location_type is the only way to tell the carrier how to classify the origin. Set it there if the pickup location is not a plain commercial address.

Insurance

Carrier liability is capped per pound and is usually far below what the freight is actually worth — the max_liability_new and max_liability_used values on each quote show the cap for that offer. Add an insurance object to the quote to price cargo insurance alongside the freight charges:

{
  "insurance": {
    "insured_value": 18500,
    "item_condition": "new",
    "commodity_category": "furniture",
    "marks_numbers": "NG-2026-0417"
  }
}

Offers then include insured_amount, insurance_premium (already part of total_charges), and an insurance_certificate_number once the insurer issues one. Insured values are in USD.

The presence of the insurance object is what requests insurance — there is no boolean to set. Two consequences worth knowing:

  • Always send insured_value. It is not validated, so an insurance object without it requests insurance with a declared value of 0 rather than returning an error.
  • Insurance is priced at quote time, like accessorials. There is no insurance field on the booking request, so adding coverage after the fact means re-quoting.

Hazardous Materials

A commodity carrying a hazardous_materials object is flagged as hazmat, and the details are printed on the Bill of Lading. Hazmat freight requires the full set of regulatory fields:

{
  "description": "Paint, flammable",
  "quantity": 8,
  "weight": 420,
  "freight_class": "70",
  "hazardous_materials": {
    "identification_number_type": "un",
    "identification_number": "UN1263",
    "proper_shipping_name": "Paint",
    "hazard_class": "3",
    "subsidiary_hazard_classes": ["8"],
    "packing_group": "iii",
    "emergency_contact_name": "Chemtrec",
    "emergency_contact_phone": "+1 800 424 9300",
    "emergency_response_reference": "CCN12345",
    "flashpoint_temperature": 73
  }
}
  • identification_number_type is un or na.
  • packing_group is i, ii, iii, or none.
  • subsidiary_hazard_classes must not contain duplicates or repeat the primary hazard_class.
  • emergency_contact_name and emergency_contact_phone must reach a 24-hour response service.

See the Full API Reference for the full list of accepted hazard classes.

Statuses

Freight shipments carry a coarse status and, when tracking, a finer-grained tracking_status from the carrier.

statusMeaning
pendingThe shipment exists but is not yet with the carrier.
quotedOffers have been retrieved but none has been booked.
bookedThe carrier has accepted the shipment and a Bill of Lading exists.
in_transitThe freight is moving, from dispatch through to out for delivery.
deliveredThe freight has been delivered.
cancelledThe booking was cancelled.
exceptionSomething went wrong, or the status could not be determined.

Several carrier tracking statuses roll up into one shipment status. dispatched, in_route_to_pickup, at_pickup, out_for_delivery, and at_delivery all appear as in_transit. Read tracking_status when you need the detail.

Response fields with no value are returned as null rather than omitted. A freshly booked shipment, for example, has no pro_number until the carrier assigns one, so the field is present with a value of null. Check for null rather than for the absence of a key.

The JSON examples on these pages are abbreviated to the fields being discussed, so a real response will usually contain more keys than the example shows.