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

# Baskets

> Shopping baskets for the current end user, with items, totals, status, and checkout

`Baskets` creates and manages the current end user's shopping baskets and converts one into an [order](/reference/sdk/orders). A basket holds `items` (each with a product `id`, `price`, and `quantity`), a `currency`, free-form `metadata`, and platform-maintained `itemCount`, `totalAmount`, and `status`. Available wherever a current end user exists: tools, dynamic jobs, and trigger-fired turns (see [execution contexts](/concepts/execution-contexts)).

*Verified against lua-cli 3.33.0.*

```ts theme={null}
import { Baskets, BasketStatus } from 'lua-cli';
```

## Quick example

```ts theme={null}
import { Baskets, BasketStatus } from 'lua-cli';

const basket = await Baskets.create({ currency: 'USD' });
await basket.addItem({ id: 'MBP-14', price: 1999, quantity: 1 });
const order = await basket.placeOrder({ paymentMethod: 'stripe' });
console.log(basket.status === BasketStatus.CHECKED_OUT, order.toJSON().id);
```

## Methods

### create()

Creates an empty basket for the current end user.

```ts theme={null}
Baskets.create(basketData: { currency: string; metadata?: Record<string, any> }): Promise<BasketInstance>
```

<ParamField path="basketData.currency" type="string" required>Currency code, for example `USD`.</ParamField>
<ParamField path="basketData.metadata" type="Record<string, any>">Free-form data stored with the basket.</ParamField>

The parameter is typed `any` in the SDK; the platform requires `currency`.

