# Price Book

Review configured sale prices, schedules, history, and exact single-price updates.

Canonical HTML: https://developer.shelfcycle.com/guides/price-book

Review configured sale prices across products and customers, follow scheduled changes and history, and apply one exact price update after reviewing its full effect.

Price Book routes keep the entered price, currency, package or base-unit basis, effective dates, customer context, and source details together. Reads return every matching configured price with clear overlap and comparison guidance.

## Endpoints

| Endpoint | Use it for |
| --- | --- |
| `GET /price-book-entries` | Review active, scheduled, expired, all, or historical Price Book entries. |
| `POST /price-book-entries?dryRun=true` | Preview one price update, including every entry it would affect. |
| `POST /price-book-entries` | Apply the reviewed update and return the complete saved entry. |

Reads require `price-book-entries:read`. Updates require `price-book-entries:write`. The acting user's current ShelfCycle Pricing Engine access and customer visibility are checked on every request. `GET /me` reports `effectiveCapabilities.priceBookEntries.read`, `write`, and `writeCurrencyMode`.

## Review current prices

`GET /price-book-entries` defaults to prices active on the organization's current business date. Narrow the result by product, customer, list price, currency, ship-to address, warehouse, terms, or source reference.

```bash
curl "$SHELFCYCLE_API_BASE_URL/price-book-entries?productId=product-id&customerId=customer-id&asOf=2026-08-04&limit=25" \
  -H "Authorization: Bearer $SHELFCYCLE_API_KEY" \
  -H "X-ShelfCycle-Client: Customer pricing review"
```

Use `listPrice=true` to select prices without a customer. When `meta.hasMore` is true, continue with `meta.nextCursor`.

Each entry includes:

- product, customer, ship-to, warehouse, terms, and transaction currency;
- active, scheduled, expired, or invalid effective state;
- the exact entered price and whether it is per package or per base unit;
- a normalized base-unit value when the entry has enough information;
- source, effective dates, timestamps, and ready links for the entry and its history; and
- overlap, value, comparison, and warning fields that help a workflow choose compatible prices.

```json
{
  "resourceType": "price_book_entry",
  "id": "price-book-entry-id",
  "product": {
    "id": "product-id",
    "code": "SOLVENT-55",
    "packagingType": "FIXED",
    "packagingName": "Drum",
    "productQuantity": "55",
    "baseUom": "GALLON"
  },
  "customer": { "id": "customer-id", "name": "Northstar Chemical" },
  "effectiveState": "active",
  "overlapState": "single",
  "enteredPrice": {
    "decimalCents": "125.5",
    "currencyCode": "USD",
    "basis": "per_package",
    "basisEvidence": "stored_snapshot",
    "roundedReportingPriceCents": "126",
    "reportingRounding": "half_up"
  },
  "normalization": {
    "decimalCentsPerBaseUom": "2.2818181818181818",
    "baseUom": "GALLON",
    "method": "divide_by_product_quantity",
    "productQuantity": "55"
  },
  "comparisonEligibility": { "eligible": true, "issueCodes": [] },
  "warningCodes": [],
  "links": {
    "self": "/api/v1/price-book-entries?view=all&laneEntryId=price-book-entry-id",
    "history": "/api/v1/price-book-entries?view=history&laneEntryId=price-book-entry-id"
  }
}
```

Use `enteredPrice.decimalCents` as the exact configured value. Use `normalization.decimalCentsPerBaseUom` for comparisons only when `comparisonEligibility.eligible` is true and the product, currency, base unit, and business date match.

## Review schedules and history

Choose the view that matches the question:

| View | Use it for |
| --- | --- |
| `active` | Prices in effect on the selected business date. |
| `scheduled` | Approved prices that begin after the selected business date. |
| `expired` | Prices whose effective period has ended. |
| `all` | The broad configured-price record, including entries that need review. |
| `history` | Every version in the exact pricing lane selected by one visible entry. |

Follow an entry's `links.history` value instead of rebuilding its product, customer, location, terms, quantity, and currency combination.

```bash
curl "$SHELFCYCLE_API_BASE_URL/price-book-entries?view=history&laneEntryId=price-book-entry-id" \
  -H "Authorization: Bearer $SHELFCYCLE_API_KEY"
```

