Data imports

Importing CSV files

How to prepare Products, Customers and Pricing Rules files for PriceRules: the columns each import accepts, how values are checked, what happens when something is wrong, and how to fix it.

Quick start

Checklist before you upload

Most rejected imports fail one of these checks.

  • Import in order: Products, then Customers, then Pricing rules.
  • Save the file as .csv (UTF-8), no larger than 50 MB, with the header row on the first line.
  • Name your headers like the fields on this page (sku, name, base_price, …) so they're matched automatically.
  • Fill every required field on every row.
  • Keep SKUs and customer codes unique within a file, and spelled the same way in every file.
  • In pricing rules, use one customer code and one SKU per row, and plain whole numbers for minimum_quantity and priority.
  • Every row must pass. If a single row is invalid, nothing from the file is imported.

Workflow

How imports work

What happens between choosing a file and seeing it completed.

  1. 01

    Choose a file

    Open the import for Products, Customers or Pricing rules (during onboarding, or from the Import button on each page in the dashboard). The browser only accepts .csv files up to 50 MB, reads the header row, detects the delimiter and previews the first rows.

  2. 02

    Map your columns

    PriceRules suggests which column fills each field, based on the header names. Check every suggestion and change any that are wrong. Required fields (marked *) must be mapped before you can start; optional fields can be set to Unmapped. Columns you don't map are ignored.

  3. 03

    Start the import

    Your file is uploaded and the server checks that the import can start: pricing-rule files need products and customers to exist, only one import of each type can run at a time, and your plan's monthly import allowance must not be used up. If a check fails, nothing is queued and the reason is shown next to the Start button.

  4. 04

    Queued

    Imports in the same workspace are processed one at a time; an import started while another is running waits its turn.

  5. 05

    Plan capacity check

    Before any row is saved, PriceRules checks that the records in the file fit your plan (see Limits). If they don't, the whole file is rejected.

  6. 06

    Validation

    Every row is checked against the rules on this page — including duplicates and, for pricing rules, references to existing customers, products and rules. If any row has a problem, the whole file is rejected and nothing is saved.

  7. 07

    Saving

    Rows are saved in batches of 1,000. Products and customers are created or updated; pricing rules are always created as new rules. The progress bar follows the batches.

  8. 08

    Pricing engine update

    For products and pricing rules, the pricing engine is refreshed so the API returns the new prices. Customer imports skip this step. An import is only marked Completed after this step succeeds.

How it ends

CompletedEvery row was saved and, for products and pricing rules, the pricing engine is serving the new data.
RejectedValidation or plan capacity rejected the file. Nothing was saved and your existing data is unchanged. You'll see each problem with up to 20 example row numbers, and can download an error log. Use Fix mapping or Upload a corrected file. Rejected files aren't retried automatically and don't count toward your monthly import allowance.
FailedAn unexpected error stopped processing after automatic retries. See Troubleshooting.
Saved, not liveAll rows were saved but the pricing-engine update failed. Try again repeats only that update.

Reading the error log

  • Download Error Log (.csv) contains every invalid row — not just the sample shown on screen — with an extra pricing_error column listing that row's problems (for example SKU: Missing).
  • Row numbers count data rows: row 1 is the first line after the header (line 2 in a spreadsheet). Blank lines are skipped but still counted, so the numbers match your file.
  • The products error log is separated with semicolons (;); the customers and pricing-rules logs use the same delimiter as your file.
  • The on-screen results group problems under Errors and Duplicates. Both block the import.

CSV

Preparing your CSV

Rules that apply to all three imports.

File format

  • A .csv file of at most 50 MB. Excel workbooks (.xlsx) aren't accepted — export them as CSV.
  • The first line is the header row; every following line is one record.
  • The delimiter is detected automatically from your file: comma (,), semicolon (;), tab or pipe (|). Use one delimiter throughout the file.
  • Wrap a value in double quotes when it contains the delimiter, for example "Hex Bolt M8 x 40, box of 100". Write a quote inside a quoted value as two quotes ("").
  • Save as UTF-8. A byte-order mark (BOM), as added by Excel's CSV UTF-8 option, is fine.
  • Blank lines — empty, or containing only delimiters and spaces — are skipped, including extra empty lines at the end.
  • Spaces around values are removed before they're checked and saved.

