Calculate Shipping Costs

ShipEngine is a REST API that allows you to manage almost every facet possible for shipping. This tutorial will show you how to create a label.

Before you begin:

This article helps you to make a POST call to get shipping rates for your multiple carrier and service options. Display these at checkout to let your customers choose the fastest, cheapest, or most-trusted route when you ship your products.

Similar to the Quickstart: Create a Label we need to know some basic information to get a rate.

Requirements

To get rates, you must locate and include the following:

  1. A List Your Carriers.
  2. The carrier_id for those carriers.

Below are four ways to POST calls in JSON, the response returns you should see, and how to understand and use their results. These examples include:

  1. Find rates with shipment details
  2. Find rates with shipment_id
  3. Find Rates with Package Types
  4. Find Rates with Service Codes
  5. Find Rates with both Service Codes and Package Types

Examples

POST /v1/rates/

Given some shipment details and rate options, this endpoint returns a list of rate quotes. You can then Use a Rate to Print a Label.

Choose to validate the address as part of the rate request to help ensure that you get back the most-accurate rates possible. There are three address validation options:

Validation Option Description
no_validation This default option in ShipEngine does not validate addresses nor does it confirm the accuracy of an address.
validate_only Validates address accuracy but returns an error if the validation fails.
validate_and_clean Validates address accuracy and updates the address with recommended adjustments.

Example Requests

This JSON example passes shipment details and no_validation for the validate_address property in the POST call.

POST /v1/rates HTTP/1.1
Host: api.shipengine.com
API-Key: __YOUR_API_KEY_HERE__
Content-Type: application/json

{
  "rate_options": {
    "carrier_ids": [
      "se-123890"
    ]
  },
  "shipment": {
    "validate_address": "no_validation",
    "ship_to": {
      "name": "Amanda Miller",
      "phone": "555-555-5555",
      "address_line1": "525 S Winchester Blvd",
      "city_locality": "San Jose",
      "state_province": "CA",
      "postal_code": "95128",
      "country_code": "US",
      "address_residential_indicator": "yes"
    },
    "ship_from": {
      "company_name": "Example Corp.",
      "name": "John Doe",
      "phone": "111-111-1111",
      "address_line1": "4009 Marathon Blvd",
      "address_line2": "Suite 300",
      "city_locality": "Austin",
      "state_province": "TX",
      "postal_code": "78756",
      "country_code": "US",
      "address_residential_indicator": "no"
    },
    "packages": [
      {
        "weight": {
          "value": 1.0,
          "unit": "ounce"
        }
      }
    ]
  }
}

If you've already created a shipment, then you can pass the shipment_id instead of the full shipment details. This examples passes the shipment_id of a previously created shipment.

POST /v1/rates HTTP/1.1
Host: api.shipengine.com
API-Key: __YOUR_API_KEY_HERE__
Content-Type: application/json

{
  "shipment_id": "se-123",
  "rate_options": {
    "carrier_ids": [
      "se-123890"
    ]
  }
}

NOTE You can pass either the full shipment details or a shipment_id, but you cannot pass both in the same request.

Example Response

The response can be quite daunting depending on how many carriers you requested rates from.
We excluded all but one in our response below. As you can see, there's a lot of data that comes back in a response.

