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

# Orders

> List and read orders.

`https://exclusivo.one/api/v1` · scopes `orders:read`, `orders:write`

## List orders

```http theme={"system"}
GET /api/v1/orders
```

Newest first.

| Parameter     | Type    | Default |                                          |
| ------------- | ------- | ------- | ---------------------------------------- |
| `limit`       | integer | `50`    | Max 100                                  |
| `cursor`      | string  | —       | An order id from `pagination.nextCursor` |
| `status`      | string  | —       | Filter by status                         |
| `customer_id` | string  | —       | Filter by customer                       |
| `start_date`  | date    | —       | On or after                              |
| `end_date`    | date    | —       | On or before                             |

<CodeGroup>
  ```bash cURL theme={"system"}
  curl "https://exclusivo.one/api/v1/orders?status=paid&limit=50" \
    -H "Authorization: Bearer ex_live_your_key_here"
  ```

  ```js JavaScript theme={"system"}
  const res = await fetch(
    'https://exclusivo.one/api/v1/orders?status=paid&limit=50',
    { headers: { Authorization: `Bearer ${process.env.EXC_API_KEY}` } }
  );
  const { data, pagination } = await res.json();
  ```
</CodeGroup>

```json Response theme={"system"}
{
  "data": [
    {
      "id": "ord_abc123",
      "status": "paid",
      "userId": "cus_xyz789",
      "total": "56.00",
      "currency": "AUD",
      "items": [
        { "productId": "prod_abc123", "name": "Ceramic Mug", "quantity": 2, "price": "28.00" }
      ],
      "shipping": { "…": "address and chosen option" },
      "fulfillment": { "…": "tracking, once a label is bought" },
      "createdAt": "2026-08-19T22:04:11.000Z"
    }
  ],
  "pagination": {
    "hasMore": true,
    "nextCursor": "ord_abc123",
    "count": 50
  }
}
```

<Warning>
  **All four filters apply to the page you got, not your whole order history.**

  A page of 50 orders containing 2 refunded ones returns `count: 2` while
  `hasMore` is still true. A short or empty page doesn't mean there's nothing left.

  Page until `hasMore` is false.
</Warning>

```js theme={"system"}
async function allOrders(filters = {}) {
  const out = [];
  let cursor = null;

  do {
    const qs = new URLSearchParams({ ...filters, limit: '100', ...(cursor ? { cursor } : {}) });
    const res = await fetch(`https://exclusivo.one/api/v1/orders?${qs}`, {
      headers: { Authorization: `Bearer ${process.env.EXC_API_KEY}` },
    });
    const { data, pagination } = await res.json();
    out.push(...data);
    cursor = pagination.hasMore ? pagination.nextCursor : null;
  } while (cursor);

  return out;
}
```

<Tip>
  Because filters are per-page, a narrow filter over a long history costs a lot of
  requests. For anything ongoing use a [webhook](/api/webhooks) —
  `order.created`, `order.paid`, `order.fulfilled`, `order.refunded` — and keep
  this endpoint for backfills.
</Tip>

## Read one

```http theme={"system"}
GET /api/v1/orders/{orderId}
```

Full order — line items, shipping choice, fulfilment and payment reference.

## Crypto orders

These carry the transaction signature or hash.

A signature on its own doesn't prove an order was paid — it proves a transaction
landed. We verify sender, recipient and amount before marking anything paid. If
you're reconciling independently, check the same three.

## Errors

| Status |                         |
| ------ | ----------------------- |
| `401`  | Missing or invalid key  |
| `403`  | Key lacks `orders:read` |
| `404`  | Not in your shop        |
| `429`  | Rate limited            |

## Related

* [Webhooks](/api/webhooks) — order events, and why they beat polling.
* [Customers](/api/store/customers) — resolving `userId`.
