Skip to main content

Create an Order with Rates

POST/api/v2/orders Open this operation in the API Reference.

Mailhub provides two Order creation operations. Use standard Order creation when you want to create the Order first and request Rates later. Use Create an Order with Rates when you want Mailhub to create the Order and immediately request Rates for its Shipments in the same API call.

Compare the creation choices​

BehaviorPOST /api/v1/ordersPOST /api/v2/orders
CreatesOne OrderOne Order
Request bodyOrder fields at the top levelRequired top-level order wrapper
Rates during creationNoYes, for each created Shipment
Success response201 created Order200 created Order plus shipmentRates
Typical next stepRequest Shipment RatesSelect a returned Rate
Label purchaseSeparateSeparate

Both operations create the same public Order resource. The create-and-rate operation uses the same underlying Order-creation workflow, then requests Rates for each created Shipment. One Order can contain one or more Shipments.

Request​

The request accepts exactly one Order under the required order property. It is one Order per request, not a batch operation, and does not accept an orders array.

{
"order": {
"fromAddress": {
"name": "Jane Sender",
"street1": "123 Main St",
"city": "Austin",
"state": "TX",
"zip": "78701",
"country": "US",
"phone": "5125550100"
},
"toAddress": {
"name": "John Recipient",
"street1": "456 Oak Ave",
"city": "Denver",
"state": "CO",
"zip": "80202",
"country": "US",
"phone": "3035550100"
},
"shipments": [
{"parcel": {"weight": 16, "length": 10, "width": 8, "height": 4}}
]
}
}

See Create an Order for the verified address and parcel requirements.

Read the response​

The order in a successful 200 response is the created Order. shipmentRates is grouped by Shipment: each entry identifies a created Shipment and contains that Shipment's returned Rate results. Your application chooses a returned rate.id; Mailhub does not select a Rate or buy a Label in this operation.

Use the selected Rate with Buy label. That remains a separate operation. Do not infer a preferred Rate from response order.

Complete success response​

Every field below is one the public contract declares for this operation. The carrier, serviceCode, and serviceName values are illustrative — see Carrier Availability.

{
"success": true,
"data": {
"status": "created",
"order": {
"id": "5f2c1a10-2b3d-4e5f-8a9b-0c1d2e3f4a5b",
"status": 0,
"isReturn": false,
"createdAt": "2026-08-20T14:31:07.482Z",
"updatedAt": "2026-08-20T14:31:07.482Z",
"fromAddress": {
"id": "8c5e0f14-7a2b-4d36-9e81-2f6a4b90c7d3",
"name": "Jane Sender",
"company": null,
"street1": "123 Main St",
"street2": null,
"city": "Austin",
"state": "TX",
"zip": "78701",
"country": "US",
"phone": "5125550100",
"email": null,
"residential": null,
"federalTaxId": null,
"stateTaxId": null,
"carrierFacility": null,
"createdAt": "2026-08-20T14:31:07.482Z",
"updatedAt": "2026-08-20T14:31:07.482Z"
},
"toAddress": {
"id": "2d90a7b6-3f18-4e52-8c47-6b1d0e35f9a2",
"name": "John Recipient",
"company": null,
"street1": "456 Oak Ave",
"street2": null,
"city": "Denver",
"state": "CO",
"zip": "80202",
"country": "US",
"phone": "3035550100",
"email": null,
"residential": null,
"federalTaxId": null,
"stateTaxId": null,
"carrierFacility": null,
"createdAt": "2026-08-20T14:31:07.482Z",
"updatedAt": "2026-08-20T14:31:07.482Z"
},
"shipments": [
{
"id": "b91a2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
"status": "Unknown",
"isReturn": false,
"createdAt": "2026-08-20T14:31:07.482Z",
"updatedAt": "2026-08-20T14:31:07.482Z",
"fromAddress": {
"id": "8c5e0f14-7a2b-4d36-9e81-2f6a4b90c7d3",
"name": "Jane Sender",
"company": null,
"street1": "123 Main St",
"street2": null,
"city": "Austin",
"state": "TX",
"zip": "78701",
"country": "US",
"phone": "5125550100",
"email": null,
"residential": null,
"federalTaxId": null,
"stateTaxId": null,
"carrierFacility": null,
"createdAt": "2026-08-20T14:31:07.482Z",
"updatedAt": "2026-08-20T14:31:07.482Z"
},
"toAddress": {
"id": "2d90a7b6-3f18-4e52-8c47-6b1d0e35f9a2",
"name": "John Recipient",
"company": null,
"street1": "456 Oak Ave",
"street2": null,
"city": "Denver",
"state": "CO",
"zip": "80202",
"country": "US",
"phone": "3035550100",
"email": null,
"residential": null,
"federalTaxId": null,
"stateTaxId": null,
"carrierFacility": null,
"createdAt": "2026-08-20T14:31:07.482Z",
"updatedAt": "2026-08-20T14:31:07.482Z"
},
"parcel": {
"id": "7e41b3c8-5d69-4a02-9b7f-1c8e2a604d5b",
"weight": 16,
"length": 10,
"width": 8,
"height": 4,
"predefinedPackage": null,
"createdAt": "2026-08-20T14:31:07.482Z",
"updatedAt": "2026-08-20T14:31:07.482Z"
}
}
]
},
"shipmentRates": [
{
"shipmentId": "b91a2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
"rates": [
{
"id": "c4a1b2d3-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
"carrier": "USPS",
"carrierCode": null,
"serviceCode": "<carrier-specific service code>",
"serviceName": "USPS Ground Advantage",
"rate": 8.42,
"currency": "USD",
"listRate": 9.1,
"listCurrency": "USD",
"retailRate": 11.3,
"retailCurrency": "USD",
"deliveryDays": 3,
"estDeliveryDays": 3,
"deliveryDateGuaranteed": false,
"estimatedDeliveryDate": "2026-08-23T00:00:00Z",
"billingType": null,
"mailClass": null,
"zone": null,
"sku": null,
"rateIndicator": null,
"processingCategory": null,
"destinationEntryFacilityType": null
}
],
"carrierResponses": [
{"carrier": "USPS", "success": true, "errorCode": null, "errorMessage": null}
],
"errors": []
}
],
"errors": []
},
"errors": null
}

Two fields in this response are named status and they are not the same thing:

FieldWhat it is
data.statusA fixed acknowledgement for the combined create-and-rate call — always the string "created" on a 200. It is not an Order status, and it does not report whether Rates came back: a call that produced no Rates at all fails with a 422 instead of returning this response.
data.order.statusThe created Order's own fulfilment status, as the numeric OrderStatus value — 0 is Created. The same representation Update Order Status uses.

data.order.shipments[].status is a third, unrelated concept: a tracking-oriented Shipment status, published as a string, which stays "Unknown" in the current integration because tracking is not yet implemented.

Three errors arrays appear in this response and they are not the same thing:

FieldOn a 200
errors (envelope)null — the envelope's own failure list.
data.errors[].
data.shipmentRates[].errorsCan carry entries. One Shipment can fail to rate while another returns Rates, and the request still succeeds.

Read data.shipmentRates[].errors and carrierResponses per Shipment before treating a 200 as complete for every Shipment in the Order.

Optional fields are shown as null rather than omitted so the shape is unambiguous; the exact set a carrier populates varies. See API Conventions for the envelope rules.

No-Rate 422 outcome​

The public response does not promise an Order identifier or recovery sequence for this ambiguous state-changing outcome.

Next steps​