**Returns** — the basket as a [`BasketInstance`](#basketinstance) with `status` `active`.

**Example**

```ts theme={null}
import { Baskets } from 'lua-cli';

const basket = await Baskets.create({ currency: 'EUR', metadata: { source: 'whatsapp' } });
console.log(basket.toJSON().id, basket.itemCount);
```

**Errors** — `Failed to create basket`.

### get()

Returns the current end user's baskets, optionally filtered by status.

```ts theme={null}
Baskets.get(status?: BasketStatus): Promise<BasketInstance[]>
```

<ParamField path="status" type="BasketStatus">One of the [`BasketStatus`](#basketstatus) values. Omit it for every basket.</ParamField>

**Returns** — an array of [`BasketInstance`](#basketinstance).

**Example**

```ts theme={null}
import { Baskets, BasketStatus } from 'lua-cli';

const active = await Baskets.get(BasketStatus.ACTIVE);
console.log(active.length);
```

**Errors** — `Failed to get user baskets`.

### addItem()

Adds an item to a basket.

```ts theme={null}
Baskets.addItem(basketId: string, itemData: BasketItem): Promise<Basket>
```

<ParamField path="basketId" type="string" required>The basket's id.</ParamField>

<ParamField path="itemData" type="{ id: string; price: number; quantity: number; SKU?: string; [key: string]: any }" required>
  The product `id`, unit `price`, and `quantity`, plus any fields of your own such as `SKU`, `color`, or `size`.
</ParamField>

**Returns**

<ResponseField name="basket" type="Basket">
  The raw basket record, not an instance.

  <Expandable title="properties">
    <ResponseField name="id" type="string">Basket id.</ResponseField>
    <ResponseField name="data" type="{ currency: string; metadata?: any; items: BasketItem[]; createdAt: string }">Contents.</ResponseField>
    <ResponseField name="common" type="{ status: BasketStatus; totalAmount: string | number; itemCount: number }">Platform-maintained totals and status.</ResponseField>
    <ResponseField name="createdAt, updatedAt" type="string">ISO 8601 timestamps.</ResponseField>
  </Expandable>
</ResponseField>

**Example**

```ts theme={null}
import { Baskets } from 'lua-cli';

const basket = await Baskets.addItem('basket_abc123', { id: 'SHIRT-M', price: 29.99, quantity: 2, SKU: 'SHIRT-M-BLUE' });
console.log(basket.common.itemCount, basket.data.items.length);
```

**Errors** — `Failed to add item to basket`.

### removeItem()

Removes one item from a basket.

```ts theme={null}
Baskets.removeItem(basketId: string, itemId: string): Promise<Basket>
```

<ParamField path="basketId" type="string" required>The basket's id.</ParamField>
<ParamField path="itemId" type="string" required>The item's `id`.</ParamField>

**Returns** — the raw basket record, as `addItem()`.

**Errors** — `Failed to remove item from basket`.

### clear()

Removes every item from a basket.

```ts theme={null}
Baskets.clear(basketId: string): Promise<Basket>
```

**Returns** — the raw basket record, as `addItem()`.

**Errors** — `Failed to clear basket`.

### updateStatus()

Sets a basket's status.

```ts theme={null}
Baskets.updateStatus(basketId: string, status: BasketStatus): Promise<BasketStatus>
```

<ParamField path="basketId" type="string" required>The basket's id.</ParamField>
<ParamField path="status" type="BasketStatus" required>The status to set.</ParamField>

**Returns** — typed as the status you set. Local runs resolve the status you passed; deployed agents resolve the updated basket record. Don't branch on the resolved value; re-read with `getById()` when you need the basket.

**Example**

```ts theme={null}
import { Baskets, BasketStatus } from 'lua-cli';

await Baskets.updateStatus('basket_abc123', BasketStatus.ABANDONED);
```

**Errors** — `Failed to update basket status`.

### updateMetadata()

Writes basket metadata.

```ts theme={null}
Baskets.updateMetadata(basketId: string, metadata: Record<string, any>): Promise<Record<string, any>>
```

**Returns** — typed as the metadata. Local runs resolve the object you passed; deployed agents resolve the platform's response envelope. Re-read with `getById()` when you need the stored metadata.

**Example**

```ts theme={null}
import { Baskets } from 'lua-cli';

await Baskets.updateMetadata('basket_abc123', { discountCode: 'SPRING25', giftWrap: true });
```

**Errors** — `Failed to update basket metadata`.

### placeOrder()

Creates an order from a basket's items. This static form leaves the basket's status unchanged; the instance form also marks the basket `checked_out`.

```ts theme={null}
Baskets.placeOrder(data: Record<string, any>, basketId: string): Promise<OrderInstance>
```

<ParamField path="data" type="Record<string, any>" required>Your order fields, for example `shippingAddress` and `paymentMethod`. Stored on the order's `data`.</ParamField>
<ParamField path="basketId" type="string" required>The basket to convert.</ParamField>

**Returns** — the order as an [`OrderInstance`](/reference/sdk/orders#orderinstance) with `status` `pending`.

**Example**

```ts theme={null}
import { Baskets } from 'lua-cli';

const order = await Baskets.placeOrder(
  { shippingAddress: { line1: '1 Main St', city: 'Oslo', postalCode: '0150', country: 'NO' }, paymentMethod: 'stripe' },
  'basket_abc123',
);
console.log(order.toJSON().id, order.status);
```

**Errors** — `Failed to create order`.

### getById()

Returns one basket by id.

```ts theme={null}
Baskets.getById(basketId: string): Promise<BasketInstance>
```

**Returns** — the basket as a [`BasketInstance`](#basketinstance). An unknown id throws; there is no `null` return.

**Example**

```ts theme={null}
import { Baskets } from 'lua-cli';

const basket = await Baskets.getById('basket_abc123');
console.log(basket.itemCount, Number(basket.totalAmount).toFixed(2));
```

**Errors** — `Failed to get basket`.

## BasketInstance

The object `create()`, `get()`, and `getById()` return. Its methods refresh the instance from the platform's response, so `itemCount`, `totalAmount`, and `status` are current after each call.

<ResponseField name="status" type="BasketStatus">`active`, `checked_out`, `abandoned`, or `expired`.</ResponseField>
<ResponseField name="itemCount" type="number">Total quantity across items.</ResponseField>
<ResponseField name="totalAmount" type="string | number">Basket total. Wrap it in `Number()` before arithmetic.</ResponseField>
<ResponseField name="metadata" type="any">The basket's metadata.</ResponseField>
<ResponseField name="items, currency, createdAt" type="any">Readable directly through the instance's proxy.</ResponseField>

The identity fields `id`, `userId`, and `agentId` and the raw `data` and `common` objects are private in the type declarations, so `basket.id` doesn't compile. Read the id from `basket.toJSON().id`.

### addItem()

Adds an item and refreshes the instance.

```ts theme={null}
basket.addItem(item: BasketItem): Promise<any>
```

**Returns** — the basket's fields, `{ ...data, ...common }`.

### removeItem()

Removes one item and refreshes the instance.

```ts theme={null}
basket.removeItem(itemId: string): Promise<any>
```

### clear()

Removes every item and refreshes the instance.

```ts theme={null}
basket.clear(): Promise<any>
```

### updateStatus()

Sets the status and updates `basket.status`.

```ts theme={null}
basket.updateStatus(status: BasketStatus): Promise<any>
```

### updateMetadata()

Writes metadata and merges it into the local `metadata`.

```ts theme={null}
basket.updateMetadata(metadata: any): Promise<any>
```

### placeOrder()

Creates an order from the basket, then sets the basket's status to `checked_out`.

```ts theme={null}
basket.placeOrder(data: Record<string, any>): Promise<OrderInstance>
```

**Example**

```ts theme={null}
import { Baskets } from 'lua-cli';

const basket = await Baskets.getById('basket_abc123');
if (basket.itemCount === 0) throw new Error('The basket is empty');
const order = await basket.placeOrder({ paymentMethod: 'stripe' });
console.log(order.status, basket.status);
```

### toJSON()

Returns `{ ...data, ...common, id }`: `items`, `currency`, `metadata`, `createdAt`, `status`, `totalAmount`, `itemCount`, and `id`.

## Types

### BasketStatus

| Member                     | Value         | Meaning                                                |
| -------------------------- | ------------- | ------------------------------------------------------ |
| `BasketStatus.ACTIVE`      | `active`      | Open for changes; the initial status                   |
| `BasketStatus.CHECKED_OUT` | `checked_out` | Converted to an order by the instance's `placeOrder()` |
| `BasketStatus.ABANDONED`   | `abandoned`   | Set by you, for example from a follow-up job           |
| `BasketStatus.EXPIRED`     | `expired`     | The basket's time-to-live passed                       |

`BasketInstance` and `BasketStatus` are exported. `Basket` and `BasketItem` are not; name them from `Baskets.addItem`.

```ts theme={null}
import { Baskets } from 'lua-cli';

type Basket = Awaited<ReturnType<typeof Baskets.addItem>>;
type BasketItem = Parameters<typeof Baskets.addItem>[1];

export function lineTotal(item: BasketItem): number {
  return item.price * item.quantity;
}

export function isEmpty(basket: Basket): boolean {
  return basket.common.itemCount === 0;
}
```

## See also

* [`Products`](/reference/sdk/products) — the catalog items come from
* [`Orders`](/reference/sdk/orders) — what `placeOrder()` creates
* [`Jobs`](/reference/sdk/jobs) — schedule an abandoned-basket follow-up
* [Commerce REST API](/reference/rest/commerce) — baskets over HTTP
