> For the complete documentation index, see [llms.txt](https://help.dollarlabs.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.dollarlabs.io/dollarlabs-b2b-custom-pricing/price-list/csv-import-and-export.md).

# CSV import & export

The complete CSV format — every column, the full cell grammar for tiers, case multiples, loose pricing and discount modes, and the rules that decide when a cell is updated, erased or skipped.

Use CSV to update many variants at once. Export your current data, edit the pricing cells, then import the file.

## The workflow

Start with **export, edit, re-import** to keep the correct headers and variant IDs.

1. Open the price list editor.
2. **Export** — choose priced rows, filtered rows or the whole catalog (see below).
3. Edit in Excel, Google Sheets or a script.
4. **Import** — check the header and the first rows in the dialog, then select **Upload and process**.
5. Watch it finish in [Jobs & history](/dollarlabs-b2b-custom-pricing/price-list/jobs-and-history.md).

<figure><img src="https://2844543096-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcVBfwy7Yj4tU8TsxkHEr%2Fuploads%2Fgit-blob-c0672be5b925960a16e503b137405a08a8106734%2Feditor-export-menu-annotated.png?alt=media" alt="Price list editor toolbar with the Export menu open, showing Export priced rows, Export filtered rows and Export entire catalog, beside Import, Sync from Shopify and Settings."><figcaption><p>Export first, edit the file, then return to Import.</p></figcaption></figure>

## Choose an export

| Option                    | Includes                                                                      | Delivery               |
| ------------------------- | ----------------------------------------------------------------------------- | ---------------------- |
| **Export priced rows**    | Variants that already have pricing                                            | Immediate CSV download |
| **Export filtered rows**  | Variants matching the current search and filters, including unpriced variants | Background export      |
| **Export entire catalog** | Every variant, ignoring the current search and filters                        | Background export      |

**Export filtered rows** appears only while a search or filter is active. Use it to price one vendor or product type. Use the full catalog when setting up prices across the store.

For background exports, download the file when it is ready. If email delivery is available, the dialog also offers an email destination. You can retrieve completed exports from [Jobs & history](/dollarlabs-b2b-custom-pricing/price-list/jobs-and-history.md).

## Columns

Exports use the following columns. Import matches columns by header, so keep the names unchanged; their order can vary.

| Column               | Meaning                                                                                                                                             |
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `op`                 | Operation for the row: `upsert` (the default) or `delete`. `delete` removes that variant's pricing. Leave as exported unless you mean to remove it. |
| `variantId`          | Shopify variant ID. The identifier rows are matched on.                                                                                             |
| `productId`          | Shopify product ID. Informational.                                                                                                                  |
| `displayName`        | Product and variant title. Informational — editing it changes nothing.                                                                              |
| `sku`                | The variant's SKU. Informational, but the natural key for joining external data.                                                                    |
| `price`              | The variant's current catalog price. Informational.                                                                                                 |
| `status`             | Active, Draft or Archived. Informational.                                                                                                           |
| `productType`        | Informational.                                                                                                                                      |
| `vendor`             | Informational.                                                                                                                                      |
| `productTags`        | Product tags. Informational — not customer tags.                                                                                                    |
| `pricing[Default]`   | Fallback pricing when no customer column matches, including for guests.                                                                             |
| `pricing[<TagName>]` | One column per customer tag.                                                                                                                        |

Columns marked informational are exported to help you filter and formula in your spreadsheet. Changing them has no effect — pricing is read only from the `pricing[…]` columns.

{% hint style="warning" %}
`productTags` are **product** tags. The `pricing[…]` headers use **customer** tags. They are unrelated, and mixing them up is a common mistake when writing formulas.
{% endhint %}

## The cell grammar

Everything about a variant's pricing for one tag lives in one cell, as parts joined by semicolons.

<table><thead><tr><th width="150">Part</th><th width="200">Meaning</th><th>Example</th></tr></thead><tbody><tr><td><code>V</code></td><td>A simple price — shorthand for a single tier at quantity 1</td><td><code>18</code></td></tr><tr><td><code>Q:V</code></td><td>A volume tier: minimum quantity <code>Q</code>, value <code>V</code></td><td><code>12:9</code></td></tr><tr><td><code>c:N</code></td><td>Case multiple of <code>N</code></td><td><code>c:12</code></td></tr><tr><td><code>d:p</code> / <code>d:f</code> / <code>d:s</code></td><td>Discount mode for the whole cell — percentage, fixed amount, or specific price (the default)</td><td><code>d:p</code></td></tr><tr><td><code>l:V</code></td><td>Global loose value, interpreted in the cell’s discount mode</td><td><code>l:7.2</code></td></tr><tr><td><code>l:Q:V</code></td><td>Loose value for the tier starting at <code>Q</code></td><td><code>l:50:7.2</code></td></tr><tr><td><code>p:Q:V</code> / <code>f:Q:V</code></td><td>Legacy tier prefix; do not mix modes within an imported cell</td><td><code>p:12:20</code></td></tr></tbody></table>

Additional case settings:

| Part  | Meaning                                                               | Example                   |
| ----- | --------------------------------------------------------------------- | ------------------------- |
| `b:c` | Specific prices are per case; requires a case size greater than one   | `1:24;c:6;b:c`            |
| `b:u` | Prices are per item (the default)                                     | `1:4;c:6;b:u`             |
| `m:N` | Minimum quantity in items; use a whole case multiple when cases apply | `1:24;c:6;b:c;m:12`       |
| `r:a` | An incomplete case order uses the loose rate for every item           | `1:24;c:12;b:c;r:a;l:2.5` |
| `r:s` | Full cases and extra units are priced separately (the default)        | `1:24;c:6;b:c;r:s;l:5`    |

Use one price type per cell. In percentage mode, `l:10` means 10% off each loose item; in fixed-amount mode it means 10 off each loose item. Only Specific price supports per-case prices.

Order does not matter for the recommended formats above, and whitespace around parts is ignored.

### Worked examples

```
18
```

$18 per unit. The most common cell in any price list.

```
1:10;12:9;24:7
```

$10 each from 1, $9 from 12, $7 from 24.

```
1:10;12:9;24:7;c:12
```

The same ladder, but quantities must be multiples of 12.

```
1:20;d:p
```

20% off. The `d:p` changes how `20` is read.

```
1:5;d:f
```

$5 off per unit.

```
c:6
```

Case multiple of 6, with no pricing at all. Valid and useful — this enforces carton-only ordering without any discount.

```
1:10;50:7;100:6.5;c:50;l:7.2
```

Case multiple of 50 with a tier ladder, and any leftover loose units at $7.20 each.

```
1:10;50:7;100:6.5;c:50;l:50:7.2;l:100:7
```

The same, but loose units get cheaper at the 100 tier. No loose value is supplied for the quantity-1 tier in this example; supply one if buyers should order below the first full case. See [progressive case multiples](/dollarlabs-b2b-custom-pricing/getting-started/progressive-case-multiples-and-loose-unit-pricing.md).

## What happens on import

Review blank cells carefully before importing.

<table><thead><tr><th width="230">Cell contains</th><th>Result</th></tr></thead><tbody><tr><td>A valid value</td><td><strong>Replaces</strong> everything previously in that cell.</td></tr><tr><td>Nothing (blank or whitespace)</td><td><strong>Erases</strong> that tag's pricing for that variant.</td></tr><tr><td>A wholly unparseable cell</td><td><strong>Skipped</strong> — the existing value is left alone.</td></tr></tbody></table>

{% hint style="danger" %}
Blank means erase. If your spreadsheet contains all your tag columns but you only filled in some of them, importing it will clear the rest. When in doubt, export, edit, re-import — never assemble a partial file with empty tag columns.
{% endhint %}

The "replaces" rule matters too. If a cell currently holds `1:10;12:9;c:12` and you write `9` into it, you get a flat $9 price with **no tiers and no case multiple**. To change just the price, write the whole cell.

A cell containing both valid and invalid parts can still be applied using the valid parts. Do not rely on a typo causing the entire cell to be skipped. Export again after an important import and check the result.

Omitting a pricing column leaves that column unchanged. Including it with blank cells clears those variants’ rules. Keep `variantId` in every row; `sku` helps you join spreadsheet data but is not the import identifier.

### Number formatting

Values must be plain unsigned decimals — `9`, `9.5`, `0.75`.

Do not use these formats:

* thousands separators — `1,200`
* comma decimals — `12,50`
* scientific notation — `1e3`
* currency symbols — `$9.00`
* negative numbers

{% hint style="warning" %}
Spreadsheets reformat numbers without asking. A column formatted as Currency will export `$9.00` and be skipped on import. Format your pricing columns as **plain text** before editing, and check the raw CSV if an import silently changes nothing.
{% endhint %}

{% hint style="info" %}
Every price you import must be at or below the product's Shopify price. The `price` column is for reference only; the app reads base prices from Shopify when you import.
{% endhint %}

## Importing

Choose **Import**, then drop your CSV on the **Import CSV** dialog or select it.

<figure><img src="https://2844543096-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcVBfwy7Yj4tU8TsxkHEr%2Fuploads%2Fgit-blob-d4867ba9a0896c31c619b84985a932ad70c5733f%2Fcsv-import-dialog-annotated.png?alt=media" alt="Import CSV dialog with a selected file, the message Header is valid, a preview of the first rows and the Upload and process button." width="732"><figcaption><p>The dialog checks your headers and shows the start of your file; the import starts when you select Upload and process.</p></figcaption></figure>

{% hint style="warning" %}
The import dialog checks your headers and shows the first 10 rows of your file. It does not list what will change. **Upload and process** starts the import straight away, so check blank tag cells and number formats before you select it.
{% endhint %}

Once started, the import runs as a background job. Large files take a while; the grid may lag behind briefly. [Jobs & history](/dollarlabs-b2b-custom-pricing/price-list/jobs-and-history.md) is the authoritative record, and it is where you download the error CSV if some rows failed.

### Large catalogs

Import in batches of a few thousand rows and let each finish before starting the next. Check the job result before submitting another file, so you can identify and correct errors without overlapping changes.

## Common problems

**"I imported and nothing changed."**\
Almost always number formatting — the values were unparseable and therefore skipped. Open the raw CSV in a text editor and look at the actual characters.

**"I imported and lost pricing."**\
Blank cells in tag columns. Restore from your previous export; keep the last known-good file.

**"My tiers vanished."**\
A bare number replaced the whole cell. Write the full cell string to preserve tiers and case multiples.

**"Some rows didn't apply."**\
Download the error CSV from [Jobs & history](/dollarlabs-b2b-custom-pricing/price-list/jobs-and-history.md) — it lists the rows and why each failed.
