> ## Documentation Index
> Fetch the complete documentation index at: https://firespark.cloud/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Create order

> Create an open customer order for the current selling scope.

Creates an `OPEN` order for the authenticated customer, or returns the existing open cart for the same scope. Owned channels typically POST an empty order with scope, then [update](https://firespark.cloud/docs/storefront-api/orders/\[id]/patch) as the cart changes.

> [!NOTE]
>
> Requires a Storefront API access token from [Token
> exchange](https://firespark.cloud/docs/storefront-api/oauth/exchange/post.md).

## Request body

| Field | Required | Type | Description |
| - | - | - | - |
| `id` | Yes | string | External order id you assign. Must be unique per merchant. 1–64 characters. |
| `store_id` | Yes | string | External store identifier |
| `channel_id` | Yes | string | External channel identifier |
| `fulfillment_id` | Yes | string | External fulfillment option |
| `brand_id` | No | string | External brand identifier when ordering under a specific brand |
| `is_anonymous` | No | boolean | Guest checkout flag. Defaults to `false`. |
| `customer` | Yes | object | Customer snapshot stored on the order (`customer_info`, optional address/billing). Built by the channel/SDK — Fire spark does not load the customer row. |
| `lines` | No | array | Priced order lines (`OrderLine`). Defaults to `[]`. |
| `totals` | No | object | Order totals. Defaults to zeros. |
| `metadata` | No | object | Channel-specific metadata. Defaults to `{}`. |
| `redeem` | No | array | Order redeems. Each needs `payment_id` (an active `REDEMPTION` payment) and `amount`; `before_taxes` defaults to `true`. Defaults to `[]`. |
| `redemption_steps` | No | array | Applied redeems in order. The server recomputes and stores them from `lines`, `totals` and `redeem`. Defaults to `[]`. |

Payments are not part of create. Save them later with [Save payment intent](https://firespark.cloud/docs/storefront-api/orders/\[id]/payment-intent/put). `payment_status` starts at `IDLE`.

## Request

```bash theme={null}
curl -X POST "https://firespark.cloud/api/storefront/v1/orders" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "ord-48291",
    "brand_id": "0001",
    "store_id": "downtown",
    "channel_id": "app",
    "fulfillment_id": "delivery",
    "is_anonymous": false,
    "customer": {
      "customer_info": {
        "display_name": "Ada Lovelace",
        "first_name": "Ada",
        "last_name": "Lovelace",
        "email": "ada@example.com",
        "phone": "+15551234567"
      }
    },
    "lines": [],
    "totals": {
      "currency": "USD",
      "subtotal": 0,
      "discount_rate": 0,
      "discount_total": 0,
      "tax_rate": 0,
      "tax_total": 0,
      "total": 0
    },
    "metadata": {
      "cart_session_id": "sess_abc123"
    }
  }'
```

## Response

The body is always `{ data: Order }`. Use the status to tell create from reuse:

| Status | Meaning |
| - | - |
| `201` | Created a new `OPEN` order |
| `202` | An `OPEN` order already exists for this customer + store + channel + fulfillment + brand. `data` is that cart — adopt its `id` |

One customer can have only one `OPEN` cart per scope. Concurrent POSTs do not create a second cart.

> [!TIP]
>
> Generate the external `id` on your server before calling POST so you can retry
> if the network fails. A retry with a new id still returns `202` and the
> existing cart when the scope already has an `OPEN` order. Duplicate ids on a
> different (non-open) order still return `422`. `@fire-spark/core` `Order.create`
> builds the `customer` snapshot from name/email/phone.

## Error responses

| Status | Description |
| - | - |
| `401` | Missing or invalid access token |
| `422` | Invalid body or duplicate order id |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.