---
title: "Read an order"
method: GET
path: "/orders/{orderId}"
tags: ["Orders"]
---

# Read an order

`GET /orders/{orderId}`

## Request

- Base URL: `https://api.layout.link/v1`
- URL: `https://api.layout.link/v1/orders/{orderId}`
- Auth: one of:
  - HTTP bearer
  - HTTP bearer

An application secret reads any order this application caused. A connected person's token reads only that person's orders this application drove, in the same shape. A build grant reads only an order a build grant from this application built for the same person, in the same environment. An order belonging to another application or another person is a 404, never a 403.

## Path parameters

- `orderId` string, required

## Headers

- `Layout-Version` '2026-10-01'

## Response `200`

The order.

- Order
  - `id` string, required
  - `state` 'building' | 'carted' | 'placing' | 'placed' | 'failed' | 'unconfirmed' | 'refunded', required
  - `store` string, nullable, required
  - `store_address` string, nullable, required: The address of that store, when Layout knows it.
  - `items` integer, required
  - `total_minor` integer, nullable, required: Minor units. 2140 is $21.40.
  - `currency` string, required
  - `created_at` string, required
  - `placed_at` string, nullable, required
  - `ready_eta` string, nullable, required: The pickup time as the store stated it, word for word, when the store states one. Layout reads it from the store's confirmation screen and its email, so it can arrive after `placed`, with an `order.updated` event. Null until then, and null for good when the store never states a time; the person then goes by the store's own confirmation. Show it as written; it is not a timestamp.
  - `failure_code` string, nullable, required: A stable machine code, never prose. Read it only when `state` is `failed` or `unconfirmed`: an order still `placing` can carry one before it settles, so switch on `state` first. One of `LOGIN_REQUIRED`, `SITE_BLOCKED`, `RATE_LIMITED`, `ITEM_UNAVAILABLE`, `SITE_ERROR`, `STORE_CLOSED`, `PICKUP_TIME_EXPIRED`, `CHECKOUT_NOT_FOUND`, `ORDERING_PAGE_NOT_FOUND`, `CLOSED_NEXT_DAY`, `MARKETPLACE_ONLY`, `APP_ONLY_ORDERING`, `ACCOUNT_VERIFICATION_REQUIRED`, `CART_DRIFTED`, `CARD_DECLINED`, `CARD_REMOVED`, `PAYMENT_REJECTED`, `OUR_TIMEOUT`, `OUR_ERROR`, `UNCONFIRMED`, `UNKNOWN`, `USER_CANCELED`, `STAFF_STOPPED`, `SESSION_EXPIRED`, `SUPERSEDED_BY_CHANGE`. Treat any value you do not recognise as `UNKNOWN`.
  - `simulated` true: Present and true on a sandbox order that was simulated. Absent on every real order.
  - `fulfillment` Fulfillment, required
    - `type` 'pickup' | 'delivery', required: How the person gets the order. A delivery that never got a driver becomes `pickup`, with `changed_from` set; tell the person to collect it.
    - `name` string, nullable, required: The name the store has the order under, as its own confirmation stated it. What the person says at the counter.
    - `address` string, nullable, required: Where the person collects it. For pickup, the same as `store_address`. For delivery, the street line it is going to.
    - `ready_text` string, nullable, required: The pickup time word for word, the same as `ready_eta`. Show it as written; it is not a timestamp.
    - `merchant_order_number` string, nullable, required: The store's own number for the order, not Layout's id.
    - `instructions` string, nullable, required: The store's own pickup instructions, word for word.
    - `status` 'finding_courier' | 'heading_to_store' | 'at_store' | 'on_the_way' | 'arriving' | 'delivered' | 'failed'
    - `eta` string, nullable: Delivery only: when it should arrive, ISO 8601, once known.
    - `courier` object, nullable: Delivery only: the driver, while one is assigned. Cleared once the delivery ends.
      - `first_name` string, nullable, required
      - `vehicle` string, nullable, required
    - `proof_photo_url` string, nullable: Delivery only: the driver's photo of the order at the door, once delivered and left there. Show it as proof of delivery.
    - `failure_reason` string, nullable: Delivery only: why the delivery could not be completed, in words you can show the person. Set when `status` is `failed`.
    - `changed_from` 'delivery', nullable: Set when a delivery became a pickup because no driver could be booked.
  - `lines` OrderLine[], required: What was ordered, as the cart was built. Layout's derived tax-and-fees line is not a line.
    - `name` string, required
    - `quantity` integer, required
    - `unit_price_minor` integer, nullable, required: Per item, when the store's cart priced it.
    - `modifiers` string[], required
  - `amounts` OrderAmounts, required
    - `subtotal_minor` integer, nullable, required: The store's own subtotal, when it stated one.
    - `tax_minor` integer, nullable, required: The store's own tax, when it stated it.
    - `merchant_total_minor` integer, nullable, required: The store's total, the same as `total_minor`.
    - `service_fee_minor` integer, required: Layout's service fee.
    - `service_fee_waived` boolean, required: True when the person's plan waives the fee: it is shown but not charged.
    - `credit_minor` integer, required: Layout credit taken off the charge.
    - `courier_fee_minor` integer, required: The delivery fee charged, at cost. 0 for pickup, and 0 when no driver delivered.
    - `tip_minor` integer, required: The driver's tip charged, all of it to the driver. 0 for pickup, and 0 when no driver delivered.
    - `charged_minor` integer, nullable, required: What the person's card was charged for the placed order: the store's total, plus the fee unless waived, plus any delivery fee and tip, less credit. Null until `state` is `placed`, and on a simulated order. A later refund is not netted here.

## Other responses

- `400`: `unsupported_version`: the Layout-Version header names no version this API answers.
- `401`: The secret or token was not recognised, or is expired or revoked.
- `403`: `unauthorized`: the application may not do this. `insufficient_scope`: a token not granted this scope.
- `404`: No such order for this application.
- `429`: A per-minute ceiling.
- `500`: Layout failed to answer. Retry with backoff.
- `503`: Layout or a dependency could not be reached. Retry with backoff.

---

[API](https://skmtc.dev/layout/apis/layout-partner-api.md) · [All operations](https://skmtc.dev/layout/apis/layout-partner-api/llms.txt) · [OpenAPI document](https://skmtc.dev/layout/apis/layout-partner-api/revisions/7ff4ba01bf56?raw)
