Skip to content

CSV imports and exports

Merchants move data in bulk with CSV or Excel files. They export from the dashboard, edit and import again, or an integration writes a file in the same layout for the merchant to import. This page describes every file: its columns, the key a row is matched on, and what a blank cell means. Imports run in the merchant's dashboard. The one file the public API takes is the product file, through /v1/import (see Product import).

Rules every file follows

  • Column names are matched without regard to case and in any order. A header that appears twice, in any casing, refuses the whole file. A header the importer does not know is not imported. The company, product, locations and cost centres files list it as a warning; the customer and order files drop it without one (the order file notes only its own export-only columns that carry values).
  • Rows group into records. The company file has one row per company user, with the company columns repeated. The customer file has one row per address, the order file one row per order line, and the product file one row per variant or image. In the company and customer files a record's own columns may sit on any of its rows: the first value found counts, and rows that give different values fail the record. In the order and product files the first row of a group carries the record's own columns.
  • A blank cell keeps the current value, so an import never clears a field by leaving it empty. Where a column can be cleared, the word none clears it; the tables say where. The order file does not follow this rule: a matching row replaces the order (see The order file). In the other files there are two exceptions:
    • a Tags cell replaces the record's tags, so a blank Tags cell removes them;
    • a blank cf:<name> cell clears that custom field. Leaving the column out of the file leaves the field alone, and when a record spans several rows, a value in any of its rows wins over another row's blank.
  • Custom fields travel as one cf:<name> column per custom field definition, named after the definition. Leaving the column out of the file leaves the values alone.
  • default and all. In a column that overrides a store or company setting, default removes this company's or user's own choice, so a company follows the store again and a user follows their company. In a list of allowed locations or cost centres, all goes back to every one.
  • Create, update or both. At upload the merchant chooses whether rows that match nothing create records, whether rows that match update them, or both. A row the choice excludes is skipped and listed with its reason. In the company file the choice governs companies, not users: a new email on a company the file creates or matches always creates its user and customer account, even when "create" alone leaves a matched company as it is, and an existing user is updated only when updating is allowed.
  • Matching keys decide whether a row updates a record or creates one, so importing the same file twice changes nothing the second time, except in the order file:
FileA row matches
Companiesthe company whose Company External ID equals the cell, ignoring case; else, by Company Name ignoring case, a company that has no External ID yet, which then takes the row's. A row with no External ID matches by name any company, one with an External ID included; names need not be unique, so give companies External IDs before relying on names
Company users (rows of the company file)the user of that company with the row's User Email
Customersthe customer with the row's Customer ID (Orbit's id); else the customer with the row's Email, ignoring case
Ordersthe order imported earlier with the same Order Reference, or the order whose order number equals it
Productsby Handle, exactly, capitals included; or by SKU or Barcode, ignoring case, when the merchant picks that key, and then a row updates every product or variant with that value and never adds or removes a variant. An import that only creates always matches by Handle
Company locationsthe location of the row's company with the row's External Ref, ignoring case; else the one with the row's Branch name, ignoring case (when the row has an External Ref, only a location with no reference yet, which then takes it)
Cost centresthe cost centre of the row's company with the row's External Ref, ignoring case; else the one with the row's Code, ignoring case (when the row has an External Ref, only a cost centre with no reference yet, which then takes it; a code that belongs to a cost centre with a different reference fails the row: "Another cost centre of this company already uses this code.")
  • References keep your spelling. The company file's Company External ID, and the External Ref of the locations and cost centres files, match ignoring case and surrounding spaces, and the record they match takes the file's spelling. In the locations and cost centres files, Company External ID only finds the row's company.
  • Exports round-trip, except the order and product exports (see each file below). Every other export imports back unchanged, and importing the company file's export again writes nothing. An export's columns are the import's columns plus a few the platform computes, marked export only below; an import ignores those.
  • Results list how many records were created, updated, skipped and failed (companies, customers, orders and products are counted per record, locations and cost centres per row), each failure with its row number and reason. In the company and cost centre files, a record that matches and that the file would not change counts as skipped, with that as its reason. One bad row never stops the others, with two exceptions: the company file and the customer file are checked a record at a time, so a row that fails the check leaves out its whole company, with every one of its users, or its whole customer, with every address. In the order and product files a row that fails is left out, and its record imports from its other rows. In the company file, a note about a company or user applied only in part, such as a catalogue it could not find or a user it could not add, is listed with the failures, though the company still counts as created or updated.

