# Costs and CSV upload

> Enter what a store pays: the four cost rules, product costs by hand or from a CSV file, other costs, and ad spend uploaded as a CSV until accounts connect.

The Profit report and the profit tiles of the Store summary need to know what the store pays. This page explains the **Costs** tab under a site's Settings: the cost rules, the product costs, the other costs and the ad spend upload. It also gives the columns of both CSV files.

Owners and Admins can open the tab and change it. Viewers see the numbers it produces but not the tab. A token with the Write permission can make the same changes through the API, the MCP server and the command line, except deleting: a cost line or a product cost is deleted from the dashboard only. The costs of the public demo cannot be changed.

## The cost currency

Every cost of a site is in one currency. The first cost you save fixes it: the currency of the store's orders, or US dollars for a site without orders. Product costs and cost lines are always in that currency. A cost in another currency is never converted: the Store summary and the Profit report list it in a note and leave it out.

## The cost rules

The **Cost rules** section holds the four rules that apply to every order:

- **Shipping per order.** What the store pays to ship one order.
- **Payment fee percentage.** The share of each order the payment provider keeps, such as `2.9` for 2.9%.
- **Fixed payment fee.** The fixed part of the fee per order, such as `0.30`.
- **Default product cost.** A percentage of the price, used for every product without a unit cost of its own.

Amounts are typed in the currency, such as `5.50`, and each rule is saved when you leave its field.

## Product costs

The **Product costs** section lists the unit cost of each product: what one unit costs the store. Add a product by hand with its id, name and cost, or change a cost in its row. A site holds up to 5,000 product costs.

The product id is the one the orders carry. For a Shopify store it is the number in the address of the product in the Shopify admin.

To fill in many at once, upload a CSV file. Its columns are product_id, product_name, unit_cost and currency:

```csv
product_id,product_name,unit_cost
8215530291462,Linen shirt,26.00
8215530291463,"Tee, everyday",9.00
```

The first line names the columns, in any case and any order. `id` is read as `product_id`, `name` and `title` as `product_name`, and `cost` as `unit_cost`. Costs are in major units, with a point or a comma before the cents. A field that holds a comma is put in quotes. A `currency` column, when there is one, must be the cost currency of the site. A product that is in the file twice takes the later row, and a product already on the list takes the new cost.

## Other costs

The **Other costs** section holds what the store pays besides products, shipping, fees and ads: rent, software, a photoshoot, returns handling. A site holds up to 100 of them. Each has a name and one of three kinds, Monthly, One-off and Share of revenue:

- **Monthly.** A fixed amount each month from a start day, with or without an end day. Each day carries its share of its month.
- **One-off.** One amount on one day.
- **Share of revenue.** A percentage of the gross sales of the days it covers, from a start day, with or without an end day.

A change to a cost line changes profit for every period it covers, past ones included. [Profit report](/docs/profit-report#how-other-costs-are-counted) shows how each kind is counted.

## Upload ad spend

Ad accounts cannot be connected yet: see [what works today](/docs/status). Until they can, the **Ad spend upload** section takes the spend of any platform as a CSV file, the kind an ad manager exports. Pick the currency the spend was billed in, then upload the file. Its columns are date, platform, campaign, campaign_id, ad_set, ad_set_id, ad, ad_id, spend, impressions, clicks, conversions, conversion_value, view_conversions and currency:

```csv
date,platform,campaign,ad_set,ad,spend,impressions,clicks,conversions,conversion_value
2026-10-01,meta,Fall Collection,Prospecting | Broad,Linen shirt | UGC video,52.00,4160,46,2,176.00
2026-10-01,google_ads,Brand Search,Brand | Exact,RSA | Brand,38.00,1580,54,1,94.00
```

- `date`, `platform`, `campaign` and `spend` are needed. The rest may be left out.
- `platform` is one of `meta`, `google_ads`, `tiktok`, `pinterest` and `amazon_ads`. `facebook` is read as `meta` and `google` as `google_ads`.
- When an id column is left out, the id is the name in lower case with hyphens, which is also how a campaign name is matched to the `utm_campaign` of visits. Ids from the platform match more reliably: see [Which ads earned sales](/docs/which-ads-earned-sales#how-a-visit-is-matched-to-an-ad).
- `conversions` and `conversion_value` are what the platform reports, and `view_conversions` its purchases after a view.

**The replace rule.** An upload covers the days from the first date in the file to the last, for every platform in it. Uploading replaces the uploaded spend of each platform the file names on all of those days, so put every day of a platform in that span in the file, not only the days you correct. A file with a whole month of Meta and one day of Google Ads leaves Google Ads with only that one day for the month. Spend of other days, and of platforms the file does not name, stays as it is.

Spend uploaded this way has campaign, ad set and ad names but no pictures, so the [Creative report](/docs/creative-report) has no creatives for it.

## What an upload answers

Both uploads read a file of at most 20,000 rows and 1,000,000 bytes. A row that cannot be read is skipped and named by its line in the file, with the reason, such as a date that is not a real day or a cost that is not an amount. Every other row is saved. The answer counts the rows read, saved and skipped.

**Next:** [Profit report](/docs/profit-report), [Creative report](/docs/creative-report), [Which ads earned sales](/docs/which-ads-earned-sales)
