Hazardous Materials (Dangerous Goods)

RocketShipIt supports shipping hazardous materials (dangerous goods) for carriers that offer it. This includes creating hazmat shipping labels and getting rates that reflect Dangerous Goods surcharges such as lithium battery fees.

Note: Hazardous materials shipping is subject to strict regulations. Ensure you are familiar with the applicable regulations (CFR, IATA, ADR, TDG) for your shipments. RocketShipIt does not validate compliance — it is your responsibility to ensure all hazmat data is accurate.

Supported Carriers#

Carrier Rating Labels
UPS-REST Yes Yes, including Shipper's Declaration paperwork
FedEx-REST Yes Lithium batteries only, see FedEx below
DHL (all variants) No No

DHL has no hazardous materials support in RocketShipIt, and the request customization escape hatch is not available for DHL either. If you need DHL dangerous goods, contact us.

Key Parameters#

Hazmat data is set at the package level using the hazmat object inside each package. Additionally, the hazmat_regulation_set parameter can be set at the request level as a default for all chemical records.

Parameter Description
hazmat_regulation_set Top-level default regulation set: CFR, IATA, ADR, or TDG
hazmat_signatory_name Person or department signing the Dangerous Goods declaration. Setting this makes UPS return the Shipper's Declaration paperwork (see below)
hazmat_signatory_title Title of the signatory
hazmat_signatory_place City of the signatory
hazmat_signatory_date Declaration date in YYYYMMDD format, defaults to today
hazmat_shipper_declaration 01 = one declaration for the shipment, 02 = one per package (default)
hazmat.transport_mode Transport method: Ground, CAO (Cargo Aircraft Only), PAX (Passenger Aircraft), Highway
hazmat.emergency_phone 24-hour emergency response phone number
hazmat.emergency_contact Emergency contact name
hazmat.all_packed_in_one Set true if all hazmat items are packed in one package
hazmat.overpack Set true if the package is an overpack
hazmat.q_value Q-value for IATA AllPackedInOne (0.1–1.0)
hazmat.outer_packaging_type Outer packaging type description (shipping labels only)
hazmat.chemical_records Array of chemical records (max 3 per package for UPS)

Chemical Record Fields#

Each entry in chemical_records supports the following fields:

Parameter Description
identifier Unique identifier for this chemical record within the package
regulation_set Per-chemical regulation set, overrides hazmat_regulation_set
regulated_level_code FR (fully regulated), LQ (limited quantity), LR (lightly regulated), EQ (excepted quantity)
id_number UN/NA/ID number (e.g., UN3480)
proper_shipping_name DOT proper shipping name
technical_name Technical/chemical name
class_division_number Hazard class (e.g., 9, 3, 4.1)
sub_risk_class Subsidiary risk class
packaging_group Packing group (I, II, or III)
quantity Quantity of the hazardous material
uom Unit of measure (e.g., kg, ml)
packaging_instruction_code Packaging instruction code (e.g., 965)
packaging_type Type of inner packaging
packaging_type_quantity Number of inner packages
hazard_label Hazard label required indicator
reportable_quantity Reportable quantity indicator (e.g., RQ)
additional_description Additional description text
transport_category Transport category
tunnel_restriction_code Tunnel restriction code (e.g., D/E)

Hazmat Shipping Labels#

To create a hazmat shipping label use the SubmitShipment action with the hazmat object on the package. The outer_packaging_type field is only used for shipping labels, not rating.

{
  "carrier": "UPS-REST",
  "action": "SubmitShipment",
  "params": {
    "account_number": "YOUR_ACCOUNT_NUMBER",
    "key": "YOUR_UPS_API_KEY",
    "service": "03",
    "hazmat_regulation_set": "CFR",
    "packages": [
      {
        "weight": 25,
        "length": 10,
        "width": 10,
        "height": 10,
        "hazmat": {
          "transport_mode": "Ground",
          "emergency_phone": "8005551234",
          "emergency_contact": "Hazmat Response Team",
          "all_packed_in_one": true,
          "overpack": true,
          "q_value": "0.5",
          "outer_packaging_type": "FIBERBOARD BOX",
          "chemical_records": [
            {
              "identifier": "1",
              "regulation_set": "CFR",
              "regulated_level_code": "FR",
              "id_number": "UN3480",
              "proper_shipping_name": "Lithium ion batteries",
              "technical_name": "Lithium Ion",
              "class_division_number": "9",
              "sub_risk_class": "4.1",
              "packaging_group": "II",
              "quantity": "6",
              "uom": "kg",
              "packaging_instruction_code": "965",
              "packaging_type": "Fiberboard Box",
              "packaging_type_quantity": "1",
              "hazard_label": "Y",
              "reportable_quantity": "RQ",
              "additional_description": "Limited Quantity",
              "transport_category": "0",
              "tunnel_restriction_code": "D/E"
            }
          ]
        }
      }
    ],
    "shipper": "RocketShipIt",
    "ship_addr1": "123 Main St",
    "ship_city": "Whitehall",
    "ship_state": "MT",
    "ship_code": "59759",
    "ship_phone": "1231231234",
    "ship_country": "US",
    "to_name": "John Doe",
    "to_addr1": "940 Presidio Ave",
    "to_addr2": "#103",
    "to_state": "CA",
    "to_city": "San Francisco",
    "to_code": "94115",
    "to_country": "US",
    "test": true
  }
}