The company file

ColumnImportValues
Company NameyesUp to 255 characters. A row needs Company Name or Company External ID; the name is needed to create a company, and an existing one can be matched by its External ID alone.
Company External IDyesYour id for the company, unique in the store ignoring case. A row whose id two older companies hold in different casings fails, naming the clash.
Company Statusyesactive or suspended.
Tax IDyesThe VAT or tax registration number.
NoteyesA note for staff; buyers never see it.
Pricing CatalogueyesThe name of a catalogue, set on the company's default location; none removes it.
Payment TermsyesThe name of a payment term, set on the default location; none removes it.
Tax Exemptyesyes or no, on the default location.
TagsyesTag names separated by commas.
Credit LimityesAn amount, or none for no limit (creditLimit).
On Stopyesyes or no (onStop).
Status NoteyesUp to 500 characters, or none (statusNote).
Order Approvalyesyes, no or default (b2bSettings.orderApprovalEnabled).
Over Spending Limityesrefuse, approval or default (b2bSettings.overSpendingLimit).
Over Credit Limityesrefuse_account, approval or default (b2bSettings.overCreditLimit).
Approval ThresholdyesAn amount, or none (approvalThreshold).
Approval Non Contractyesyes or no (approvalNonContract).
Authoriser EmailyesA company user's email, or none (authoriserContactId).
Second Authoriser EmailyesA company user's email, or none (secondAuthoriserContactId).
Approval Reminder HoursyesA whole number from 1 to 168, or default (b2bSettings.approvalReminderHours).
PO Number Ruleyesoff, optional, required or default (b2bSettings.poNumberMode).
PO FormatyesA mask, or default (b2bSettings.poNumberFormat).
PO Uniqueyesyes, no or default (b2bSettings.poNumberUnique).
Cost Centre Ruleyesoff, optional, required or default (b2bSettings.costCentreMode).
Cost Centres Managed Externallyyesyes, no or default (b2bSettings.costCentresManagedExternally).
Pay On Accountyesyes, no or default (b2bSettings.payOnAccountEnabled).
Branch Pickeryesyes, no or default (b2bSettings.branchPickerEnabled).
Delivery Instructionsyesyes, no or default (b2bSettings.deliveryInstructionsEnabled).
Lead Timesyesyes, no or default (b2bSettings.leadTimePerLineEnabled).
New Address At Checkoutyesyes, no or default (b2bSettings.newAddressAtCheckoutDefault).
Loyalty MultiplieryesA whole number from 1 to 3 (loyaltyMultiplier). Company loyalty is not in use yet, so the value changes nothing for now.
Loyalty Potyesshared, per_user or default (loyaltyPotMode); not in use yet.
Loyalty Redeemyesmanagers, managers_authorisers, everyone or default (loyaltyRedeemRoles); not in use yet.
User EmailyesThe user's email. A row with no user email carries the company only.
User First Nameyes
User Last Nameyes
User Roleyesadmin, buyer or viewer, a preset of permissions.
User PermissionsyesPermission flags separated by ;: can_view_company_orders, can_place_orders, can_add_users, can_delete_users, can_manage_permissions, can_request_quotes, can_view_company_quotes, can_view_invoices, can_pay_invoices, can_manage_company_profile, can_manage_addresses. Or none for no permissions. Wins over User Role.
User Spending LimityesThe largest order total, with up to two decimals. Blank on a new user means no limit.
Main Contactyesyes or no.
User Statusyesactive or inactive; suspended is read as inactive. An inactive user cannot sign in or order.
User Loginexport onlyverified when the user's email address is confirmed, pending when it is not. It does not say whether they have set a password.
User Approves Ordersyesyes or no (canApproveOrders).
User Approval LimityesAn amount, or none (approvalLimit).
User Over Spending Limityesrefuse, approval or default (overSpendingLimit).
User Pay On Accountyesyes, no or default (payOnAccount).
User May Enter New Addressyesyes, no or default (mayEnterNewAddress).
User Visibility CatalogueyesA restricted catalogue's name, or none (visibilityCatalogId).
User LocationsyesBranch names or external refs separated by ;, or all for every location (allowedLocationIds).
User Cost CentresyesCost centre codes separated by ;, or all for every active cost centre (allowedCostCentreIds).
User Default Billing LocationyesA branch name or external ref, or none (defaultBillingLocationId).
User Default Shipping LocationyesA branch name or external ref, or none (defaultShippingLocationId).
cf:<name>yesOne column per company custom field.

