Getting started
Bulk managing rules with CSV
How to export your pricing rules to a spreadsheet, edit them in bulk, and re-import. Pro plan feature, with atomic validation so a broken file never half-applies.
Updated May 19, 2026
If you have more than a handful of rules — or you want to author them in a
spreadsheet first and paste them in once — PriceMux’s CSV import/export is the
shortcut. Export your existing rules to a .csv, edit them anywhere you’d
edit a spreadsheet (Excel, Google Sheets, Numbers), and re-import. PriceMux
validates the whole file up front; if anything looks wrong, nothing is
written and you get an error report telling you exactly which rows to fix.
This page covers:
- Who gets CSV import/export
- Exporting your rules
- The CSV format — one row per rule (or one row per weight bracket)
- Editing in a spreadsheet
- Re-importing — replace-mode semantics and the deletion confirmation
- What happens when validation fails
- Limits
CSV import/export is for the rules themselves — the conditions and formulas PriceMux uses to compute online prices. Base prices and variant weights live in Shopify, not in PriceMux; see Editing base prices and weights for how to bulk-edit those.
Who gets this
CSV import/export is a Pro plan feature. Free, Starter, and Growth merchants can still use the in-app rule editor; they just can’t upload or download the CSV. If you’re on a lower tier, the Export CSV and Import CSV buttons are hidden.
The Pro plan caps that matter here:
- 500 rules total (active + inactive combined).
- 250 active rules. Inactive rules count toward the 500-total cap but not the 250-active cap.
If a CSV would push you over either cap, the import is refused before any write happens.
Exporting your rules
On the PriceMux dashboard, click Export CSV. Your browser downloads a
file named rules-YYYY-MM-DD.csv (the date is today’s date in UTC) with
one column per rule field and one row per rule — with one exception
covered below for weight-tier rules.
The export is a snapshot of the current rules. You can open it in any
spreadsheet program. Save it as .csv when you’re done editing — Excel
sometimes defaults to .xlsx, which PriceMux won’t accept.
The CSV format
Every column has a fixed name and meaning. The order doesn’t have to match the export (PriceMux matches by header name), but every column has to be present.
| Column | What it is |
|---|---|
external_id | Stable identifier for an existing rule (format: rule_<number>). Blank means “create a new rule.” |
rule_type | One of flat, percentage, weight_tier. |
scope | One of global, collection, product, variant, tag. |
channel | One of online, pos, all. |
priority | Integer. Higher priority wins when multiple rules match a variant at the same specificity. |
is_active | true or false. Inactive rules are kept around for reuse but skipped at price-apply time. |
min_price_floor | Optional decimal (≤2 places). If the rule computes a price below this, PriceMux refuses to write it and logs a floor-catch entry. Leave blank for no floor. |
rounding_pattern | Optional. One of end_in_99, end_in_95, end_in_00, nearest_5_cents, nearest_25_cents, nearest_1_dollar, nearest_5_dollars, none. Leave blank to fall back to the shop default. |
active_from / active_until | Optional scheduling window. ISO 8601 UTC datetimes (e.g. 2026-06-01T00:00:00Z). Leave blank for “always on.” |
scope_ids | Required for non-global scopes. See below. |
flat_amount | Required for flat; blank otherwise. Decimal with ≤2 places. |
percent | Required for percentage; blank otherwise. Decimal with ≤2 places (e.g. 25 for 25%). |
weight_unit | Required for weight_tier; blank otherwise. One of POUNDS, OUNCES, KILOGRAMS, GRAMS. |
bracket_min / bracket_max / bracket_markup | Required for weight_tier; blank otherwise. One row per bracket — see below. |
scope_ids
What goes in this column depends on the rule’s scope:
global— leave blank.product— one or more Shopify product GIDs, comma-separated. Format:gid://shopify/Product/<digits>. The fastest way to grab a product GID is from its Shopify admin URL.collection— same idea:gid://shopify/Collection/<digits>, comma-separated.variant—gid://shopify/Variant/<digits>, comma-separated.tag— exactly one tag string per rule (no commas; multi-tag rules aren’t supported yet). Tags are 1–255 characters, letters/numbers/ spaces/hyphens only.
Weight-tier rules: one row per bracket
A weight_tier rule has several brackets (e.g. 0–1 kg, 1–2 kg, 2 kg+),
each with its own markup. The CSV represents these as one row per
bracket, all sharing the same external_id and rule metadata. PriceMux
groups consecutive rows with the same external_id into one rule at
import time.
Example — a single weight-tier rule with three brackets:
external_id,rule_type,scope,channel,priority,is_active,...,weight_unit,bracket_min,bracket_max,bracket_markup
rule_42,weight_tier,global,online,10,true,...,KILOGRAMS,0,1,5.00
rule_42,weight_tier,global,online,10,true,...,KILOGRAMS,1,2,8.00
rule_42,weight_tier,global,online,10,true,...,KILOGRAMS,2,,12.00
A few notes:
- Rows in the same weight-tier group must be contiguous. Don’t interleave them with rows from other rules.
- All non-bracket cells (everything except
bracket_min/bracket_max/bracket_markup) must be identical across rows in a group. If they differ, the import is refused. - The last row’s
bracket_maxmay be blank — that’s the open-ended top bracket (“everything above 2 kg”). - Brackets must be sorted by
bracket_minascending and must not overlap.
Editing in a spreadsheet
Most editing patterns work as you’d expect:
- Change a value — edit the cell, save, re-upload. PriceMux matches
by
external_idand updates the rule in place. - Add a rule — append a new row, leave
external_idblank. PriceMux treats blankexternal_idas “this is a new rule” and creates it. - Delete a rule — remove its row from the file. PriceMux will detect the rule is missing from the file and delete it on import (see below).
- Disable a rule temporarily — set
is_activetofalse. The rule stays in your library but is skipped at price-apply time.
If you accidentally change an external_id to a value that no longer
matches an existing rule, PriceMux will treat that row as a brand-new
rule (creating a fresh one) rather than failing — but the original rule
will be deleted because it’s now missing from the file. When in doubt,
leave external_id cells alone.
Re-importing — replace mode
This is the most important thing to understand:
Import replaces your rule set entirely. Any rule in PriceMux that isn’t in the file will be deleted.
If you export 12 rules, delete 5 rows from the CSV, and re-import, PriceMux will delete those 5 rules. This is intentional — it’s the shape that makes “edit in a spreadsheet” work. But it also means a half-edited file (e.g. you only kept the rows you were changing) will delete everything else.
Two safeguards are built into the flow:
- Preview before commit. After upload + validation, PriceMux shows a summary — X to create, Y to update, Z to delete, W unchanged — and the first 50 changes. Nothing is written until you click Commit import.
- Deletion confirmation. If the import would delete any rules, a checkbox appears: “I understand this will delete N rule(s) not in the file.” You can’t click Commit until you check it.
To upload: click Import CSV on the dashboard, pick your file, click Upload and validate, review the preview, check the deletion confirmation if it appears, and click Commit import.
When validation fails
PriceMux validates the entire file before writing anything. If even one
row has a problem — bad column value, missing required field, unknown
weight unit, broken external_id, over-cap totals — the whole import
is refused and zero rules change.
You’ll see a critical banner (“Import refused — file has validation errors”) followed by a list of the first errors found and a Download error report (.csv) link. The error report has four columns:
| Column | What it tells you |
|---|---|
row_number | 1-based row in your source file (row 1 is the header). |
external_id | The row’s external_id, if any. |
error_field | Which column triggered the error (blank if the error is row-wide). |
error_message | What’s wrong, in plain English. |
Fix the rows the error report points at, save, and re-upload. The cycle is: fix → upload → either error report or success.
Limits
| Limit | Value |
|---|---|
| Maximum file size | 20 MB |
| Maximum rows | 100,000 (per file, including the header row) |
| Maximum uploads per shop | 5 per hour |
| Maximum parallel uploads per shop | 1 (a second upload while one’s in flight returns an error) |
| Maximum active rules (Pro) | 100 |
| Maximum total rules (Pro) | 200 |
The 5-per-hour cap counts every upload submission — including ones that fail validation — so an automated script firing malformed files can’t bypass it. If you hit the cap, the upload form returns a “try again in N seconds” hint.
Common questions
Q: I exported, made no changes, and re-uploaded. What happens?
Every row is detected as unchanged and the import commits as a zero-op (“0 to create, 0 to update, 0 to delete, N unchanged”). No audit log spam, no DB writes. This is the round-trip-clean property — safe to verify your tooling against.
Q: Can I import just a few new rules without exporting first?
You can, but you have to be careful. Because import is replace-mode, uploading a file with only your new rows will delete every rule that isn’t in the file. The safe pattern is always export first, edit, re-upload. The deletion-confirmation checkbox is there to catch this mistake.
Q: I changed a rule’s external_id. Now what?
PriceMux treats the renamed row as a brand-new rule (it can’t find a
match for the new external_id) and creates it. The original rule —
which is no longer referenced anywhere in the file — gets deleted.
End result: same content, but with a fresh database ID and a
broken-looking audit log trail (the old rule’s history stops; the new
rule’s history starts). Avoid editing this column unless you know
that’s what you want.
Q: Can I import rules that reference products or collections that don’t exist on my shop?
The import won’t fail on a foreign or stale Shopify GID at upload time (PriceMux doesn’t cross-check every ID against Shopify on every import, which would be slow for large catalogs). But a rule scoped to a product that doesn’t exist on your shop will never match any variant and will appear to do nothing. If a product or collection is later deleted in Shopify, PriceMux drops the dangling reference automatically and writes an audit log entry.
Q: What if the rules in the file exceed the plan caps?
PriceMux calculates the post-import active and total rule counts before committing. If either would exceed the Pro caps (250 active, 500 total), the import is refused with a row-zero error pointing at the cap. Trim rules from the file or deactivate some and try again.
Q: Is the import atomic? What if PriceMux crashes mid-commit?
The commit runs inside a single database transaction. If anything fails partway, the whole transaction rolls back and your rules stay exactly as they were before the upload. You’ll see an error banner and can re-upload the file once whatever caused the problem is resolved.