Headers and column mapping

Your headers don't have to match the field names exactly: after you choose a file, you map each PriceRules field to one of your columns. PriceRules pre-fills the mapping from your header names, so using the field names on this page as headers gives the best results. Header matching is not case-sensitive for the suggestions, and you can always change a suggestion by hand.

Required

The column must be mapped and every row needs a valid value.

Optional

You can leave the field unmapped. If you map it, its values are still validated.

  • Each field can be mapped to one column. Extra columns you don't map are ignored and never saved.
  • Some optional fields are validated more strictly once mapped: a mapped category or country column must have a value on every row.
  • Products and customers have no other fields than the ones listed below — currencies, emails, external IDs and metadata can't be imported.

One invalid row rejects the whole file

PriceRules checks every row before saving anything. If any row fails, the import is rejected and no rows are saved — there is no partial import of the valid rows. Fix the rows listed in the error log and upload the file again.

Products

Products

Your catalog and the base prices that pricing rules start from.

skuRequired
TypeText
DefaultNone — every row needs a value
  • Surrounding spaces are removed.
  • Must be unique within the file. The check ignores upper/lower case: ABC-1 and abc-1 count as duplicates.
  • Identifies the product. If a product with exactly this SKU already exists in your workspace, it is updated instead of created.
  • Can't differ only in upper/lower case from an existing product: abc-1 when your workspace has ABC-1 rejects the file. Use the existing spelling to update it.
nameRequired
TypeText
DefaultNone — every row needs a value
  • Surrounding spaces are removed. A blank name rejects the file.
base_priceRequired
TypeNumber, 0 or greater
DefaultNone — every row needs a value
  • Accepted formats: 1750, 1750.00, 1750,00, 1,750.00, 1.750,00. Don't include currency symbols.
  • A single dot is always a decimal point: 1.750 is read as 1.75, not 1750.
  • 0 is allowed. Negative or non-numeric values reject the file.
  • Stored with up to 4 decimal places (more are rounded). At most 8 digits before the decimal point — larger prices reject the file.
categoryOptional
TypeText
DefaultColumn not mapped: no category
  • If you map this column, every row must have a category — a blank cell rejects the file.
  • To import products without categories, leave the column unmapped.
  • Re-importing with this column unmapped keeps the existing categories of the products in the file.

Examples

Minimal — required columns onlyCSV
sku,name,base_price
FAS-1001,Hex Bolt M8 x 40 (box of 100),18.50
TOL-2001,Cordless Drill 18V,149.00
SAF-4001,Safety Gloves Cut Level C (pair),6.80
Complete — with categoryCSV
sku,name,base_price,category
FAS-1001,"Hex Bolt M8 x 40, box of 100",18.50,Fasteners
TOL-2001,Cordless Drill 18V,149.00,Power Tools
SAF-4001,Safety Gloves Cut Level C (pair),6.80,Safety
LUB-6002,Industrial Degreaser 5L,36.00,Maintenance

The first name in the complete example contains a comma, so it's wrapped in double quotes.

Error log messages

SKU: MissingThe SKU cell is empty.
SKU: DuplicateThe SKU already appeared on an earlier row of this file (case-insensitive).
NAME: MissingThe name cell is empty.
PRICE: MissingThe base_price cell is empty.
PRICE: InvalidThe base_price is negative or isn't a number.
PRICE: Too largeThe base_price has more than 8 digits before the decimal point.
SKU: Differs only in case from existing "…"An active product has the same SKU in different upper/lower case. Use the existing spelling.
CATEGORY: InvalidThe category column is mapped but this row's category is empty.

Customers

Customers

The accounts that customer-specific pricing rules point to.

