---
title: "Set cost inputs"
method: PUT
path: "/pnl/costs"
tags: ["P&L"]
---

# Set cost inputs

`PUT /pnl/costs`

Insert or update cost inputs in bulk — the endpoint a spreadsheet or CSV import writes through. Rows are keyed on (product_id, sku_id, cost_type, effective_from): re-sending a key overwrites its amount rather than stacking a second cost onto the same units, so replaying the same import is safe. Omit ``sku_id`` to set a product-level default that applies to every SKU without one of its own. Requires ``read_write`` scope and a single shop.

## Request body

- PnlCostsUpsertRequest — PUT /pnl/costs request body — set costs in bulk.
  - `costs` PnlCostEntry[], required — Rows to insert or update, keyed on (product_id, sku_id, cost_type, effective_from). Re-sending a key overwrites its amount rather than stacking a second cost onto the same units. If the same key appears twice in one request, the last one wins.
    - `product_id` string, required
    - `sku_id` string, nullable — The SKU this cost applies to. Omit (or null) to set the product-level default, which applies to every SKU without a row of its own. `sample_unit_cost` is always product-level — sample records do not carry a SKU.
    - `cost_type` 'cogs' | 'sample_unit_cost', required — `cogs` — what one unit costs you, applied to units sold. `sample_unit_cost` — the all-in cost of putting one sample in a creator's hands, applied to sample sends.
    - `amount` number, required — Cost per unit, as a positive number in `currency`.
    - `currency` string — ISO code. Must match the shop's Seller Center currency — costs in another currency are skipped rather than converted at a rate we would have to invent.
    - `effective_from` string, date, nullable — First day this amount applies. Omit for 'always'. Resolution picks the latest `effective_from` on or before an order's paid date, so adding a new dated cost never moves already-reported periods.
    - `notes` string, nullable

## Response `200`

Successful Response

- PnlCostsResponse — The cost inputs stored for one shop.
  - `shop_id` integer, required
  - `costs` PnlCostItem[], required
    - `id` integer, required
    - `product_id` string, required
    - `sku_id` string, nullable — Null means the product-level default.
    - `cost_type` string, required
    - `amount` number, required — Cost per unit, positive.
    - `currency` string, required
    - `effective_from` string, required
    - `notes` string, nullable
    - `source` string, nullable
    - `updated_at` string, nullable

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.dev/reacherapp/apis/reacher-data-api.md) · [All operations](https://skmtc.dev/reacherapp/apis/reacher-data-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/reacherapp/reacher-data-api/revisions/5eefff009b5b/schema)