In User Locations and the two default location columns, a branch is named by its External Ref or its name. A cell that could name two locations (one location's External Ref and another's name, or the name of two locations) is noted and the field left as it is: use an External Ref only one location has, or rename one of them. A deleted location a user still holds is exported by its External Ref or name rather than as all, and an import that names it notes it and leaves the field as it is. The words all and none keep their meaning only while nothing they could name is called that. A location named All or None, or with that word as its External Ref, or a cost centre coded all, from before those words were refused, makes a cell reading the word a clash, which is noted and the field left as it is: change that External Ref or code, or rename the location. all with other values in a list is noted too, and the list left as it is. Where the store has a catalogue or a payment term actually called None, a none cell never clears one. In Pricing Catalogue and Payment Terms, a default location already holding that record is left alone without a note, and any other keeps its value with a note asking you to rename the catalogue or payment term; in User Visibility Catalogue, the user's catalogue is left as it is, with the same note. A Status Note that already reads None is not cleared by a None cell.

The customer file

ColumnImportValues
Customer IDyesOrbit's id for the customer, as the export writes it. Leave it blank for a new customer: an id Orbit does not know fails the row. Keep your own system's id in a cf:<name> column.
First Nameyes
Last Nameyes
Emailyes
Phone Country Codeyes
Phoneyes
Notesyes
Marketing Email ConsentyesThe export writes true or false; the import reads true, yes, 1 or y as yes and anything else as no. Blank keeps the value, or means no for a new customer.
Marketing SMS ConsentyesThe export writes true or false; the import reads true, yes, 1 or y as yes and anything else as no. Blank keeps the value, or means no for a new customer.
Transactional SMS ConsentyesThe export writes true or false; the import reads true, yes, 1 or y as yes and anything else as no. Blank keeps the value, or means no for a new customer.
Tax ExemptyesThe export writes true or false; the import reads true, yes, 1 or y as yes and anything else as no. Blank keeps the value, or means no for a new customer.
Tagsyes
Customer GroupsyesNames of existing customer groups, separated by commas, matched ignoring case; an unknown name is a warning. An import only ever adds a customer to a group, never takes one out.
Address IDyesOrbit's id of the address the row updates; an id that is not one of the customer's skips the row's address, and a value that is not an id fails the customer. When it is blank and the customer has one address row in the file, the row updates their default shipping address, else their oldest, and adds one only when they have none. With several address rows, a blank one updates the address with the same Address1 and Postal Code, ignoring case, and adds one when none matches.
Address First Nameyes
Address Last Nameyes
Companyyes
Address1yes
Address2yes
Cityyes
Stateyes
Postal Codeyes
Countryyes
Address Phone Country Codeyes
Address Phoneyes
Default Shippingyesyes or no; yes takes the default from the customer's other address, and blank keeps it.
Default Billingyesyes or no; yes takes the default from the customer's other address, and blank keeps it.
Account Typeyesstandard or company. It must match an existing customer's type; an import never changes it. A new customer is always standard: company customers are created through the company file.
Price Displayyesinc or ex: whether the customer sees prices with or without VAT; none removes the choice. The same value is priceDisplay on /v1/customers.
Company Nameexport onlyThe company the customer belongs to.
Company External IDexport onlyThat company's External ID.
cf:<name>yes

The order file

