Orders
create_order
destructive writeCreate order
Record an order bought through a custom integration, so Sign Customiser hands its designs to production.
Overview
Records an order from an enabled custom integration. Call get_store first. Select an integration where accepts_writes is true. Use this tool only for an order that already exists in that integration. Sign Customiser does not call the integration to verify it. Send its external order id and number, grand total, currency, optional customer and address snapshots, and line items. Each line item references a product already recorded by create_integration_product by its Sign Customiser product id. Creating the order durably schedules the Store's established follow-on effects: the manufacturer order emails, order analytics, the order.created webhook and onboarding synchronisation. An email to a real manufacturer cannot be recalled, so the call needs confirm: true and an idempotency_key that makes an exact repeat replay the original response without scheduling those effects again. It records an order; it takes no payment and collects no card data. It requires the orders:write scope.
Permission
Requires theorders:writepermission. A connection without it answersinsufficient_scopenaming the permission to approve.
Annotations
Prerequisites
- Every product on the order already recorded by create_integration_product, so its Sign Customiser product_id exists.
- An integration_id for an enabled custom integration. Call get_store and select one where accepts_writes is true.
- The store contact email must be set in the merchant admin, or the manufacturer hand-off has nowhere to send.
- A merchant has connected this store and approved the orders:write scope.
Side effects
- Creates one order and its line items against the store.
- Schedules the manufacturer order emails, which reach a real manufacturer and cannot be recalled.
- Records the order in the store analytics.
- Delivers the order.created webhook to every subscription for that topic.
- Runs onboarding synchronisation for the store.
- Uses order-write budget based on the durable hand-off work.
- Claims the idempotency_key for at least 24 hours.
Arguments
An enabled custom integration from get_store where accepts_writes is true. store_order_id is unique within it. An unknown, disabled or non-custom integration is a validation failure on this field.
The order identifier the integration uses. It must be unique within the integration. A repeat fails with store_order_id_conflict and does not create a second order.
The order number the shopper and the merchant see.
The grand total in integer minor units. Sign Customiser derives its own total from the stored unit prices, so this never overrides the fee basis.
The ISO 4217 code in upper case. It must equal the store currency and the currency of every referenced product.
The shipping method the shopper chose, as free text.
The customer snapshot the integration supplied. Personal data: repeat only what the merchant asked for.
The billing address snapshot. Every member is optional. Personal data.
The delivery address snapshot, which is what reaches the manufacturer hand-off. Every member is optional. Personal data.
Between 1 and 100 line items. A line item carries no title, price or design: those come from the product it references.
The Sign Customiser product id create_integration_product returned. Not the integration own identifier, and distinct across the order.
How many of that product were bought.
Must be true to apply the change, because recording the order schedules the manufacturer emails and the order.created webhook, and an email that has been sent cannot be recalled. Without it the call returns a confirmation_required error and changes nothing. A dry run does not need it.
A client-generated key unique to this logical write, such as a UUID. Required: repeating the call with the same key and the same arguments replays the original result instead of writing twice, and the same key with different arguments is an idempotency_key_conflict. A dry run claims no key.
Result
The created order with its line items, and whether the call replayed an earlier one. The response does not enumerate the hand-off effects it scheduled. There is no dry run: the route has no validate twin.
The created order with its line items, as get_order publishes it.
True when this call replayed an earlier write carrying the same idempotency_key. A replay schedules no further hand-off effects.
Error cases
Send confirm: true. The manufacturer emails this schedules cannot be recalled.
currency must equal the store currency and the currency of every referenced product.
That key was used with different arguments. Re-send the original arguments or issue a new key.
The first call with this key is still running. Wait retry_after seconds and send the identical call again.
The created order was later deleted. Issue a new key and re-check the resource before writing again.
The connection was approved without orders:write.
Send idempotency_key. It is required for this write.
The store contact email is not set. It has to be completed in the merchant admin before an order can be recorded.
The store order-write budget is exhausted; wait retry_after seconds.
This integration already has an order with this store_order_id. Retry the original request with its original idempotency_key, or use a new store_order_id.
The integration_id is unknown, disabled, or does not accept recorded products or orders. Correct the field at the error pointer. Other invalid request fields can also produce this code.
Record a one-line order
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "create_order",
"arguments": {
"integration_id": 3,
"store_order_id": "ext-ord-4471",
"store_order_number": "#4471",
"total_amount": 24900,
"currency": "GBP",
"shipping_method": "Tracked 48",
"customer": {
"first_name": "Ada",
"last_name": "Lovelace",
"email": "ada@example.com"
},
"line_items": [
{
"product_id": 5001,
"quantity": 1
}
],
"confirm": true,
"idempotency_key": "0718293a-4b5c-4f30-8a4b-5c6d7e8f9012"
}
}
}{
"jsonrpc": "2.0",
"id": 1,
"result": {
"structuredContent": {
"request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t",
"store": {
"id": 12,
"name": "Demo Signs"
},
"order": {
"id": 8801,
"store_order_id": "ext-ord-4471",
"store_order_number": "#4471",
"status": "received",
"status_display_name": "Received",
"total_amount": 24900,
"currency": "GBP",
"shipping_method": "Tracked 48",
"line_items": [
{
"id": 9901,
"store_product_id": "ext-90210",
"customiser_id": 42,
"title": "Custom neon sign — \"Open\"",
"quantity": 1,
"unit_price_amount": 24900,
"currency": "GBP"
}
],
"created_at": "2026-08-24T00:00:00Z",
"updated_at": "2026-08-24T00:00:00Z"
},
"idempotent_replay": false
}
}
}Without confirmation no order is recorded and no email is sent (error)
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "create_order",
"arguments": {
"integration_id": 3,
"store_order_id": "ext-ord-4471",
"store_order_number": "#4471",
"total_amount": 24900,
"currency": "GBP",
"line_items": [
{
"product_id": 5001,
"quantity": 1
}
],
"idempotency_key": "0718293a-4b5c-4f30-8a4b-5c6d7e8f9012"
}
}
}{
"jsonrpc": "2.0",
"id": 1,
"result": {
"isError": true,
"structuredContent": {
"error": {
"code": "confirmation_required",
"title": "Confirmation required",
"detail": "Recording order ext-ord-4471 schedules the manufacturer order emails and the order.created webhook, and an email that has been sent cannot be recalled.",
"recovery": "This operation changes something consequential. Send confirm: true once the merchant has agreed to it.",
"parameter": "confirm",
"allowed_values": [
"true"
]
}
}
}
}