Hazmat Rating#

To get rates that include Dangerous Goods surcharges, use the GetAllRates action with the same hazmat object on the package. This is useful for quoting accurate shipping costs for orders containing hazardous materials like lithium batteries.

The request is nearly identical to the label request. The only differences are:

  • action is GetAllRates instead of SubmitShipment
  • outer_packaging_type is not used for rating
{
  "carrier": "UPS-REST",
  "action": "GetAllRates",
  "params": {
    "account_number": "YOUR_ACCOUNT_NUMBER",
    "key": "YOUR_UPS_API_KEY",
    "service": "03",
    "hazmat_regulation_set": "CFR",
    "packages": [
      {
        "weight": 25,
        "length": 10,
        "width": 10,
        "height": 10,
        "hazmat": {
          "transport_mode": "Ground",
          "emergency_phone": "8005551234",
          "emergency_contact": "Hazmat Response Team",
          "all_packed_in_one": true,
          "overpack": true,
          "q_value": "0.5",
          "chemical_records": [
            {
              "identifier": "1",
              "regulation_set": "CFR",
              "regulated_level_code": "FR",
              "id_number": "UN3480",
              "proper_shipping_name": "Lithium ion batteries",
              "technical_name": "Lithium Ion",
              "class_division_number": "9",
              "sub_risk_class": "4.1",
              "packaging_group": "II",
              "quantity": "6",
              "uom": "kg",
              "packaging_instruction_code": "965",
              "packaging_type": "Fiberboard Box",
              "packaging_type_quantity": "1",
              "hazard_label": "Y",
              "reportable_quantity": "RQ",
              "additional_description": "Limited Quantity",
              "transport_category": "0",
              "tunnel_restriction_code": "D/E"
            }
          ]
        }
      }
    ],
    "shipper": "RocketShipIt",
    "ship_addr1": "123 Main St",
    "ship_city": "Whitehall",
    "ship_state": "MT",
    "ship_code": "59759",
    "ship_phone": "1231231234",
    "ship_country": "US",
    "to_name": "John Doe",
    "to_addr1": "940 Presidio Ave",
    "to_addr2": "#103",
    "to_state": "CA",
    "to_city": "San Francisco",
    "to_code": "94115",
    "to_country": "US",
    "test": true
  }
}

The response will include rates with any applicable Dangerous Goods surcharges. You can inspect the rate_detail array on each rate to see itemized charges.

Multiple Chemical Records#

You can include up to 3 chemical records per package for UPS. Each record can have its own regulation_set — if omitted, it falls back to the top-level hazmat_regulation_set.

"chemical_records": [
  {
    "identifier": "1",
    "regulation_set": "CFR",
    "regulated_level_code": "FR",
    "id_number": "UN3480",
    "proper_shipping_name": "Lithium ion batteries",
    "class_division_number": "9",
    "quantity": "6",
    "uom": "kg",
    "packaging_instruction_code": "965",
    "packaging_type": "Fiberboard Box",
    "packaging_type_quantity": "1"
  },
  {
    "identifier": "2",
    "regulated_level_code": "LQ",
    "id_number": "UN1088",
    "proper_shipping_name": "Acetal",
    "class_division_number": "3",
    "packaging_group": "II",
    "quantity": "100",
    "uom": "ml",
    "packaging_instruction_code": "Y341",
    "packaging_type": "Fiberboard Box",
    "packaging_type_quantity": "1"
  }
]

Note that the second record does not set regulation_set — it will use the value from hazmat_regulation_set at the request level.

Shipper's Declaration Paperwork#

