Creating orders
Submit orders in bulk, and read the per-order result correctly.
Overview
An Order is a request to ship something to someone. It carries the addresses, the lines, and the routing — a rate group or a carrier service — that decides how it ships.
Two things about order.create differ from the other create mutations:
- It takes a list of orders.
- It returns OrderCreationResult, not
Order— a per-order success flag. A partial failure is a successful response.
Before you create an order
An order cannot be created in isolation. You need:
| Prerequisite | Why | Where |
|---|---|---|
| Items | Order lines resolve by sku or item_id | Creating items |
Creating orders
mutation CreateOrders($orders: [OrderInput!]!) {
order {
create(orders: $orders) {
external_order_id
success
error_message
order {
id
external_order_id
}
}
}
}
{
"orders": [
{
"external_order_id": "SO-10432",
"shipping_address": {
"attention_first_name": "Dana",
"attention_last_name": "Reyes",
"street": ["1200 Market St", "Suite 400"],
"city": "Philadelphia",
"state_code": "PA",
"postal_code": "19107",
"country_code": "US",
"residential": true
},
"billing_address": {
"attention_first_name": "Dana",
"attention_last_name": "Reyes",
"street": ["1200 Market St", "Suite 400"],
"city": "Philadelphia",
"state_code": "PA",
"postal_code": "19107",
"country_code": "US"
},
"order_lines": [
{
"quantity": 2,
"identifier": { "sku": "WIDGET-BLUE-01" },
"sell_price": "24.99"
}
]
}
]
}
Required fields
| Field | Type | Description |
|---|---|---|
external_order_id | String! | Your order number. This is how results are keyed back. |
shipping_address | AddressInput! | Where it goes. |
billing_address | AddressInput! | Who is billed. |
order_lines | [OrderLineInput!]! | What is on the order. Must not be empty. |
NOTE
AddressInput names its fields
postal_code, state_code and country_code, and splits the recipient into
attention_first_name / attention_last_name or company_name — not zip, state,
country or name. Every field on it is optional at the type level; the carrier decides
what is actually needed.
Order lines
Each line names a quantity and an identifier. The identifier is a
OrderLineIdentifierInput — supply
either sku or item_id:
{
"quantity": 2,
"identifier": { "sku": "WIDGET-BLUE-01" },
"sell_price": "24.99",
"discount": "2.00"
}
sku matches against item SKUs and item aliases, so a marketplace's own identifier
resolves without translation on your side — see
aliases.
Handling the result
order.create returns one result per submitted order. Some can succeed while others fail,
and the HTTP status is still 200 with no errors key. Inspect each result individually.
{
"data": {
"order": {
"create": [
{
"external_order_id": "SO-10432",
"success": true,
"error_message": null,
"order": { "id": "a58f2d04-6b39-4c17-9e85-1d7b30f2a9c6" }
},
{ "external_order_id": "SO-10433", "success": false, "error_message": "No item matching sku WIDGET-RED-99", "order": null }
]
}
}
}
Results are keyed by external_order_id, which is why that field is required — match on it
rather than on array position.
WARNING
A 200 response does not mean every order was created. Check success on each element
of the returned list.
Dates and holds
| Field | Effect |
|---|---|
first_ship_date | Order will not ship before this date. |
last_ship_date | Order should ship by this date. |
order_batch_id | Groups orders for batch processing. |
To hold an order after creation:
mutation HoldOrders($orders: [SetOrderHoldStatusInput!]!) {
order {
set_order_hold_status(orders: $orders) {
id
external_order_id
}
}
}
Updating orders
Three different shapes, depending on what you are changing:
| Operation | Use for |
|---|---|
order.update | Per-order changes, each with its own values |
order.bulk_update | One set of changes applied to many order ids |
order.update_order_ship_to_address | Correcting a delivery address |
Addresses have their own mutations because changing one re-triggers address validation.
Sub-resources
Parts of an order that are managed separately, each with create / update / delete:
order.order_line— add or amend lines after creationorder.item_bundle— bundles on the orderorder.customs— customs declarationorder.commercial_invoice— commercial invoiceorder.extra_service— insurance, signature, and similar
Cancelling
mutation CancelOrders($orders: [ID!]!) {
order {
cancel_order(orders: $orders) {
id
external_order_id
}
}
}
International orders
Customs information comes from three separate places, and they are not alternatives — each covers something the others do not.
| Layer | Carries | Set on |
|---|---|---|
| Item customs | Per-commodity data: hs_code, country_of_origin, USMCA origin criterion | The item, reusable across orders |
| Order customs | The whole declaration: parties, declared and insured value, commercial invoice, AES / ITAR / FICE, incoterms | The order, via customs |
| Workflows | Defaults applied by a customs_information action when a trigger fires | A workflow on the account |
Set customs on the order for anything crossing a border:
{
"customs": {
"export_reason": "SOLD",
"incoterms": "DDP",
"duties_prepaid": true,
"taxes_prepaid": true,
"usmca_applies": false
}
}
OrderCustomsInput is much wider than
that — exporter, importer and seller parties, override_total_declared_value,
insured_value, commercial_invoice, and the export-control blocks.
Workflows and customs
A workflow's customs_information action can insert or update the order's customs
declaration after the order is created — any OrderCustoms column may be given, and
overwrite decides whether it replaces values the order already carries. Nothing runs at
import until a workflow is triggered, so an order created through the API carries exactly
the customs data you send until one does.
NOTE
Workflows do not read item customs data. hs_code and country_of_origin
come from each item's own customs record and are
declared per commodity; a workflow only supplies shipment-level values.
Finding orders again
Orders are searchable under the ORDER entity type:
query FindOrders($search: PaginatedSearchQuery) {
searches {
order {
search(search: $search) {
rows {
id
external_order_id
}
next_cursor
has_next_page
}
}
}
}
See Searching for filters, sorting and pagination.
Next
Rating →