> Part of [WHCC Developer Documentation](https://www.whcc.com/developer/llms.txt)

# Shipping

Version 1.5 &middot; Updated 2026-10-08

Every call to `POST /v1/commerce/submissions` and `POST /v1/commerce/submissions/calculate` needs a `shipping` object, and both accept the same values. The one difference is that `shipping.address` is optional on calculate, so you can price a basket before checkout collects an address (see [Response Bodies](https://www.whcc.com/developer/docs/api/responses/#calculate-no-address)).

## The `shipping` object

- **`address`** (object, required on submit): Where the order ships: `name`, `addr1`, `addr2`, `city`, `state`, `zip`, `country` (2-letter code), and optionally `attn` (an attention line), `email` and `phone`. There is no `company` field: sending one returns `400`. International destinations may also need a `phone` in E.164 format, for example `+15551234567`. Optional on calculate only.Every address needs `name`, `addr1` and `city`. Send `country` every time too: an address without one is read as a US address, not reported as incomplete. A US address also needs a 2-letter `state` and a `zip` of at least 5 characters. Outside the US, `state` and `zip` are optional. Submit with a field missing and you get a `400` (`submission.not_submittable`) with one `invalidParams[]` entry per field, named like `shipping.address.zip`. Calculate with a partial address still answers `200`, with `validation.isValidForSubmit: false` and the same entries in `validation.invalidParams[]`, so you can check an address before you submit. A `zip` under 5 characters or a 1-letter `state` also makes `isValidForSubmit` false, with an entry whose reason gives the length rule (`Must be at least 5 characters.`, `Must be 2 characters.`). See [what WHCC checks](https://www.whcc.com/developer/docs/api/shipping/#address-checks).
- **`type`** (string, optional): `dropship` ships straight to your customer. `studio` ships to you. Leave it out and it defaults to `dropship`, or follows `priority` when you send one: `studio_*` means `studio`, `dropship_*` means `dropship`. If you send both, they must agree. If your account can't use that type for these products, the request is rejected with a `400` naming `shipping.type`.Studio shipping goes to US and Canadian street addresses only: not to a PO Box, and not outside the US and Canada.
- **`priority`** (string, optional): The shipping method. Which methods a basket can use depends on the type, the address and the products in it, so take the value from `options.shipping[]` on a calculate response for that address ([see below](https://www.whcc.com/developer/docs/api/shipping/#options)). Leave it out and WHCC uses the least expensive method the destination offers. A priority from the other type, or one the destination doesn't offer, is rejected with a `400` (see the note at the end of this page).

## Which methods an address offers

Call calculate with the basket, `shipping.type` and the address, and no `priority`. The response prices the basket with the least expensive method for that destination, and `options.shipping[]` lists every method the address offers, each with its price:

```json
{
	"shippingType": "dropship",
	"shippingPriority": "dropship_lowest_cost",
	"options": {
		"shipping": [
			{ "id": "dropship_lowest_cost", "type": "dropship", "priority": "dropship_lowest_cost", "label": "Economy", "price": { "value": "7.95", "code": "USD" } },
			{ "id": "dropship_expedited", "type": "dropship", "priority": "dropship_expedited", "label": "Expedited", "price": { "value": "20.61", "code": "USD" } },
			{ "id": "dropship_one_day_standard", "type": "dropship", "priority": "dropship_one_day_standard", "label": "Standard One-Day", "price": { "value": "31.34", "code": "USD" } },
			{ "id": "dropship_one_day_priority", "type": "dropship", "priority": "dropship_one_day_priority", "label": "Priority One-Day", "price": { "value": "40.48", "code": "USD" } }
		]
	}
}
```

Show your customer the `label` and `price` of each entry. To ship with one of them, send its `priority` as `shipping.priority` on submit, with the same `type`. To take the cheapest, leave `priority` out. Either way, `shippingType` and `shippingPriority` on the response tell you what the order is using, and `totalPrice.subtotals.shipping.label` names it. See [Response Bodies](https://www.whcc.com/developer/docs/api/responses/#calculate).

A few things to expect from the list:

- It changes with the destination, and some destinations offer a single method. Don't carry a priority from one address to another; ask calculate again.
- A priority names a level of service, not a carrier or a delivery date. For a territory, Canada or another country the `label` can name the carrier.
- Calculate without an address returns no `options.shipping[]`, because the choices depend on where the order is going (see [calculating with no address](https://www.whcc.com/developer/docs/api/responses/#calculate-no-address)).

## Calculate prices the basket now. The order sets the charge.

Calculate returns the current price for the items and address you send. The amount you're billed is set by WHCC's order system when it places the order, from the same pricing, so for most US addresses the two match. Nothing in the response marks a value as provisional, and the price isn't held between calculate and submit. For a US territory or an address outside the US, expect gaps: shipping to Puerto Rico can show `0.00` with the description "Actual Postage", and sales tax depends on the destination: money for a US state, and for Canada when the address has a province and a `zip`; `0.00` for Alaska and the US territories; and the string `"TBD"` for Canada without a province or `zip`, for an APO/FPO address, and for any other country, so `totalPrice.value` doesn't include it. An order to Canada adds the import surtax under `subtotals.surcharges.delivery`. See [Response Bodies](https://www.whcc.com/developer/docs/api/responses/#submission-root-fields).

## What WHCC checks on an address

Calculate and submit check that the required fields are present. They don't verify that the address exists, that the `zip` belongs to the `state`, or that `phone` and `email` are well formed. Validate the address in your own checkout before you send it.

- `country` left out or empty is treated as `US`, with no `invalidParams[]` entry for it. The US rules for `state` and `zip` then apply. A code that isn't a real country is not rejected: it is priced as an international destination.
- `country` and `state` are accepted in either case and returned as you sent them. Send codes, not names: a name such as `United States` or `Minnesota` returns `400`.
- Calculate puts no limit on the length of `name`, `addr1`, `addr2` or `city` and doesn't screen their characters: markup, emoji and control characters come back as sent. Labels print from the Windows-1252 character set (see [Metadata & Reference](https://www.whcc.com/developer/docs/api/metadata/#reference)), so send plain text that fits on a label.
- A `state` or `zip` WHCC can't place leaves sales tax as `"TBD"`. A `"TBD"` response doesn't carry the `submission.pricing.total_excludes_tax` guidance note.
- A US address with a PO Box in `addr1` is offered a single `dropship` method, and no `studio` method.

> **If you send both `type` and `priority`, make them agree.** A priority belongs to the type in its name: `dropship_*` to `dropship`, `studio_*` to `studio`. A pair that disagrees is rejected with a `400` whose `invalidParams[]` names both `shipping.type` and `shipping.priority`. A value that isn't shaped like any priority is rejected the same way, naming `shipping.priority`.
>
> A well-formed priority that the destination doesn't offer (one from a Canadian address sent with a US address, say) is also rejected once you've sent an address: `400` with `code: "submission.shipping_priority_unsupported"`, and the reason lists the priorities of the same shipping type that are available, if there are any. The list can be missing even when other priorities are on offer. Calculate without an address never fails this check. To avoid it, [ask calculate](https://www.whcc.com/developer/docs/api/shipping/#options) what the address offers and pick from that.

> ### What's Next
>
> See the submission shape this produces on [Response Bodies](https://www.whcc.com/developer/docs/api/responses/#submission), or how to carry your own order identifiers alongside it on [Metadata & Reference](https://www.whcc.com/developer/docs/api/metadata/index.html.md).