codeRequired
TypeText
DefaultNone — every row needs a value
  • Surrounding spaces are removed.
  • Must be unique within the file. The check ignores upper/lower case: ACME and acme count as duplicates.
  • Identifies the customer. If a customer with exactly this code already exists in your workspace, it is updated instead of created.
  • Can't differ only in upper/lower case from an existing customer: acme when your workspace has ACME rejects the file. Use the existing spelling to update it.
  • This is the value pricing rules use in their code column.
nameRequired
TypeText
DefaultNone — every row needs a value
  • Surrounding spaces are removed. A blank name rejects the file.
countryOptional
TypeText
DefaultColumn not mapped: no country
  • Any non-empty text is accepted — values are not checked against a list of countries, so pick one convention (for example ISO codes such as DE, FR) and use it consistently.
  • If you map this column, every row must have a country — a blank cell rejects the file. Leave it unmapped to import customers without one.
  • Re-importing with this column unmapped keeps the existing countries of the customers in the file.

Examples

Minimal — required columns onlyCSV
code,name
ACME-BUILD,Acme Construction GmbH
NORDIC-FAB,Nordic Fabrication AS
Complete — with countryCSV
code,name,country
ACME-BUILD,Acme Construction GmbH,DE
NORDIC-FAB,Nordic Fabrication AS,NO
ATLAS-MRO,Atlas Maintenance Services,NL

Error log messages

ID: MissingThe code cell is empty.
ID: DuplicateThe code already appeared on an earlier row of this file (case-insensitive).
ID: Differs only in case from existing "…"An active customer has the same code in different upper/lower case. Use the existing spelling.
NAME: MissingThe name cell is empty.
COUNTRY: InvalidThe country column is mapped but this row's country is empty.

Pricing Rules

Pricing rules

Fixed prices and percentage discounts for a specific customer and product.

Every imported rule targets one customer and one product

Each row needs an existing customer code and an existing product sku. Rules that apply to all customers or all products can't be imported — create them by hand on the Customer Pricing page.
nameOptional
TypeText
DefaultBlank or not mapped: the rule has no name
  • Only a label — it isn't used for matching prices or detecting duplicates.
codeRequired
TypeOne existing customer code
DefaultNone — every row needs a value
  • Must match a customer that already exists in your workspace, ignoring upper/lower case. The rule is saved with the customer's stored spelling (see how references are saved).
  • One code per cell. A comma-separated list rejects the file (CODE: One customer code per row) — add one row per customer instead.
  • Can't be left blank: a rules file can't create rules that apply to all customers. Create those by hand in the app instead.
skuRequired
TypeOne existing product SKU
DefaultNone — every row needs a value
  • Must match a product that already exists in your workspace, ignoring upper/lower case. The rule is saved with the product's stored SKU.
  • One SKU per cell. Blank cells and comma-separated lists (SKU: One SKU per row) reject the file.
typeRequired
Typefixed or discount
DefaultNone — every row needs a value
  • fixed: value is the final unit price.
  • discount: value is a percentage taken off the product's base price (10 means 10% off).
  • Any capitalization is accepted (Fixed, DISCOUNT); the rule is saved in lowercase.
valueRequired
TypeNumber
DefaultNone — every row needs a value
  • Same formats as base_price: 12.5, 12,5, 1,750.00, 1.750,00. A single dot or comma is always a decimal separator.
  • Stored with up to 4 decimal places (more are rounded). At most 8 digits before the decimal point — larger values reject the file.
  • There is no range check: negative values and discounts above 100 are not rejected, so check them before importing.
minimum_quantityOptional
TypeWhole number, 0 or greater
DefaultBlank or not mapped: no minimum (applies from quantity 1)
  • The rule only applies when the requested quantity is at least this number.
  • Only plain digits are accepted. Negative values, decimals (2.5), separators (1,000) and text reject the file.
  • For duplicate detection, a blank cell and 0 are the same value (1 is a different one).
priorityOptional
TypeWhole number (negative allowed)
DefaultBlank or not mapped: 1
  • Only plain digits with an optional minus sign are accepted. Decimals (1.5), separators and text reject the file.
  • When several rules qualify, a higher number wins (see how rules are chosen).
  • For duplicate detection, a blank cell and 1 are the same value.
