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 a blueprint_id that decides how the order gets fulfilled and shipped.
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 |
| A blueprint | blueprint_id is required and drives fulfillment and shipping | Creating blueprints |
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",
"blueprint_id": "3d7c6a15-9e28-4b70-8c31-5f0a2e94d6b1",
"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. |
blueprint_id | ID! | Which blueprint fulfills and ships this order. |
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 |
| Customs blueprint | Defaults for eight order-customs fields | The blueprint |
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. The blueprint does
not cover those; they are order-level only.
What a customs blueprint actually does
A customs blueprint initializes
eight fields on the order's customs information: comments, export_reason,
duties_prepaid, taxes_prepaid, incoterms, usmca_applies, aes_exemption and
itar_license_or_exemption_number.
Each is configured on the blueprint as a value plus an allow_overwrite flag, which
defaults to false. So by default the blueprint only fills a field the order left
unset — a value you send on the order wins. Setting allow_overwrite: true inverts that for
that one field, and the blueprint's value replaces whatever the order supplied.
NOTE
A customs blueprint does not read item customs data. hs_code and country_of_origin
come from each item's own customs record and are
declared per commodity; the blueprint only supplies shipment-level defaults.
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 →