When more than one active entry applies to the same pricing lane, the API returns every matching entry with `overlapState: "multiple"` and `activeClaimCount`. This keeps the full pricing context visible for the workflow's review policy.

## Choose the price basis

For a fixed-package product, submit an exact price either per package or per product base unit. A base-unit submission is converted to the package price using the product quantity, and the response preserves the submitted value, stored value, and conversion.

For a variable-package product, submit the price per base unit and include an active reference package with its quantity. Resolve active package ids through `GET /reference/product-packaging`.

Price Book updates use the organization's base currency reported by `GET /me` as `org.baseCurrencyCode`.

## Preview one price update

Use one stable `Idempotency-Key` for the preview and the later execution. The preview returns the exact affected entry ids, a signed plan token, the predicted entry, and any warnings without writing.

```bash
curl "$SHELFCYCLE_API_BASE_URL/price-book-entries?dryRun=true" \
  -X POST \
  -H "Authorization: Bearer $SHELFCYCLE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: quote-2026-0819-line-2" \
  -d '{
    "productId": "product-id",
    "customerId": "customer-id",
    "shipToAddressId": null,
    "warehouseId": null,
    "terms": "Delivered",
    "effectiveFrom": "2026-08-20",
    "effectiveTo": null,
    "price": {
      "decimalCents": "2.5",
      "currencyCode": "USD",
      "basis": "per_base_uom",
      "baseUom": "GALLON"
    },
    "referencePackaging": null,
    "note": "Customer quote",
    "sourceRef": "quote-2026-0819-line-2"
  }'
```

```json
{
  "data": {
    "object": "price_book_write_readiness",
    "status": "ready",
    "expectedAffectedEntryIds": ["existing-price-book-entry-id"],
    "expectedPlanToken": "signed-plan-token",
    "predictedEntry": {
      "enteredPrice": {
        "decimalCents": "137.5",
        "currencyCode": "USD",
        "basis": "per_package"
      },
      "writeValue": {
        "submittedPrice": {
          "decimalCents": "2.5",
          "basis": "per_base_uom",
          "baseUom": "GALLON",
          "currencyCode": "USD"
        },
        "storedPrice": {
          "decimalCents": "137.5",
          "basis": "per_package",
          "currencyCode": "USD"
        },
        "conversion": {
          "operation": "multiply_by_product_quantity",
          "productQuantity": "55"
        }
      }
    },
    "warningCodes": []
  }
}
```

Review `expectedAffectedEntryIds`, the predicted value and basis, effective dates, and `warningCodes` before execution.

## Apply and verify the update

Send the same intended update without `dryRun=true`, adding the preview's `expectedAffectedEntryIds` and `expectedPlanToken`. Keep the same `Idempotency-Key`.

```json
{
  "productId": "product-id",
  "customerId": "customer-id",
  "shipToAddressId": null,
  "warehouseId": null,
  "terms": "Delivered",
  "effectiveFrom": "2026-08-20",
  "effectiveTo": null,
  "price": {
    "decimalCents": "2.5",
    "currencyCode": "USD",
    "basis": "per_base_uom",
    "baseUom": "GALLON"
  },
  "referencePackaging": null,
  "note": "Customer quote",
  "sourceRef": "quote-2026-0819-line-2",
  "expectedAffectedEntryIds": ["existing-price-book-entry-id"],
  "expectedPlanToken": "signed-plan-token"
}
```

A successful update returns the complete saved Price Book entry with `resultAction` and `idempotencyStatus`. Preserve that response as the write receipt, then follow `links.self` or `links.history` when the key also has read access.

If the request outcome is unknown, replay the identical execute request with the same key and body. The replay returns the original saved result. If the plan is no longer current, repeat the preview and review the new affected set before deciding whether to apply it.

## Choose the right commercial book

Use Price Book for configured customer-facing sale prices, schedules, and history. Use Cost Book for supplier-facing product costs and their direct or constructed cost details. Use product cost context when comparing a Cost Book entry with completed or pending purchase evidence.

> **Guardrail**: Compare prices only when the response marks them eligible and their product, currency, base unit, and business date match. Keep the same stable idempotency key from preview through execution and any retry.