statusOptional
TypeActive: true, yes, 1, active. Inactive: false, no, 0, inactive
DefaultBlank or not mapped: true (active)
  • Any capitalization is accepted.
  • Any other value rejects the file (STATUS: Invalid).
  • Inactive rules are saved but never applied to prices.

Duplicate rules

A rule is identified by four values together: code, sku, minimum_quantity and priority. Code and SKU are compared ignoring upper/lower case and surrounding spaces; a blank minimum quantity counts as 0; a blank priority counts as 1. name, type, value and statusare not part of the identity, so an inactive rule still counts. Deleted rules don't.

  • Two rows in the file with the same identity: the later row is reported as PRICING_RULE: Duplicate in import.
  • A row matching a rule already in your workspace: PRICING_RULE: Already exists.
  • To have several rules for the same customer and product, give them different minimum quantities (volume tiers) or priorities.

Rules created by hand with several customers or products

Rules created on the Customer Pricing page can list several customer codes or SKUs. Duplicate detection only compares their first customer code and first SKU: for a hand-made rule for customers ACME and BETA, an imported rule for BETA with the same product, minimum quantity and priority is not reported as a duplicate. Check those rules before importing overlapping ones.

How imported rules are chosen

In the default pricing mode, when a price is resolved for a customer, product and quantity, only active rules whose minimum quantity is reached are considered. Among them, the rules with the highest minimum quantity are kept, then the most specific rule wins, then the highest priority, then the lowest resulting price. Imported rules always name both a customer and a product, which is the most specific kind.

How references are saved

  • Customer codes and SKUs are matched ignoring upper/lower case and spaces around the value in your file: acme-build finds the customer ACME-BUILD.
  • The rule is saved with the stored spelling — ACME-BUILD — so it matches the customer and product exactly when prices are resolved.
  • A product or customer whose stored SKU or code has spaces around it (for example "SKU-9 ") can't be referenced by an import: the row is reported as not found. Correct the stored value on the Products or Customers page first.

Examples

The minimal example uses the minimal products and customers examples above; the complete example uses the complete ones. They don't overlap, so you can import both.

Minimal — required columns onlyCSV
name,code,sku,type,value
Acme fixed price - drill,ACME-BUILD,TOL-2001,fixed,129
,NORDIC-FAB,FAS-1001,discount,8

name is optional: the second rule leaves it empty, and you can also leave the column out. Without minimum_quantity, priority and status columns, both rules apply from quantity 1, have priority 1 and are active.

Complete — all columnsCSV
name,code,sku,type,value,minimum_quantity,priority,status
Acme contract - fasteners,ACME-BUILD,FAS-1001,discount,12,,1,true
Acme volume - bolts 50+,ACME-BUILD,FAS-1001,discount,18,50,1,true
Nordic gloves bulk,NORDIC-FAB,SAF-4001,discount,25,100,1,true
Atlas degreaser contract,ATLAS-MRO,LUB-6002,fixed,31.50,,2,true
Atlas drill (paused),ATLAS-MRO,TOL-2001,fixed,139,,1,false
  • Rows 1–2: Acme gets 12% off FAS-1001, and 18% off from 50 units. Same code, SKU and priority, but different minimum quantities — so they aren't duplicates.
  • Row 3: a volume discount of 25% from 100 units.
  • Row 4: a fixed unit price of 31.50 with priority 2.
  • Row 5: status is false, so the rule is saved but inactive.
  • Empty cells (two commas in a row) mean “no value”: the default for that column applies.

Error log messages

