Skip to main content

Estimate Sales Order Shipping

POST 

/api/sales-orders/:salesOrder/shipping-estimates

Rates the sales order's product lines with the account's own EasyPost connection and records the run as an estimate. Parcels are built from product weights and dimensions (case packs first, then loose units), from each line's warehouse to the order's shipping address. Nothing on the order changes until a rate is applied.

Required scope: orders:write

Grant this scope to your token under Settings → Developer → Personal Access Tokens.

Request body (all optional — send {} to rate the order as it stands):

  • origin_warehouse_id (integer, nullable): rate every item from this warehouse instead of each line's own warehouse.
  • parcels (array, max 50, nullable): override the parcels built from product weights and dimensions. Each parcel: weight_oz (number, required, > 0, max 2400 = 150 lb), length_in / width_in / height_in (number, optional, > 0, max 108).
  • refresh (boolean): bypass the 15-minute rate cache.

Response (data):

  • status: ok, not_connected (no EasyPost connection), key_rejected (the EasyPost API key was refused), missing_package_data (some products have no weight — listed in missing_weight_products), no_origin_address (the shipping warehouse has no complete address), no_destination (no ship-to address), no_items (no product lines), no_rates (no carrier returned a rate) or rating_failed (EasyPost could not rate the shipment; try again). Only ok carries options; every status comes back as 200 with a human-readable message.
  • mode: production or test — the mode of the EasyPost key that rated the shipment (test keys return list rates).
  • currency: the order's currency; every amount is converted to it. original_amount / original_currency are what the carrier quoted.
  • options[]: one per carrier service, cheapest first — key (<carrier>|<service>, pass it as option_key when applying), carrier, service, carrier_account_id, amount, currency, original_amount, original_currency, delivery_days, and origins[] (the per-warehouse share when the order ships from several warehouses: warehouse_id, warehouse_name, amount, currency, parcels). A service is offered only when every origin warehouse can use it.
  • warnings[]: notes such as products rated on a default weight or a missing exchange rate.
  • missing_weight_products[]: {id, sku, name} of products with no weight.
  • shipments[]: what was rated per origin warehouse — warehouse_id, warehouse_name, from address, parcels[] (weight_oz, length_in, width_in, height_in) and total_weight_oz.
  • quoted_at, request_hash, estimate_id: when it was rated, a fingerprint of the rated request, and the recorded estimate's id (use it in the apply endpoint).
  • defaults: the account's default markup (markup_type percent or flat, markup_value) used when applying without an explicit markup.
  • subject: the current Shipping lines that a rate would replace (existing_shipping_lines[]: id, description, quantity, amount, tax_rate), the current total, currency, the new_line_tax_rate a new Shipping line would carry and is_tax_included.

Identical requests within 15 minutes reuse the cached rates; send refresh: true to re-rate.

Only orders on the local channel or the B2B portal channel can be quoted. A channel order, or one that is cancelled, closed or invoiced, is refused with 422.

Authentication: Requires Bearer token.

Requires permission: sales_orders.update

Request​

Responses​

OK

Response Headers
    Content-Type