# Calculate Shipping Costs With the ShipStation API Rates endpoint, you can get shipping rates for multiple carrier and service options. You can then select the desired service for the shipment based on the response or display these at checkout to let your customers choose the fastest, cheapest, or most-trusted service. If you are new to ShipStation API, make sure you have the following first: - An active ShipStation API account. You can [sign up here](https://www.shipengine.com/signup/) if you haven't already. - Your ShipStation [API key](/apis/shipengine/docs/guides/auth#api-keys) (a [sandbox API key](/apis/shipengine/docs/guides/auth#types-of-api-keys) will work for the steps provided below). - A [tool to make an API call](/apis/shipengine/docs/getting-started/tools), like [curl](/apis/shipengine/docs/guides/curl) or [Postman](/apis/shipengine/docs/reference/postman). There are multiple methods available for getting rates, each with their own use cases: 1. [Find rates with `shipment` details](#find-rates-using-shipment-details) 2. [Find rates with `shipment_id`](#find-rates-using-shipment-id) 3. [Find Rates with Package Types](#find-rates-with-package-types) 4. [Find Rates with Service Codes](#find-rates-with-service-codes) 5. [Find Rates with both Service Codes and Package Types](#find-rates-with-service-codes-and-package-types) ## Requirements No matter which method you use, you’ll always need the `carrier_ids`, which will be included in the `rate_options` object. You can get rates for one or multiple carrier IDs. [List carriers](/apis/shipengine/docs/reference/list-carriers) to locate your carrier IDs. There may also be additional requirements, depending on which method you use. ## About the /rates/ Endpoint **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](/apis/shipengine/docs/labels/create-from-rate). - You can also choose to validate the address as part of the rate request to help ensure you receive the most-accurate rates possible. There are three address validation options: - `no_validation` - This is the default option and *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. ## Find Rates Using Shipment Details **Requirements:** - `carrier_ids` - `shipment` object ### Sample Request In this example, the `shipment` details uses the `no_validation` value in the `validate_address` property. ```http 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": "The President", "phone": "222-333-4444", "company_name": "", "address_line1": "1600 Pennsylvania Avenue NW", "city_locality": "Washington", "state_province": "DC", "postal_code": "20500", "country_code": "US", "address_residential_indicator": "no" }, "ship_from": { "name": "ShipStation API Team", "phone": "222-333-4444", "company_name": "ShipStation API corp.", "address_line1": "4301 Bull Creek Road", "city_locality": "Austin", "state_province": "TX", "postal_code": "78731", "country_code": "US", "address_residential_indicator": "no" }, "packages": [ { "package_code": "package", "weight": { "value": 6, "unit": "ounce" } } ] } } ``` ## Find Rates Using Shipment ID If you've already [created a shipment](/apis/shipengine/docs/shipping/create-a-shipment), then you can pass the `shipment_id` instead of the full shipment details. **Requirements:** - `carrier_ids` - `shipment_id` for a previously created shipment. ### Sample Request ```http 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" ] } } ``` > **IMPORTANT:** You can pass *either* the full `shipment` details *or* a `shipment_id`, but you cannot pass both in the same request. ## Find Rates with Package Types Use this method to filter the response by a specific set of package types. If no package type is specified, the *default* package type for that carrier is used, not all package types. **Requirements:** - `carrier_ids` - `shipment_id` or `shipment` details - `package_types` object and desired values ### Sample Request ```http 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" ] } } ``` ## Find Rates with Service Codes Use this method to filter the response by a specific set of service codes. If no service code is specified, *all* service codes are returned. **Requirements:** - `carrier_ids` - `shipment_id` or `shipment` details - `service_codes` object and desired values ### Sample Request ```http 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" ], "package_types": [] } } ``` ## Find Rates with Service Codes and Package Types Use this method to filter the resonse by a combination of service codes and package types. **Requirements:** - `carrier_ids` - `shipment_id` or `shipment` details - `package_types` object and desired values - `service_codes` object and desired values ### Sample Request ```http 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" ] } } ``` ## Overview of Custom Rate Shopper You are not limited to `cheapest`, `fastest`, and `best_value` IDs. Custom configurations created in the ShipStation UI can be triggered via the API. ### Custom Rate Shopper Rules In addition to the default strategies, you can trigger custom Rate Shopper rules created in your ShipStation account. To set up a custom rule, go to **Settings > Shipping > Rate Shopper** in the ShipStation UI. You can create rules from scratch or start from a recommended configuration. Once created, use the rule's name or ID as the rate_shopper_id in the API request. The following settings dictate how the custom rate shopper functions: **Delivery Time Constraints**: Restricts eligible services to those with a carrier delivery estimate within a set number of days (calculated using only business days starting from the day after the ship date). - If no estimate is provided by the carrier, the service is not eligible. **Service Preferences**: Allows a preferred service to be used even if it isn't the cheapest, provided it is within a defined cost threshold of the cheapest service. **AU/NZ Account Capabilities**: Allows for comparisons between Custom and Standard package types for accounts based in Australia and New Zealand. ### Example Request and Payload This example shows how you pass the custom rule `rate_shopper_id`. ```http POST /v1/labels/rate_shopper_id/{rate_shopper_id} HTTP/1.1 Host: api.shipstation.com API-Key: __YOUR_API_KEY_HERE__ Content-Type: application/json { "shipment": { "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": { "name": "John Doe", "company_name": "Example Corp", "phone": "111-111-1111", "address_line1": "4009 Marathon Blvd", "city_locality": "Austin", "state_province": "TX", "postal_code": "78756", "country_code": "US" }, "packages": [{ "weight": { "value": 20, "unit": "ounce" }, "dimensions": { "height": 6, "width": 12, "length": 24, "unit": "inch" } }] }, "label_format": "pdf", "label_layout": "4x6" } ``` ### Best Practices and Troubleshooting - **Rule Requirements**: Ensure the custom rule is published in the ShipStation UI. - **Service Exclusion**: Do not include `carrier_id`, `service_code`, or `shipping_rule_id` inside the `shipment` object, or the API will return a 400-level validation error. - **Error Responses**: If the custom rule cannot find a matching service based on the criteria (such as a Deliver-by Date restriction), the system returns a **404 - Rate Shopper could not find a matching service** error. - **Preference Bounds**: This Service Preference relies on a "less than" calculation (e.g., if the rule is set for a maximum of $1.00 more, it applies to any rate that is $0.99 or less above the cheapest rate). ## About the Response The response returns a list of rates from your connected carriers along with related shipment data. For domestic U.S. shipments, the first three rates typically include a `rate_attributes` object that highlights the best value, cheapest, and fastest options for quick comparison. The rates are then sorted from cheapest to most expensive. When you make this call, a shipment object is automatically created with a `shipment_id`, allowing you to update it and retrieve new rates before purchasing a label. To explore optional functionality, see the [advanced rating features guide.](/apis/shipengine/docs/rates/advanced-features) ### Rate Attributes A single rate may have multiple attributes applied however each attribute only exists once in the response. The following table defines the possible rate attributes and their meanings: | Rate Attribute | Description | | --- | --- | | `best_value` | Lowest cost option arriving on a specified date within 4 days, with free carrier coverage up to $100 and a free dropoff option. | | `cheapest` | Lowest cost option | | `fastest` | Fastest delivery option | ### Itemized Rate Breakdown 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. ### Rate Details Object You may want some additional details about the rates in the response. When it's available, we provide this additional information in the `rate_details` object. Here is the structure: | Property | Description | | --- | --- | | `rate_detail_type` | Normalized type for the additional rate information. These types are enumerated as: `uncategorized`, `shipping`, `insurance`, `confirm`, `discount`, `fuel_charge`, `additional_fees`, `tariff`, `tax`, `delivery`, `handling`, `special_goods`, `pickup`, `location_fee`, `oversize`, `returns`, `notifications`, `tip`, `duties_and_taxes`, `brokerage_fee`, `admin_fee`, `adjustment` | | `carrier_description` | Plain text description of the rate detail as provided by the carrier. | | `carrier_billing_code` | Code for the billing type provided by the carrier. | | `carrier_memo` | Additional text regarding this charge. Usually null. | | `amount` | The `currency` and `amount` of the detailed charge | The `rate_details` object should match the total of the `shipment_amount`, `insurance_amount`, `confirmation_amount`, and `other_amount` when it is provided. > **TIP:** ### Don't want to wait for rates? ShipStation API supports asynchronous requests using [webhooks](/apis/shipengine/docs/guides/webhooks). However, **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. ### Sample Response The response can be lengthy depending on how many carriers you requested rates for. This sample response excludes all but one. ```json { "rate_response": { "rates": [ { "rate_id": "se-321654", "rate_type": "shipment", "carrier_id": "se-123890", "shipping_amount": { "currency": "usd", "amount": 10.1 }, "insurance_amount": { "currency": "usd", "amount": 0.0 }, "confirmation_amount": { "currency": "usd", "amount": 0.0 }, "other_amount": { "currency": "usd", "amount": 1.52 }, "rate_details": [ { "rate_detail_type": "fuel_charge", "carrier_description": "FedEx Ground Fuel", "carrier_billing_code": null, "carrier_memo": null, "amount": { "currency": "usd", "amount": 1.52 }, "billing_source": "Carrier" }, { "rate_detail_type": "shipping", "carrier_description": "Total Net Freight", "carrier_billing_code": null, "carrier_memo": null, "amount": { "currency": "usd", "amount": 10.1 }, "billing_source": "Carrier" } ], "zone": 6, "package_type": null, "delivery_days": 3, "guaranteed_service": false, "estimated_delivery_date": "2023-04-28T23:59:00Z", "carrier_delivery_days": "3", "ship_date": "2023-04-25T00:00:00Z", "negotiated_rate": false, "service_type": "FedEx Ground®", "service_code": "fedex_ground", "trackable": true, "carrier_code": "fedex", "carrier_nickname": "My FedEx account", "carrier_friendly_name": "FedEx", "validation_status": "has_warnings", "warning_messages": [ "FedEx may add a Home Delivery Surcharge to this shipment later if this is a residential address." ], "error_messages": [], "rate_attributes": [ "best_value", "fastest", "cheapest" ] } ] "invalid_rates": [], "rate_request_id": "se-987", "shipment_id": "se-12345", "created_at": "2023-04-25T22:44:33.8102925Z", "status": "completed", "errors": [] }, "shipment_id": "se-12345", "carrier_id": "se-123890", "service_code": null, "external_shipment_id": null, "shipment_number": null, "ship_date": "2023-04-25T00:00:00Z", "created_at": "2023-04-25T22:44:32.887Z", "modified_at": "2023-04-25T22:44:32.88Z", "shipment_status": "pending", "ship_to": { "instructions": null, "name": "The President", "phone": "222-333-4444", "company_name": "", "address_line1": "1600 Pennsylvania Avenue NW", "address_line2": null, "address_line3": null, "city_locality": "Washington", "state_province": "DC", "postal_code": "20500", "country_code": "US", "address_residential_indicator": "no" }, "ship_from": { "instructions": null, "name": "ShipStation API Team", "phone": "222-333-4444", "company_name": "ShipStation API corp.", "address_line1": "4301 Bull Creek Road", "address_line2": null, "address_line3": null, "city_locality": "Austin", "state_province": "TX", "postal_code": "78731", "country_code": "US", "address_residential_indicator": "no" }, "warehouse_id": null, "return_to": { "instructions": null, "name": "ShipStation API Team", "phone": "222-333-4444", "company_name": "ShipStation API corp.", "address_line1": "4301 Bull Creek Road", "address_line2": null, "address_line3": null, "city_locality": "Austin", "state_province": "TX", "postal_code": "78731", "country_code": "US", "address_residential_indicator": "no" }, "is_return": false, "confirmation": "none", "customs": { "contents": "merchandise", "contents_explanation": null, "customs_items": [], "non_delivery": "return_to_sender", "buyer_shipping_amount_paid": null, "duties_paid": null, "terms_of_trade_code": null, "declaration": null, "invoice_additional_details": { "freight_charge": null, "insurance_charge": null, "other_charge": null, "discount": null }, "importer_of_record": null }, "external_order_id": null, "order_source_code": null, "advanced_options": { "bill_to_account": null, "bill_to_country_code": null, "bill_to_party": null, "bill_to_postal_code": null, "contains_alcohol": false, "delivered_duty_paid": false, "non_machinable": false, "saturday_delivery": false, "dry_ice": false, "dry_ice_weight": null, "fedex_freight": null, "third_party_consignee": false, "ancillary_endorsements_option": null, "freight_class": null, "custom_field1": null, "custom_field2": null, "custom_field3": null, "collect_on_delivery": null, "return_pickup_attempts": null, "additional_handling": false }, "insurance_provider": "none", "tags": [], "packages": [ { "shipment_package_id": "se-65432", "package_id": "se-3", "package_code": "package", "package_name": "Package", "weight": { "value": 6.00, "unit": "ounce" }, "dimensions": { "unit": "inch", "length": 0.0, "width": 0.0, "height": 0.0 }, "insured_value": { "currency": "usd", "amount": 0.00 }, "label_messages": { "reference1": null, "reference2": null, "reference3": null }, "external_package_id": null, "content_description": null, "products": [] } ], "total_weight": { "value": 6.00, "unit": "ounce" }, "items": [] } ``` ## Automatic Label Creation with Rate Shopper Once you understand how rate shopping works, you might want to automate the entire process. The **Rate Shopper** feature eliminates the need to manually review rates and select one — it automatically chooses and purchases a label based on your strategy in a single API call. ### How It Works Instead of making two separate calls (one for rates, another for label creation), Rate Shopper: 1. Gets rates from all your wallet carriers 2. Selects the optimal rate based on your chosen strategy 3. Purchases the label automatically 4. Returns the completed label with details about which carrier and service were selected ### When to Use Rate Shopper | Scenario | Recommended Approach | | --- | --- | | **Automated fulfillment workflows** where you want consistent, hands-off carrier selection | ✅ Use Rate Shopper | | **Displaying rates to customers** at checkout for them to choose | ❌ Use manual rate shopping (`POST /v1/rates`) | | **Reviewing options** before committing to a carrier | ❌ Use manual rate shopping (`POST /v1/rates`) | | **High-volume shipping** with clear cost or speed priorities | ✅ Use Rate Shopper | ### Available Strategies The `rate_shopper_id` determines which carrier and service will be selected: - **`cheapest`**: Best for non-urgent shipments where cost savings are the priority - **`fastest`**: Best for time-sensitive shipments where speed matters most - **`best_value`**: Best for balancing reasonable speed (within 4 days) without excessive cost > **Learn more**: See [Create a Label with Rate Shopper](/apis/shipengine/docs/labels/create-a-label#automated-carrier-selection-with-rate-shopper) for implementation details and examples.