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

# Price Books API

> Manage marketplace channel list-price markup rules.

Use the Developer Platform price books endpoints to manage marketplace channel list-price markup rules. Semantics match the workspace Price book UI (`/app/{organizationId}/pricebook`) and the OmniBot `manage_price_book` tool.

Price books **do not** change canonical product prices in Omni. They rewrite channel list price at publish/catalog time by platform (and optional store/country).

## Authentication

Send an OmniCommerce API key or OAuth client-credentials token:

```http theme={null}
Authorization: Bearer $OMNI_API_KEY
Content-Type: application/json
```

| Endpoint                              | Required scope      |
| ------------------------------------- | ------------------- |
| `GET /api/v1/price-books`             | `price_books:read`  |
| `GET /api/v1/price-books/{ruleId}`    | `price_books:read`  |
| `POST /api/v1/price-books/preview`    | `price_books:read`  |
| `POST /api/v1/price-books`            | `price_books:write` |
| `PATCH /api/v1/price-books/{ruleId}`  | `price_books:write` |
| `DELETE /api/v1/price-books/{ruleId}` | `price_books:write` |

OAuth clients must include the scope on the client. API keys created from organization settings receive all developer scopes by default.

Session-authenticated calls must include `organizationId` in the query (GET) or JSON body (writes).

OpenAPI reference: [API reference](/api-reference) · Spec: [openapi.json](/openapi.json)

## List rules

```http theme={null}
GET /api/v1/price-books
```

### Query parameters

| Parameter        | Description                                                                  |
| ---------------- | ---------------------------------------------------------------------------- |
| `organizationId` | Organization scope for session auth. Optional for single-org OAuth/API keys. |
| `platform`       | Filter: `shopee`, `lazada`, `tiktok`, `shopify`, or `whatsapp`.              |
| `enabledOnly`    | When `true`, only enabled rules.                                             |

### Response

```json theme={null}
{
  "rules": [
    {
      "id": "11111111-1111-4111-8111-111111111111",
      "organizationId": "org_1",
      "platform": "shopee",
      "storeId": null,
      "country": "singapore",
      "base": "list_price",
      "marginType": "markup_percent",
      "marginValue": 10,
      "rounding": "currency_minor",
      "currency": "SGD",
      "enabled": true,
      "createdAt": "2026-07-01T00:00:00.000Z",
      "updatedAt": "2026-07-01T00:00:00.000Z"
    }
  ],
  "total": 1
}
```

## Create rule

```http theme={null}
POST /api/v1/price-books
```

### Request body

```json theme={null}
{
  "platform": "shopee",
  "marginValue": 10,
  "country": "singapore",
  "rounding": "currency_minor",
  "currency": "SGD",
  "enabled": true
}
```

| Field         | Notes                                                            |
| ------------- | ---------------------------------------------------------------- |
| `platform`    | Required. `shopee`, `lazada`, `tiktok`, `shopify`, or `whatsapp` |
| `marginValue` | Required markup percent (0–500)                                  |
| `storeId`     | Optional store scope; omit/`null` = all stores for platform      |
| `country`     | Optional country scope                                           |
| `rounding`    | `none`, `currency_minor` (default), `nearest_0_05`, `nearest_1`  |
| `currency`    | Optional ISO 4217 for `currency_minor` rounding                  |
| `enabled`     | Defaults to `true`                                               |

Scope uniqueness: one rule per `platform` + `storeId` + `country` combination.

Returns `201` with `{ "rule": { ... } }`.

## Get / update / delete

```http theme={null}
GET    /api/v1/price-books/{ruleId}
PATCH  /api/v1/price-books/{ruleId}
DELETE /api/v1/price-books/{ruleId}
```

Update accepts partial fields (`storeId`, `country`, `marginValue`, `rounding`, `currency`, `enabled`). Platform cannot be changed after create.

## Preview channel list price

```http theme={null}
POST /api/v1/price-books/preview
```

```json theme={null}
{
  "platform": "shopee",
  "listPrice": 100,
  "country": "singapore",
  "currency": "SGD"
}
```

Optional `ruleId` forces a specific rule instead of most-specific matching.

### Response

```json theme={null}
{
  "listPrice": 100,
  "channelListPrice": 110,
  "applied": true,
  "source": "price_book",
  "markupPercent": 10,
  "rule": { "id": "…", "platform": "shopee", "marginValue": 10 }
}
```

When no enabled rule matches, `applied` is `false`, `source` is `canonical`, and `channelListPrice` equals `listPrice`.

## Matching priority

Most specific enabled rule wins for a given platform/store/country:

1. platform + store + country
2. platform + store
3. platform + country
4. platform only

## Related

* Workspace UI: `/app/{organizationId}/pricebook`
* OmniBot tool: `manage_price_book` (default Omnibot tool)
* Product base price writes: `POST /api/v1/sync` (see [API reference](/api-reference)) or workspace product price update
* Promotions (discounts/campaigns): [Promotions API](/guides/promotions)
