# Cost Book

Read, compare, and maintain direct and constructed product costs.

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

Read current and historical product costs, compare exact product and supplier context, and maintain verified direct or constructed Cost Book entries.

Cost Book routes work with exact product and supplier ids. Amounts use decimal-string cents per product base unit in the organization's base currency, preserving precision from source through readback.

## Endpoints

| Endpoint | Use it for |
| --- | --- |
| `GET /cost-book-entries` | Read current Cost Book entries or history for an exact product and supplier. |
| `GET /products/{id}/cost-context` | Compare current and prior Cost Book entries with completed-purchase and open-purchase-order evidence for one supplier. |
| `POST /cost-book-entries` | Check readiness, then create or supersede one verified direct or constructed Cost Book entry. |

Reads require `cost-book-entries:read`. Writes require `cost-book-entries:write`. The acting user's current ShelfCycle Cost Book access is checked on every request. `GET /me` reports `effectiveCapabilities.costBookEntries.view`, `effectiveCapabilities.costBookEntries.create`, and Cost Book write readiness.

## Read current Cost Book entries

`GET /cost-book-entries` defaults to the current view. Narrow by `productId`, `supplierId`, or both when the workflow knows the product and supplier it needs.

```bash
curl "$SHELFCYCLE_API_BASE_URL/cost-book-entries?productId=product-id&supplierId=supplier-id&asOf=2026-07-17" \
  -H "Authorization: Bearer $SHELFCYCLE_API_KEY" \
  -H "X-ShelfCycle-Client: Supplier quote review"
```

Each complete entry identifies its product, supplier, effective dates, direct or constructed shape, starting cost, additional costs, total cost, provenance, and completeness. Use `meta.matchStatus`, `meta.completeness`, and `meta.warnings` together. A missing or unresolved amount remains `null`, so callers can distinguish unavailable cost from a real zero.

For the full history of one product and supplier pair, send `view=history` with both `productId` and `supplierId`:

```bash
curl "$SHELFCYCLE_API_BASE_URL/cost-book-entries?view=history&productId=product-id&supplierId=supplier-id&limit=25" \
  -H "Authorization: Bearer $SHELFCYCLE_API_KEY"
```

History can include current and superseded entries, their effective windows, and any unresolved construction details. When `meta.hasMore` is true, continue with `meta.nextCursor` as the only query parameter.

## Understand direct and constructed costs

A direct entry begins with one entered material or landed cost and has no additional components.

A constructed entry begins with either:

- an entered material or landed cost; or
- the Cost Book entry for an exact referenced product.

It can then add ordered freight, packaging, duty, storage, processing, handling, tax, or other components. Components can use a percentage of starting cost, cents per base unit, or cents per package. Read `resolvedContribution`, `additionalCostTotal`, and `totalCost` as decimal strings.

## Compare product and supplier cost context

Use the cost-context endpoint after resolving an exact active product and supplier:

```bash
curl "$SHELFCYCLE_API_BASE_URL/products/product-id/cost-context?supplierId=supplier-id&asOf=2026-07-17" \
  -H "Authorization: Bearer $SHELFCYCLE_API_KEY" \
  -H "X-ShelfCycle-Client: Supplier quote review"
```

The response brings together:

- the current and prior Cost Book entries;
- the latest completed-purchase material and landed evidence;
- the latest open-purchase-order material evidence;
- comparison amounts and percentages when the currency, base unit, cost basis, and timing align; and
- `expectedCurrentEntryId` for a later write.

Purchase evidence is presented as context alongside the Cost Book entry. Use each value's `comparisonBasis` and the comparison's `comparable`, `reason`, and `temporalRelation` fields before describing a change. Missing evidence remains `null`.

## Check a Cost Book update

Submit the intended request with `dryRun=true` to see normalized construction, the predicted entry, current-to-proposed comparisons, readiness checks, and warnings without writing.

```bash
curl "$SHELFCYCLE_API_BASE_URL/cost-book-entries?dryRun=true" \
  -X POST \
  -H "Authorization: Bearer $SHELFCYCLE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: supplier-quote-2026-0717-line-4" \
  -d '{
    "productId": "11111111-1111-4111-8111-111111111111",
    "supplierId": "22222222-2222-4222-8222-222222222222",
    "expectedCurrentEntryId": null,
    "effectiveFrom": "2026-07-17",
    "effectiveTo": null,
    "sourceRef": "supplier-quote-2026-0717-line-4",
    "construction": {
      "type": "direct",
      "basis": "material",
      "uom": "POUND",
      "costPerBaseUomCents": "49.5"
    }
  }'
```

Use the current entry id returned by the exact product and supplier read or cost-context response. Send `null` only when the current read reports that no entry exists. If the current entry changes, fetch it again before preparing a new request.

## Execute and keep the receipt

When the readiness response is `ready` and the workflow's policy allows the update, send the same body without `dryRun=true`. Keep the same stable `Idempotency-Key` for retries of that exact payload.

The first successful update returns the full Cost Book entry with `resultAction` and `idempotencyStatus`. A retry with the same key and body returns the original result. Preserve that receipt as the write readback, then use the verification path when the key also has read access.

> **Guardrail**: Resolve exact product and supplier ids, keep source values and units intact, and review the normalized construction before submitting a Cost Book update.
