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

# upstack products

> Browse products and manage per-variant costs — handling fee + COGS history — from the CLI.

Browse products + variants in the configured catalog and manage per-variant cost data. Wraps the `/api/products*` endpoints — see the [API reference](/api-reference/overview) under the **Products** group for full request / response shapes.

Mutations fire the same per-order COGS recalculation as the web UI.

## Subcommands

| Subcommand                              | Wraps                                                       |
| --------------------------------------- | ----------------------------------------------------------- |
| [`search`](#search)                     | `GET /api/products/search`                                  |
| [`cost`](#cost)                         | `GET /api/products/{productId}/{variantId}/cost`            |
| [`handling-fee set`](#handling-fee-set) | `PUT /api/products/{productId}/{variantId}/handling-fee`    |
| [`cogs add`](#cogs-add)                 | `POST /api/products/{productId}/{variantId}/cogs`           |
| [`cogs update`](#cogs-update)           | `PUT /api/products/{productId}/{variantId}/cogs/{cogId}`    |
| [`cogs delete`](#cogs-delete)           | `DELETE /api/products/{productId}/{variantId}/cogs/{cogId}` |

## search

Search products by title / SKU / variant. Cursor-paginated.

```bash theme={null}
upstack products search -q "shirt"
upstack products search -q "shirt" --page-size 50
upstack products search --cursor "<nextCursor from previous response>"
```

`--page-size` accepts 1–100 (default 20). Pass the `nextCursor` from the response into `--cursor` to page.

**Required scope:** `costs:read`.

## cost

Show the resolved cost breakdown for a single variant — the per-unit effective cost, handling fee, and which configuration tier supplied it (per-variant COG line, global override, or default fallback).

```bash theme={null}
upstack products cost --product-id prd_123 --variant-id var_456
```

**Required scope:** `costs:read`.

## handling-fee set

Set the per-variant handling fee. Must be `>= 0`.

```bash theme={null}
upstack products handling-fee set --product-id prd_123 --variant-id var_456 --fee 2
upstack products handling-fee set --product-id prd_123 --variant-id var_456 --fee 0 --yes
```

**Required scope:** `costs:write`.

## cogs add

Append a new COG line to a variant's manual cost history. The server assigns a ULID for the new line.

```bash theme={null}
upstack products cogs add \
  --product-id prd_123 --variant-id var_456 \
  --cost 5 --start 2026-01-01 \
  --description "Q1 batch"

upstack products cogs add \
  --product-id prd_123 --variant-id var_456 \
  --cost 6 --start 2026-04-01 --end 2026-06-30
```

`--end` is optional — omit for an open-ended interval.

**Required scope:** `costs:write`.

## cogs update

Update an existing COG line by its server-assigned ID. Pass any combination of `--cost`, `--start`, `--end`, `--description`. Use `--end null` to clear an end date (make the line open-ended).

```bash theme={null}
upstack products cogs update \
  --product-id prd_123 --variant-id var_456 --cog-id cog_abc \
  --cost 7

upstack products cogs update \
  --product-id prd_123 --variant-id var_456 --cog-id cog_abc \
  --end null
```

**Required scope:** `costs:write`.

## cogs delete

Delete a COG line by its ID. The CLI prompts for confirmation; `--yes` (or `-y`) skips it.

```bash theme={null}
upstack products cogs delete \
  --product-id prd_123 --variant-id var_456 --cog-id cog_abc
```

**Required scope:** `costs:write`.