CODE: MissingThe code cell is empty.
CODE: Customer not foundNo customer with this code exists in your workspace.
CODE: One customer code per rowThe cell lists several codes separated by commas.
CODE: Matches more than one customerMore than one customer has this code (ignoring upper/lower case). Make the codes unique first.
SKU: MissingThe sku cell is empty.
SKU: Product not foundNo product with this SKU exists in your workspace.
SKU: One SKU per rowThe cell lists several SKUs separated by commas.
SKU: Matches more than one productMore than one product has this SKU (ignoring upper/lower case). Make the SKUs unique first.
TYPE: MissingThe type cell is empty.
TYPE: InvalidThe type is something other than fixed or discount.
VALUE: MissingThe value cell is empty.
VALUE: InvalidThe value isn't a number.
VALUE: Too largeThe value has more than 8 digits before the decimal point.
MINIMUM_QUANTITY: InvalidThe minimum quantity isn't a whole number of 0 or more.
PRIORITY: InvalidThe priority isn't a whole number.
STATUS: InvalidThe status isn't one of the accepted values.
PRICING_RULE: Duplicate in importAn earlier row of this file has the same code, SKU, minimum quantity and priority.
PRICING_RULE: Already existsYour workspace already has a rule with the same code, SKU, minimum quantity and priority.
PRICING_RULE: Deleted since the previous attempt — upload the file againA rule this import saved before it failed has been deleted since. See Troubleshooting.

Updates

Re-importing data

What happens when a file contains records that already exist.

ProductsMatched by sku. Existing products are updated: name, base price and category are replaced by the file's values (if the category column is unmapped, existing categories are kept). New SKUs are created. Products not in the file are left alone — imports never delete. New prices are live once the import shows Completed.
CustomersMatched by code. Existing customers are updated: name and country are replaced (if the country column is unmapped, existing countries are kept). New codes are created; customers not in the file are left alone.
Pricing rulesNever updated by an import. A row matching an existing rule (same code, SKU, minimum quantity and priority) is rejected as Already exists, which rejects the whole file — so uploading the same rules file again fails. (Retrying a failed import with Try again is different: see Troubleshooting.) Change existing rules on the Customer Pricing page.
  • Write each SKU and customer code exactly the same way, including upper/lower case, every time you import it. A SKU or code that differs only in case from an active one rejects the file.
  • If a SKU or code exactly matches a product or customer you deleted, the deleted record is updated but stays deleted — it doesn't reappear in your lists.
  • Re-importing products and customers counts toward your monthly import allowance like any other import, but updates don't use up plan capacity.

Limits

Limits

File, plan and concurrency limits that apply to imports.

  • File size: up to 50 MB per file. There is no separate row limit — your plan's capacity is the limit.
  • One import of each type can run at a time per workspace, and imports in a workspace are processed one after another.
  • Plan capacity: products and customers count only records the file would create (updates are free); every row of a pricing-rules file is a new rule. If the total would exceed your plan, the whole file is rejected before anything is saved.
  • Monthly import allowance: each completed import counts as one. Rejected and failed imports don't count, but imports still running are reserved.
PlanProductsCustomersPricing rulesImports per period
Free100102006
Starter5,0002,00010,00020
Growth25,00010,00050,000100

Help

Troubleshooting

Common problems, why they happen, and how to fix them.

Import can't startWhole file rejectedImport failedSaved, not yet liveNot rejected — check your data

Import can't start: nothing was queued. Whole file rejected: nothing was saved. Import failed: processing stopped on an unexpected error. Saved, not yet live: rows are saved, the pricing engine isn't updated yet. Not rejected: the import succeeds, but the data may not behave as you expect.

A required field can't be mapped, or the wrong column is suggested

Import can't start
Cause
Your header names don't resemble the field names, so the suggestion is missing or wrong. Start stays disabled until every required field is mapped.
Fix
Pick the right column for each field in the mapping table. Naming your headers exactly like the field names on this page (sku, base_price, …) gives the most reliable suggestions.

Every row is rejected as missing the same value

Whole file rejected
Cause
A column is mapped to the wrong field, or the mapped column is empty in your file.
Fix
Use Fix mapping to check which column fills each field.

Empty required fields

Whole file rejected
Cause
A required cell is blank (SKU: Missing, NAME: Missing, …).
Fix
Fill in the cell, or remove the row. Download the error log to see every affected row.

Empty optional category or country