{
  "rate_response": {
    "rate_request_id": 501834,
    "shipment_id": "se-2127183",
    "status": "completed",
    "created_at": "2019-07-26T22:10:50.286Z",
    "rates": [
      {
        "rate_id": "se-11744390",
        "rate_type": "shipment",
        "carrier_id": "se-123890",
        "shipping_amount": {
          "currency": "usd",
          "amount": 9.37
        },
        "insurance_amount": {
          "currency": "usd",
          "amount": 0.00
        },
        "confirmation_amount": {
          "currency": "usd",
          "amount": 0.00
        },
        "other_amount": {
          "currency": "usd",
          "amount": 0.00
        },
        "delivery_days": 3,
        "guaranteed_service": false,
        "estimated_delivery_date": "2019-07-26T05:00:00.000Z",
        "carrier_delivery_days": "Friday by 11:00 PM",
        "ship_date": "2019-07-26T05:00:00.000Z",
        "negotiated_rate": false,
        "service_type": "UPS® Ground",
        "service_code": "ups_ground",
        "trackable": true,
        "validation_status": "valid",
        "warning_messages": [],
        "error_messages": [],
        "carrier_code": "ups",
        "carrier_nickname": "UPS-28A1R9",
        "carrier_friendly_name": "UPS"
      }
    ],
    "invalid_rates": []
  },
  "shipment_id": "se-2127183",
  "carrier_id": "",
  "external_shipment_id": null,
  "ship_date": "2019-07-26T05:00:00.000Z",
  "created_at": "2019-07-26T22:10:50.286Z",
  "modified_at": "2019-07-26T22:10:50.286Z",
  "shipment_status": "pending",
  "ship_to": {
    "name": "Amanda Miller",
    "phone": "555-555-5555",
    "address_line1": "525 S Winchester Blvd",
    "city_locality": "San Jose",
    "state_province": "CA",
    "postal_code": "95128",
    "country_code": "US",
    "address_residential_indicator": "yes"
  },
  "ship_from": {
    "company_name": "Example Corp.",
    "name": "John Doe",
    "phone": "111-111-1111",
    "address_line1": "4009 Marathon Blvd",
    "address_line2": "Suite 300",
    "city_locality": "Austin",
    "state_province": "TX",
    "postal_code": "78756",
    "country_code": "US",
    "address_residential_indicator": "no"
  },
  "return_to": {
    "company_name": "Example Corp.",
    "name": "John Doe",
    "phone": "111-111-1111",
    "address_line1": "4009 Marathon Blvd",
    "address_line2": "Suite 300",
    "city_locality": "Austin",
    "state_province": "TX",
    "postal_code": "78756",
    "country_code": "US",
    "address_residential_indicator": "no"
  },
  "confirmation": "none",
  "advanced_options": {
    "bill_to_account": null,
    "bill_to_country_code": null,
    "bill_to_party": null,
    "bill_to_postal_code": null,
    "contains_alcohol": false,
    "custom_field1": null,
    "custom_field2": null,
    "custom_field3": null,
    "non_machinable": false,
    "saturday_delivery": false
  },
  "insurance_provider": "none",
  "tags": [],
  "total_weight": {
    "value": 1.00,
    "unit": "ounce"
  },
  "packages": [
    {
      "weight": {
        "value": 1.00,
        "unit": "ounce"
      },
      "dimensions": {
        "unit": "inch",
        "length": 0.0,
        "width": 0.0,
        "height": 0.0
      },
      "insured_value": {
        "currency": "usd",
        "amount": 0.0
      }
    }
  ]
}

Each rate includes the itemized prices for:

Property Description
shipment_amount Cost of shipment only.
insurance_amount Cost to insure shipment.
confirmation_amount Cost to confirm shipment delivery.
other_amount Fees and surcharges from the carrier.

The total rate is the sum of all these amounts.

INFO

Don't want to wait for rates?

ShipEngine supports asynchronous requests using webhooks.

We recommend waiting if you need to display the rates as a 'next step' for your user, or if you're developing for a platform that does not support webhooks.

Example: Find Rates with Package Types

This example shows how to get rates that are filtered by a specific set of package types. If no package type is specified the the default package type for that carrier is used, not all package types.

POST /v1/rates HTTP/1.1
Host: api.shipengine.com
API-Key: __YOUR_API_KEY_HERE__
Content-Type: application/json

{
  "shipment_id": "se-123",
  "rate_options": {
    "carrier_ids": [
      "se-123890"
    ],
    "service_codes": [],
    "package_types": [
      "flat_rate_envelope",
      "medium_flat_rate_box"
    ]
  }
}

Example (Find Rates with service codes)

This example shows how to get rates that are filtered by a specific set of service codes. If no service code is specified then all service codes are returned.

POST /v1/rates HTTP/1.1
Host: api.shipengine.com
API-Key: __YOUR_API_KEY_HERE__
Content-Type: application/json

{
  "shipment_id": "se-123",
  "rate_options": {
    "carrier_ids": [
      "se-123890"
    ],
    "service_codes": [
      "usps_first_class_mail",
      "usps_priority_mail",
      "ups_next_day_air_early_am"
    ],
    "package_types": []
  }
}

Example (Find Rates with service codes and package types)

This example shows how to get rates that are filtered by a combination of service codes and package types.

POST /v1/rates HTTP/1.1
Host: api.shipengine.com
API-Key: __YOUR_API_KEY_HERE__
Content-Type: application/json

{
  "shipment_id": "se-123",
  "rate_options": {
    "carrier_ids": [
      "se-123890"
    ],
    "service_codes": [
      "usps_first_class_mail",
      "usps_priority_mail",
      "ups_next_day_air_early_am"
    ],
    "package_types": [
      "flat_rate_envelope",
      "medium_flat_rate_box"
    ]
  }
}