For fully regulated dangerous goods UPS can generate the required Dangerous Goods shipping papers (Shipper's Declaration) along with the label. To receive them, set the signatory parameters at the request level:

"hazmat_signatory_name": "Jane Smith",
"hazmat_signatory_title": "Compliance Manager",
"hazmat_signatory_place": "Whitehall"

The paperwork is returned as one or more PDF documents in the response alongside the label:

"documents": [
  {
    "code": "dg_paper",
    "type": "application/pdf",
    "media": "JVBERi0xLjQg..."
  }
]

FedEx#

The examples above use UPS-REST. FedEx supports the same package-level hazmat object, but only for rating. Use GetAllRates with carrier FedEx-REST to quote Dangerous Goods surcharges:

{
  "carrier": "FedEx-REST",
  "action": "GetAllRates",
  "params": {
    "account_number": "YOUR_ACCOUNT_NUMBER",
    "key": "YOUR_FEDEX_API_KEY",
    "packages": [
      {
        "weight": 25,
        "length": 10,
        "width": 10,
        "height": 10,
        "hazmat": {
          "transport_mode": "Ground",
          "emergency_phone": "8005551234",
          "emergency_contact": "Hazmat Response Team",
          "all_packed_in_one": true,
          "chemical_records": [
            {
              "identifier": "1",
              "regulated_level_code": "FR",
              "id_number": "UN3480",
              "proper_shipping_name": "Lithium ion batteries",
              "class_division_number": "9",
              "packaging_group": "II",
              "quantity": "6",
              "uom": "kg",
              "packaging_instruction_code": "965",
              "packaging_type": "Fiberboard Box",
              "packaging_type_quantity": "1"
            }
          ]
        }
      }
    ],
    "ship_city": "Whitehall",
    "ship_state": "MT",
    "ship_code": "59759",
    "ship_country": "US",
    "to_state": "CA",
    "to_code": "90210",
    "to_country": "US",
    "test": true
  }
}

How FedEx interprets the parameters#

  • regulated_level_code selects the FedEx dangerous goods option: FR is HAZARDOUS_MATERIALS, LQ is LIMITED_QUANTITIES_COMMODITIES, EQ is SMALL_QUANTITY_EXCEPTION and LR is ORM_D. Any other value is treated as HAZARDOUS_MATERIALS.
  • reportable_quantity also adds the REPORTABLE_QUANTITIES option. Accepted values are RQ, Y, N, true and false.
  • transport_mode of CAO marks the package cargo aircraft only. PAX and CAO also set the aircraft accessibility. Ground and highway modes leave accessibility unset, because it is an air-only concept.
  • packaging_type and packaging_type_quantity describe the container. FedEx holds these once per container, so the first chemical record that sets them wins for the whole package.
  • All chemical records for one package are sent as a single FedEx container.
  • quantity must be a number and packaging_type_quantity must be a whole number. RocketShipIt rejects the request with an error naming the field if they are not.

These fields are accepted for UPS but have no FedEx equivalent, and are ignored on FedEx requests: q_value, hazard_label, reference_number, transport_category, tunnel_restriction_code, adr_item_number, adr_packing_group_letter, local_proper_shipping_name, local_technical_name, outer_packaging_type, and the per-record regulation_set (FedEx infers it from the service and destination).

FedEx hazmat labels#

FedEx does not accept chemical records on its Ship API. Its label request takes only the dangerous goods classification, and expects the commodity data to already be registered against your FedEx account. So SubmitShipment with a hazmat object does not produce a hazmat label the way it does for UPS.

What does work for FedEx labels today is lithium batteries. Set battery.type on the package to LITHIUM_ION or LITHIUM_METAL and RocketShipIt sends the Dangerous Goods special service with the battery option, declared as IATA Section II packed in equipment:

"packages": [
  {
    "weight": 5,
    "battery": {
      "type": "LITHIUM_ION"
    }
  }
]

For any other FedEx hazmat label, use request customization to add the dangerousGoodsDetail block your account requires, and talk to your FedEx account representative about enabling dangerous goods shipping.

International Hazmat#

This section applies to UPS. International dangerous goods shipments use the same hazmat parameters combined with the usual international shipping parameters (customs/commodity data). For air transport set the regulation set to IATA and the transport mode to PAX (passenger aircraft) or CAO (cargo aircraft only):

"hazmat_regulation_set": "IATA",
"packages": [
  {
    "hazmat": {
      "transport_mode": "CAO",
      ...
    }
  }
]

Include the signatory parameters above so the Shipper's Declaration required for air transport is returned with the label. Note that your UPS account must be enabled for international Dangerous Goods shipping — contact your UPS account representative if you receive entitlement errors.

API Examples#