A row group whose Order Reference matches an order replaces that order: its lines, amounts and statuses all come from the file. A blank amount reads as 0 (a blank Tax Amount or Discount Amount adds up the lines' own instead, and a blank Item Quantity is 1), a blank Payment Status reads as payment_due, a blank Type as order, and a blank Order Status follows from the payment status. Only Notes, PO Number, Delivery Instructions, Branch, Order Date and the addresses keep their value when blank, and a matched order keeps its currency. Each import also adds the order's shipping and billing addresses to the customer's address book, so every run adds them again. The order's customer is found by Email in lower case, compared exactly: a customer saved with capitals in their email is not found, and the import creates a new customer. A row that fails validation is left out, and its order imports from the rest of its rows, so a matched order loses that line.

ColumnImportValues
Order ReferenceyesRequired; groups the rows of one order.
Typeyesorder or draft; blank is order.
Order DateyesA date, YYYY-MM-DD, with an optional time and zone, such as 2021-03-04T14:22:10Z or 2021-03-04 14:22:10 +0000; a value without a zone is read as UTC. It cannot be in the future.
Emailyes
Customer First Nameyes
Customer Last Nameyes
Currency Codeyes
Order Statusyespending, processing, awaiting_balance, completed, canceled or refunded. Blank follows from the payment status; any other value reads as pending.
Payment Statusyespaid, succeeded, payment_due (also unpaid), partially_paid, awaiting_payment, processing, refunded, partially_refunded, canceled or failed; blank reads payment_due. Use payment_due for an order the customer still owes. pending is only valid on a draft. The export can also write authorized, captured, disputed and expired, which do not import back: a row with one fails as an unrecognised Payment Status.
Amount PaidyesRequired for partially_paid.
Prices Include Taxyestrue or false (yes, y and 1 also read as true): whether Item Price already includes its VAT, so an order's line totals do not add Item Tax on top. Read from the order's first row; blank takes the store's own pricing mode. Shopify's Taxes Included column is read the same way. The export writes it on each order's first row.
Shipping Amountyes
Tax Amountyes
Discount Amountyes
Notesyes
Item Nameyes
Item SKUyes
Item Priceyes
Item Quantityyes
Item Discountyes
Item Taxyes
Shipping Address1yes
Shipping Address2yes
Shipping Cityyes
Shipping Stateyes
Shipping Postal Codeyes
Shipping Countryyes
Billing Address1yes
Billing Address2yes
Billing Cityyes
Billing Stateyes
Billing Postal Codeyes
Billing Countryyes
PO NumberyesThe buyer's purchase order number.
BranchyesThe branch name or external reference of the customer's company location, matched within their company. The export writes the location's External Ref when it has one, else its name. A cell that could name two locations is not imported, with the note Branch "X" was not imported: and the reason.
Delivery InstructionsyesThe order's own delivery instructions, up to 1000 characters.
Item Cost Centre CodeyesThe code of a cost centre of the customer's company, matched ignoring case.
Item Lead Time DaysyesA whole number of days, from 0 to 9999, until the line could ship; a row with any other value is refused on its own, with the reason.
Item Expected DateyesA real date written YYYY-MM-DD; a row with an impossible date is refused on its own, with the reason.
Is Draftyestrue or false. The export still writes it and the import still reads it: a row is a draft when Type is draft or Is Draft is true. The import template leaves it out.
Order Numberexport only
Subtotalexport only
Totalexport only
Item Totalexport only
Item Bundle Nameexport only
Item Bundle Groupexport only
Payment Flowexport onlyHow the order is paid, as recorded when it was placed: on_account, manual, gift_card or loyalty_points; blank for other orders.
Amount Dueexport onlyWhat is still owed.
Due Dateexport onlyYYYY-MM-DD.
Item Cost Centre Nameexport onlyThe cost centre's name as it was at placement.
Approval Stateexport onlyawaiting, approved or declined.
Approved Byexport onlyThe name of who decided the order.

The product file

The product export does not import back unchanged. Its Quantity is the quantity stored on the product, not the live stock, and an import sets the stock of every product it matches from that column, so take the column out of an export you import again unless you mean to set stock. A scheduled product's row fails, Bundle Components are not applied, and Taxonomies holds only each product's primary path. With SKU or Barcode as the match key every row is matched on its own, so a blank Tags or cf: cell on a variant's row clears that product's tags or custom field; the export fills those cells only on a product's first row.

ColumnImportValues
HandleyesThe product's URL handle; the default match key.
Nameyes
Descriptionyes
Short Descriptionyes
BrandyesA brand's name, matched exactly, capitals included; a name that matches no brand creates a new, live brand. Blank keeps the brand.
Product Typeyesphysical, digital, subscription, service, gift_card or bundle; an unknown value is read as physical. A blank cell makes a new product physical and keeps an existing product's type.
Custom TypeyesThe name of a custom product type.
Tagsyes
Statusyesactive, draft or archived; any other value, scheduled included, fails the row. Blank keeps an existing product's status; a new product is active, or draft when none of its rows has a price.
SKUyes
Barcodeyes
Manufacturer Part NumberyesUp to 50 characters: on each variant's row for a product with options, else on the product's first row. Blank keeps it, and a value that is too long or holds control characters is skipped with a warning.
Search KeywordsyesExtra words the store's search finds the product by, separated by commas or spaces; never shown to shoppers. On the product's first row; blank keeps them. Up to 1,000 characters: a longer value is cut at the last whole keyword before the limit, with a warning naming what was dropped.
Replacement SKUyesThe SKU of the product that replaces this one once it is discontinued, on the product's first row: a product's SKU, or a variant's, which means its product. Matched without regard to capitals. Blank keeps the current replacement. A SKU this store does not have, the product's own, or one whose replacements lead back to this product is skipped with a warning, and the rest of the row imports.
QuantityyesSets the stock of the product or variant the row matches.
Is Physicalyes
Is Taxableyes
Weightyes
Weight Unityes
Dimensions Lengthyes
Dimensions Widthyes
Dimensions Heightyes
Dimensions Unityes
Priceyes
Compare At Priceyes
Cost Priceyes
CategoriesyesManual category (collection) names separated by commas.
SEO Titleyes
SEO Descriptionyes
SEO Keywordsyes
Image URLyes
Image Positionyes
Image Altyes
Option1 Nameyes
Option1 Valueyes
Option2 Nameyes
Option2 Valueyes
Option3 Nameyes
Option3 Valueyes
Option4 Nameyes
Option4 Valueyes
Option5 Nameyes
Option5 Valueyes
Variant Image URLyes
Variant Shipping Classyes
Shipping Classyes
Inventory Policyyescontinue or deny.
Track Inventoryyestrue or false.
TaxonomiesyesPaths in the standard product category list, levels separated by > and paths by commas, such as Home & Garden > Kitchen & Dining > Tableware > Drinkware > Mugs; each level matches ignoring case. A path that is not in the standard list is skipped with a warning, and a category whose name holds a comma cannot be named. A matched path replaces the product's taxonomies.
HS Codeyes
Country of Originyes
Customs Descriptionyes
Bundle Componentsexport onlysku:qty pairs. The import does not apply them: set a bundle's components in the dashboard.
Image Variant SKUyes
Tax ClassyesAn unknown class fails the product, with all its rows.
cf:<name>yesOne column per product custom field. All the columns above are importable.

The company locations file

ColumnImportValues
Company External IDyesThe company the branch belongs to; matched first, ignoring case. A row whose id two companies hold in different casings is refused, naming the clash.
Company NameyesThe company's name, used when the external id is blank.
BranchyesThe branch name buyers see at checkout. A new or changed name cannot be all or none, in any casing; a name the location already has passes.
External RefyesYour own reference for the branch, unique within the company. A new or changed reference cannot be all, none or default, in any casing.
Defaultyesyes or no; the company's default branch, used when an order names no branch.
Billing Address1yes
Billing Address2yes
Billing Cityyes
Billing Stateyes
Billing Postal Codeyes
Billing Countryyes
Billing Phoneyes
Shipping Address1yes
Shipping Address2yes
Shipping Cityyes
Shipping Stateyes
Shipping Postal Codeyes
Shipping Countryyes
Shipping Phoneyes
Delivery InstructionsyesStanding instructions for every delivery to this branch; none clears them.
PO Requiredyesyes, no or default; default follows the company's poNumberMode. It counts only while that mode is optional or required: while it is off, PO numbers are not used and this cell changes nothing.
Payment TermsyesThe name of a payment term, or none.
Pricing CatalogueyesThe name of a catalogue, or none.
Tax Exemptyesyes or no.

Each address you send replaces the stored one whole. As in the company file, a none cell never clears a catalogue or payment term when the store has one actually called None, and Delivery Instructions that already read None are not cleared by a None cell.

The cost centres file

ColumnImportValues
Company External IDyesThe company the cost centre belongs to; matched first, ignoring case. A row whose id two companies hold in different casings is refused, naming the clash.
Company NameyesThe company's name, used when the external id is blank.
CodeyesThe code buyers pick, unique within the company ignoring case. A new or changed code cannot be all, none or default, in any casing; a code the cost centre already has passes. A row matched by its External Ref renames the cost centre to this code.
NameyesWhat the code stands for.
External RefyesYour own reference for it, unique within the company. A new or changed reference cannot be all, none or default, in any casing. Rows that repeat a reference for one company, in any casing, fail.
Statusyesactive or archived.
UsersyesEmails of the company users allowed to charge this cost centre, separated by ;, or none to take it from every user; the export writes none for a cost centre nobody is given. If any email in the cell is not a user of the company, the cost centre's users are left as they are and each unknown email is noted. A user given any cost centre here can charge only the ones they are given.

Every row for a company whose Cost Centres Managed Externally is on fails with "This company's cost centres are managed by its accounts system. Change them there, or through the API.", whichever columns it fills.

Next steps