Cost Book
Maintain supplier costs by ship-from origin, compare exact cost context, and choose the precise Current Source a product should follow.
Cost Book amounts use decimal-string cents per product base unit in the organization's base currency, preserving precision from source through readback. Direct entries can identify a supplier's ship-from location and Incoterm, so several current costs for the same product and supplier can coexist when they come from different origins. Current Source identifies the exact supplier and ship-from origin a variable-supplier product should follow, while fixed-supplier products continue to follow their assigned supplier.
Endpoints
| Endpoint | Use it for |
|---|---|
GET /cost-book-entries | Read current Cost Book entries or history for an exact product, supplier, and optional ship-from origin. |
GET /products/{id}/cost-context | Compare current and prior Cost Book entries with purchasing evidence for an explicit or resolved supplier. |
GET /products/{id}/current-cost-source | Read fixed, selected, unconfigured, or unavailable source state and eligible supplier-location choices. |
PUT /products/{id}/current-cost-source | Preview, set, replace, or clear the exact supplier-location Current Source for a variable-supplier product. |
POST /cost-book-entries | Check readiness, then create or supersede one verified direct or constructed Cost Book entry. |
Cost Book reads require cost-book-entries:read, and Cost Book writes require cost-book-entries:write. Current Source reads require current-cost-sources:read, and Current Source changes require current-cost-sources:write. The acting user's current ShelfCycle Cost Book access is checked on every request. GET /me reports effectiveCapabilities.costBookEntries, effectiveCapabilities.currentCostSources, and matching write-readiness fields.
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. Add shipFromLocationId to choose one origin. Send shipFromLocationId=null for the supplier's general cost with no ship-from location, or omit the parameter to include every origin.
curl "$SHELFCYCLE_API_BASE_URL/cost-book-entries?productId=product-id&supplierId=supplier-id&shipFromLocationId=location-id&asOf=2026-08-18" \
-H "Authorization: Bearer $SHELFCYCLE_API_KEY" \
-H "X-ShelfCycle-Client: Supplier quote review"
Each complete entry identifies its product, supplier, shipFromLocation, incoterm, effective dates, direct or constructed shape, starting cost, additional costs, total cost, provenance, and completeness. A null ship-from location is the supplier's general cost; a matching location-specific cost takes precedence when the origin is known. 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. Add a ship-from location when the workflow needs one origin's history:
curl "$SHELFCYCLE_API_BASE_URL/cost-book-entries?view=history&productId=product-id&supplierId=supplier-id&shipFromLocationId=location-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.
Read Current Source
Read Current Source before making a supplier-and-origin decision:
curl "$SHELFCYCLE_API_BASE_URL/products/product-id/current-cost-source" \
-H "Authorization: Bearer $SHELFCYCLE_API_KEY" \
-H "X-ShelfCycle-Client: Product cost workflow"
The response reports one of four authorityState values:
| State | Meaning |
|---|---|
fixed_supplier | The product follows its fixed supplier. |
current_source | An exact supplier and ship-from origin was selected for the variable-supplier product. |
unconfigured | No Current Source is selected. Review locationCandidates before choosing a supplier and origin. |
unavailable | The selected supplier-origin combination can no longer provide eligible Cost Book context. Review the reason, then replace or clear it. |
authoritativeLane identifies the fixed or selected supplier and its ship-from location. selectionProvenance reports who selected a Current Source and when. locationCandidates contains each eligible supplier-location choice, while candidates remains a supplier-level view for workflows that only need to choose the supplier. inferredDisplay may describe an available choice for display, but it is distinct from a selected Current Source.
Preview and manage Current Source
Current Source is available for variable-supplier products. Send the desired supplierId and shipFromLocationId, together with the supplier and location observed in the preceding GET as expectedCurrentSupplierId and expectedCurrentShipFromLocationId. Use null for an expected value when no Current Source or no ship-from location is selected.
Preview the change with dryRun=true:
curl "$SHELFCYCLE_API_BASE_URL/products/product-id/current-cost-source?dryRun=true" \
-X PUT \
-H "Authorization: Bearer $SHELFCYCLE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"supplierId": "22222222-2222-4222-8222-222222222222",
"shipFromLocationId": "33333333-3333-4333-8333-333333333333",
"expectedCurrentSupplierId": null,
"expectedCurrentShipFromLocationId": null
}'
The preview returns consequence as set, replace, clear, or unchanged, the desired and previous supplier-location values, eligibility, and a verification path. When the result matches the intended source choice, send the same PUT without dryRun=true.
To clear a selection, send supplierId: null and shipFromLocationId: null, plus the currently selected supplier and location as the expected values. A successful change returns the exact current state and selection provenance. Repeating an already completed desired state returns unchanged.
If another selection happened after the read, stale_current_cost_source returns the current expected supplier and ship-from location. Read Current Source again and review the intended change before retrying.
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 with an exact active product. Include supplierId when the workflow has already chosen a specific supplier:
curl "$SHELFCYCLE_API_BASE_URL/products/product-id/cost-context?supplierId=supplier-id&asOf=2026-08-18" \
-H "Authorization: Bearer $SHELFCYCLE_API_KEY" \
-H "X-ShelfCycle-Client: Supplier quote review"
You may omit supplierId when the workflow should follow the product's source authority:
curl "$SHELFCYCLE_API_BASE_URL/products/product-id/cost-context?asOf=2026-08-18" \
-H "Authorization: Bearer $SHELFCYCLE_API_KEY"
Without supplierId, a fixed-supplier product follows its fixed supplier, a configured variable-supplier product follows its exact Current Source, and a product with one eligible supplier can use that supplier's available Cost Book context. The response's sourceSelection explains how the source was resolved and includes candidate and selection details.
When several eligible lanes remain, cost_source_ambiguous returns the complete supplier choices. Select a supplier under the workflow's policy and retry with its supplierId. If a selected Current Source becomes unavailable, review it through the Current Source endpoint before replacing or clearing it.
The cost-context 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
expectedCurrentEntryIdfor 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.
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-0818-line-4" \
-d '{
"productId": "11111111-1111-4111-8111-111111111111",
"supplierId": "22222222-2222-4222-8222-222222222222",
"expectedCurrentEntryId": null,
"effectiveFrom": "2026-08-18",
"effectiveTo": null,
"sourceRef": "supplier-quote-2026-0818-line-4",
"shipFromLocationId": "33333333-3333-4333-8333-333333333333",
"incoterm": "FOB",
"construction": {
"type": "direct",
"basis": "material",
"uom": "POUND",
"costPerBaseUomCents": "49.5"
}
}'
Use shipFromLocationId and incoterm on direct entries when the cost belongs to a named origin and commercial basis. Omitting shipFromLocationId writes the supplier's general cost; it does not replace a location-specific entry. Constructed entries continue to use the supplier's general cost basis.
Use the current entry id returned by the exact product, supplier, and ship-from-location read or cost-context response. Send null only when that exact origin 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.
Resolve exact product, supplier, and ship-from location ids, keep source values and units intact, and review the normalized construction before submitting a Cost Book update.