# Carts confirmed elsewhere

October 2, 2026 · API

The person can confirm your cart without you: a YES to Layout's cart-ready text, the Layout app, or Layout's tracking page. Your confirm on that cart now says so, names the order and its state now, and never sends a second order.

## What changed

- `POST /v1/carts/:id/confirm` and `/confirm/resend-code` on a cart whose order was already confirmed answer `409 already_confirmed`. Nothing is confirmed or charged again. `error.order` is `{ id, status, confirmedVia? }`, where `status` is `placing`, `placed`, `unconfirmed` or `refunded`, and `error.userMessage` is a sentence for the person.
- `confirmedVia` is `sms` (a YES to Layout's text) or `tracking_link` (Layout's tracking page) when Layout knows, on the error and on `GET /v1/carts/:id`'s `order` for a `closed` cart. It is absent for a confirm in the Layout app or through the API or MCP.
- A retry of your own confirm with the same `idempotencyKey` still gets the answer that call earned.
- The MCP `order` tool's `confirm` result carries `alreadyConfirmed: true`, `orderState` and, when known, `confirmedVia`, plus `complete: false` and `nextAction: "order_status"` while the order is `placing` or `unconfirmed`.

```
409 {
  "error": {
    "code": "already_confirmed",
    "message": "This cart was already confirmed by the person replying YES to Layout's text, so nothing was confirmed or charged again. It is placing now. Read GET /v1/orders/ord_7c21e4b9a0d3, and do not confirm or build this order again.",
    "orderId": "ord_7c21e4b9a0d3",
    "order": { "id": "ord_7c21e4b9a0d3", "status": "placing", "confirmedVia": "sms" },
    "userMessage": "This order was already confirmed and is being placed now. Nothing extra was charged."
  }
}
```

## Why it matters

A confirm that lost to the person's own YES used to answer `202 placing` as if your call had placed it, even once the order was placed. On an order whose placement Layout could not verify, it answered `409 cart_closed` and suggested building a new cart, which is how a person ends up with two orders. Now your application can show the person what actually happened.

## What to do

On `already_confirmed`, show `error.userMessage`, follow the order with `GET /v1/orders/:id` or the `order.*` webhooks, which go out whichever surface confirmed it, and do not confirm or build it again. Treat `unconfirmed` as pending, never as failed. See [Already confirmed elsewhere](https://developer.layout.link/reference/carts#confirmed-elsewhere) and [Errors](https://developer.layout.link/reference/errors).

## Breaking changes

None under the [versioning policy](https://developer.layout.link/reference/versioning): `already_confirmed` is a new error code on a 409. One answer moves: a confirm that lost the race to another surface used to answer `202 placing`, and an already confirmed cart whose order is `unconfirmed` or `refunded` used to answer `409 cart_closed`. Both now answer `409 already_confirmed` with the same order id.