Whole file rejected
Cause
The optional column is mapped, so every row needs a value.
Fix
Fill in the missing values, or set the field to Unmapped if you don't want to import it.

Invalid numbers

Whole file rejected
Cause
A price, value, minimum quantity or priority isn't a number, or a price or minimum quantity is negative.
Fix
Remove currency symbols and text. Use plain whole numbers for minimum quantity and priority, and keep prices and values under 100,000,000.

Duplicate SKUs or customer codes

Whole file rejected
Cause
The same SKU (products) or code (customers) appears on more than one row. Case is ignored when comparing.
Fix
Keep one row per SKU or code. To update an existing record, import it again in a later file — that updates it.

Duplicate pricing rules

Whole file rejected
Cause
Two rows — or a row and an existing rule — share the same customer code, SKU, minimum quantity and priority (PRICING_RULE: Duplicate in import / Already exists).
Fix
Remove the repeated rows. Rules can't be updated by import: change an existing rule on the Customer Pricing page, or give the new rule a different minimum quantity or priority. See Re-importing data.

Customer code or SKU not found

Whole file rejected
Cause
The pricing rule references a customer or product that doesn't exist in your workspace (yet).
Fix
Import or create the missing customers and products first, wait for those imports to complete, then import the rules again.

Pricing rules import is locked or refused

Import can't start
Cause
Your workspace has no products (PRODUCTS_REQUIRED) or no customers (CUSTOMERS_REQUIRED).
Fix
Import products, then customers, before pricing rules. See Import order.

Invalid rule type or status

Whole file rejected
Cause
The type is something other than fixed or discount (for example percent or flat), or the status isn't one of the accepted values.
Fix
Use fixed or discount, and true/false (or another accepted status value).

A rule was imported but never applies

Not rejected — check your data
Cause
The rule is inactive, or your price requests spell the SKU or customer code differently from the stored product or customer. Imported rules use the stored spelling, and prices are matched on the exact spelling.
Fix
Check the rule's status on the Customer Pricing page, and send the SKU and customer code exactly as stored on the product and customer.

File too large or not a CSV

Import can't start
Cause
The file is over 50 MB, or isn't a .csv file (for example an .xlsx workbook).
Fix
Export as CSV from your spreadsheet. Split very large files into several smaller files.

File doesn't fit your plan

Whole file rejected
Cause
Importing the file would take you over your plan's limit for products, customers or pricing rules.
Fix
Import fewer new records, delete records you no longer need, or upgrade your plan. See Limits.

Monthly import limit reached, or another import is running

Import can't start
Cause
Your plan's CSV imports for this period are used up (IMPORT_LIMIT_REACHED), or an import of the same type is still running (IMPORT_IN_PROGRESS).
Fix
Wait for the running import to finish, or for your next usage period. Upgrading raises the monthly allowance.

The import failed with an unexpected error

Import failed
Cause
Something went wrong while processing (not a problem in your data). PriceRules retries automatically, up to 3 attempts in total, before showing the import as failed.
Fix
Try again starts a new import of the same file and mapping. Rows are saved in batches of 1,000 and batches saved before the error stay saved — but retrying the same file with the same mapping doesn't save them twice or reject them as Already exists; it saves the remaining rows. Uploading the file again, or changing the mapping, starts from scratch: rules saved by the failed attempt are then reported as Already exists. If you deleted any of those saved rules before retrying, the retry is rejected (Deleted since the previous attempt) — deleted rules are never restored automatically. Upload the file again as a new import, without the rows the failed attempt saved.

“Your data was saved, but the pricing engine couldn't be updated”

Saved, not yet live
Cause
Every row was saved, but refreshing the pricing engine failed on every attempt. The API may still return old prices.
Fix
Click Try again. It only repeats the pricing-engine update — your rows aren't written twice. Don't upload the file again.

The import stays in progress, then stops

Import failed
Cause
If the background job behind an import disappears, the import is closed as failed with “The import stopped unexpectedly. Please try again.”
Fix
Use Try again. If it keeps happening, contact support.