Skip to main content

Rates

What a Rate is​

A Rate is a pricing/service result returned for a Shipment in the current request and available Account/carrier context. It is not a booking, reservation, purchased service, permanent quote, standalone public CRUD resource, or persisted selection.

Get Rates​

There are two public paths to Rate results:

Packed is not a prerequisite for either path.

Select a Rate for Label purchase​

Shipment
-> Rate results
-> client selects rateId
-> Label purchase request

The client selects a returned rateId and supplies it to the Label purchase request. Retain that value only as needed for the current workflow. Selecting a Rate is not documented as a mutation of Mailhub state.

See Labels for the bounded Label operation behavior. Use Select a Rate for the application-owned selection step.

Public Rate fields​

A Get Rates call returns several Rates. Each one is a JSON object, and id is the field that matters for the rest of the workflow: it is the value you keep and send back when buying the Label. The other fields describe the option so your application can choose between them.

A Rate is a returned decision result, not something you create. Your application decides which one to use: Mailhub does not mark one as recommended, fastest, or cheapest, and the order of the response is not a ranking.

The selected id travels in a nested rate object on the Label-purchase request — there is no flat rate.id key:

{ "rate": { "id": "c4a1b2d3-..." } }
FieldClassificationPublic meaning
idIDENTIFIERReturned Rate identifier. A selected returned id is supplied for the Label-purchase workflow.
ratePRICEReturned Rate price value.
currencyCURRENCYReturned currency value associated with rate.
carrierCARRIER_DISPLAYReturned carrier display value.
serviceCodeSERVICE_CODEReturned machine-facing carrier service code.
serviceNameSERVICE_DISPLAYReturned human-readable service name, for display.

For the complete Rate response schema, including all optional fields and types, see the API Reference.

Public monetary amounts are JSON numbers, not strings — rate here, and selectedRate.rate, selectedRate.retailRate and selectedRate.listRate on a Label purchase. Read them as numbers and format them yourself for display: the wire value carries the amount, not its presentation, so do not rely on a trailing zero or on a fixed number of decimal places being present.

serviceCode is provider-dependent. Do not hard-code or parse it, and do not build against a fixed list of values — the public contract does not define one. Recognize a service by its returned serviceName, and carry the returned id into the Label-purchase workflow.

Service code and service name​

Each returned Rate carries two values that describe the same carrier service:

FieldRole
serviceCodeThe carrier service code. Machine-facing.
serviceNameThe name of that service, human-readable and meant for display.

A successful Label purchase echoes the Rate it used back as selectedRate. selectedRate.service carries that Rate's serviceCode value, not its serviceName:

Rate
serviceCode ---------------> selectedRate.service
serviceName --- display only

selectedRate.service is returned metadata describing the Rate that was purchased. It is not a request field: the Label purchase identifies the Rate by rate.id alone. See Buy a Label.

Transit time and delivery dates​

Four Rate fields describe timing, and they answer fewer distinct questions than their names suggest.

FieldWhat it is
deliveryDaysCarrier-supplied transit estimate, in days
estDeliveryDaysThe same estimate — always the same number as deliveryDays
estimatedDeliveryDateDate the carrier expects to deliver on, or null
deliveryDateGuaranteedWhether the carrier guarantees that date

deliveryDays and estDeliveryDays always carry the same value. Every carrier integration fills both from one quantity, so there is no committed-versus-estimated distinction to read between them. Use either; do not compare them to each other, and do not treat deliveryDays as a commitment. deliveryDateGuaranteed is the only field that says whether anything is guaranteed.

0 means the carrier supplied no transit time for that Rate — it does not mean same-day delivery. Some carriers return no transit figure at all, so 0 is a normal value to receive.

The day basis is the carrier's own. One carrier reports business days in transit; another derives a span from its own quoted delivery window. Mailhub passes the number through without normalizing it, so the same integer from two carriers is not necessarily comparable. Do not compute a delivery date from it — read estimatedDeliveryDate, which is null when the carrier supplied none.

On a Label purchase, selectedRate.deliveryDate is this same estimatedDeliveryDate value under a different name.

Result interpretation​

More than one Rate result can be returned. The client makes the selection for its own workflow.

Do not infer cheapest, best, recommended, or otherwise ranked meaning from the response order unless a future public contract explicitly defines one.

Validity and outcomes​

There is no Rate validity period, and no expiry timestamp. A Rate carries no TTL, the contract publishes none, and nothing in Mailhub rejects a Rate identifier for age. Do not build a countdown against a fixed number of minutes — no such number exists.

What does make a Rate identifier stop working is re-rating the same Shipment. Requesting Rates for a Shipment replaces that Shipment's Rate set, so identifiers returned by an earlier call for the same Shipment no longer resolve. The one exception is a Rate a label purchase is already running against, which is retained until that purchase settles. A purchase naming a Rate that is gone fails with 404 and the error code Rate.NotFound.

Beyond that, the carrier is the authority at purchase time: Mailhub forwards the purchase, and a price the carrier will no longer honour is refused by the carrier, not by Mailhub. So: request Rates, and buy from that same set. If a purchase fails because the Rate is gone or the carrier declines it, request Rates again and buy from the new set rather than retrying the old identifier.

For V1, a successful response can contain rates: []. Inspect carrierResponses when it is present in the response, together with the public response envelope. This page does not assign a complete diagnostic meaning to that field.

For Create an Order with Rates, the documented 422 response can represent an invalid Order or a case where no carrier could rate the Shipment.

See Rate Errors for the documented error guidance.