Skip to main content
Every import type follows its own rules for two questions:
  1. What does it create? - which records appear in your workspace.
  2. When does it create a new record vs. reuse an existing one? - how a row is matched against data you already have, and what happens when it matches.
Knowing these rules lets you re-run an import without guessing whether you’ll end up with duplicates.

At a glance

Import typeWhat it createsMatched against existing byRe-importing a matching row
ProductsA product owned by your companySKU, within your companyReused, never overwritten
MaterialsA source product, plus a supplier when supplier columns are presentSKU, within the owning supplierReused, never overwritten
Bill of materials (BOM)Inputs on the target product, plus the supplier parts and materials they referenceProducts by SKU + ownership; inputs by source + quantity + unitProducts reused; inputs added only to unmodeled products
SuppliersA supplier company, plus contacts when contact columns are presentUUID, then your internal ID, then nameReused, never overwritten; new contacts merged in
LocationsA named location, optionally geocodedLocation name, within the owning companyReused; blank fields filled in, set values kept
Activity data, Air travel, TransportOne activity record per rowNot matchedA new record every time
Products, materials, suppliers, locations, and BOMs are safe to re-run - matching records are reused, so you won’t create duplicates. Activity, air travel, and transport imports are not - every row becomes a new record each time you import the file. See Activity data, air travel, and transport below.
The sample rows below use Variable’s canonical column names. Your file’s headers don’t need to match - the column mapping step lets you map any header to the right field.

Products

Creates a product owned by your company for each row.
  • Matched by: SKU, scoped to your company. If a row has no SKU, the product name is used instead.
  • On a match: the existing product is reused and left untouched - its name, supplier, and other fields are not overwritten with the values in your file.
  • Created new when: no product matches - by SKU, or by name when the row has no SKU. A SKU-less row gets a SKU generated from its name on creation.
Sample rows:
name,sku,unitCode,weightQuantity,weightUnitCode
Mountain Bike,BIKE-001,item,15.2,kg
Road Bike,BIKE-002,item,8.4,kg

Materials

Creates a source product (a material or supplier part) for each row, and a supplier company when supplier columns are present.
  • Matched by: SKU, scoped to the owning supplier. The supplier is matched first by UUID, then by your internal supplier ID, then by supplier name. Name is the fallback when a row has no SKU.
  • On a match: the existing material and supplier are reused and left untouched.
  • Created new when: no material matches - by SKU, or by name when the row has no SKU. A SKU-less row gets a SKU generated from its name on creation.
Sample rows:
name,sku,supplier,supplierId,unitCode,weightQuantity,weightUnitCode
Aluminum Alloy 6061,ALU-6061,RimSupply,SUP-001,kg,1,kg
Natural Rubber,RUB-NAT,TireCo,SUP-002,kg,1,kg

Bill of materials (BOM)

Creates inputs (line items) on the product you’re importing into, plus any supplier parts and materials the rows reference. See What happens after upload for the full 3-level structure.
  • Matched by: products are matched by SKU and ownership; individual inputs are matched by their source product, quantity, and unit.
  • On a match: products are reused and left untouched. Inputs are only added to a product that was created during this import, is still UNKNOWN, or has no inputs yet. A product that’s already LIVE with inputs is treated as fully modeled and keeps its existing inputs.
  • Created new when: the product or input isn’t already present under those rules.
Sample rows (a root product on level 0, with a supplier part and its material on level 1):
bomLevel,productSku,productName,quantity,unitCode,supplierName,supplierPartId,materialName,weightAmount,weightUnitCode
0,BIKE-001,Mountain Bike,1,item,,,,,
1,RIM-001,Alloy Rim,2,item,RimSupply,RS-RIM-42,Aluminum Alloy 6061,0.3,kg
If a re-import isn’t adding inputs to a product, the product is most likely already LIVE with a model. See Import troubleshooting for how to add to it.

Suppliers

Creates a supplier company for each row, plus contacts when contact columns (name or email) are present.
  • Matched by: UUID, then your internal supplier ID, then supplier name.
  • On a match: the existing supplier is reused and left untouched. A contact is added only when no contact with the same email or name is already on that supplier.
  • Created new when: no supplier matches by ID or name.
Sample rows:
name,orgNumber,internalId,contactName,contactEmail
RimSupply,123456789,SUP-001,John Doe,john@rimsupply.com
TireCo,987654321,SUP-002,Jane Smith,jane@tireco.com

Locations

Creates a named location for each row, optionally geocoded to coordinates when address details are provided.
  • Matched by: location name, within the owning company - the company named in the companyId column, or your own company for locations you hold directly.
  • On a match: the existing location is reused. Address fields from your file fill in blanks but do not overwrite values that are already set.
  • Created new when: no location with that name exists for that company.
Sample rows:
name,address1,postCode,city,country,type
Bike Assembly Plant,Industriveien 12,3045,Drammen,Norway,factory
Oslo Parts Warehouse,Torggata 23,0183,Oslo,Norway,warehouse

Activity data, air travel, and transport

These three types record transactions and events - a purchase, a sale, a flight, a shipment. Each row becomes one activity record. Air travel and transport are activity types with their own columns (flight details, logistics weight and distance, and so on).
  • Matched by: nothing. Imported activity rows are not matched against existing activities.
  • Always created new: every row produces a new record on every import.
Sample rows - activity data:
name,direction,startDate,endDate,quantity,unitCode,productName,productSku
Aluminum tubing purchase Q1,Purchase,2026-01-15,2026-01-15,1200,kg,Aluminum Alloy 6061,ALU-6061
Sample rows - air travel:
direction,name,startDate,flightRoute,flightCabinClass,quantity
Purchase,Supplier visit Oslo to Taipei,2026-02-03,OSL-TPE,Economy,8300
Sample rows - transport:
direction,transportTypeName,startDate,endDate,name,logisticsWeightInKg,logisticsDistanceInKm
Purchase,Sea,2026-03-01,2026-03-20,Frame shipment Shanghai to Oslo,5000,18000
Because activity rows aren’t deduplicated, re-importing the same activity file will create the records again. Import each period’s data once. To correct activities you’ve already imported, edit or delete them in the app or via the API rather than re-importing - see the Activity API.

Why re-imports don’t update existing records

For products, materials, suppliers, and BOMs, a match means reuse, not update: Variable keeps the record you already have and ignores the newer values in your file. This prevents an accidental re-import from silently rewriting curated data. If you’ve fixed values in your source file and want them to land, edit the records directly in the app or via the API. Locations are the one exception - a re-import fills in any address fields that were previously blank, but still won’t overwrite values that are already set.

Next steps