Bring Your Own Data
Export. Rename. Upload.
Wherever you sell, your data comes in from a spreadsheet. Three files: what you sell, what's on the shelf, and what actually sold. Send those and Skuvelo is planning against your own numbers. No connector required, and no wizard to sit through.
That's Genuinely the Whole Process
There is no wizard to sit through and no field-mapping screen to learn. You export what you already have, rename the header row, and upload it.
Export
Download CSVs from the platform you sell on. The button is usually filed under Reports or Data.
Rename
Match the header row to our column names. That is the entire mapping. Anything we don't recognize is ignored.
Upload
Upload them from the Import data screen in your workspace, products first.
Plan
Cover and reorder points recalculate against the orders you marked as shipped.
Three things worth knowing before you start
- Name your stock locations in the workspace first. The stock file refers to them by name, and one location is a perfectly normal setup.
- On the history file, every row needs a status. Send fulfilled for anything that already shipped. Skuvelo refuses a blank rather than filing the order as still open, which would reserve stock and count as no demand.
- If your export is not US-formatted, check the separator, the decimal mark, and the date order before you upload.
Three Files. That's the Whole Job.
You do not need every field. A list of what you sell, a count of what is on the shelf, and enough sales history for the arithmetic to work on. Most of the rest is optional, and the few places where that is not true are called out where they matter.
File one
Your product list
What do I sell?
One row per SKU: your code, the name, and a cost if you have one.
.csv or .xlsx5,000 rows per file
File two
What's on the shelf right now
How much do I have, and where is it?
One row per product per place you keep it. The same SKU in two locations is two rows.
.csv2,000 rows per file
File three
Your sales history
What actually sold, and how fast?
One row per line on an order. A three-product order is three rows sharing one order number.
.csv2,000 rows per file
Send them in that order: nothing can attach to a SKU Skuvelo has not been told about yet. Files cap at 2,000 rows each (5,000 for the product file), and you can upload as many as you need. About 12 months of sales history gives the forecast a useful baseline; seasonal methods wait for two full years of weekly history.
Every column, for all three files
Your product list
| Column | Needed? | What it is |
|---|---|---|
| sku | Required | Your code for the item. Whatever you already call it is fine, as long as you use the same code in the other two files. |
| title | Required | The product name. Required for anything Skuvelo has not seen before, which on your first file is everything. |
| category | Optional | How you group it. Useful for reading reports later. |
| brand | Optional | Who makes it. |
| unit_costalso reads unitcost | Optional | What you pay for one. Costs are what turn a stock level into a cash number, so include them if you have them. |
| selling_pricealso reads sellingprice | Optional | What you charge. |
| standard_costalso reads standardcost | Optional | Your planned or budgeted cost, if you keep one. |
| last_costalso reads lastcost | Optional | What the most recent purchase actually cost. |
| supplier_costalso reads suppliercost, supplierprice, vendorcost | Optional | What your supplier charges for one unit. Lands on the product's supplier price list, the number purchase orders and buy recommendations are priced with. Applied only when the product already has a linked supplier. Changed in August 2026: columns named Supplier Cost or Supplier Price previously filled the product's own unit cost; they now fill the supplier price list instead. If your file used one of those names for the product's own cost, rename that column to unit_cost. The import result states how many supplier costs were applied and how many were skipped for want of a linked supplier. |
| image_urlalso reads imageurl, productphoto | Optional | A web address for the product photo. Inventory, Planning, and Today show it as a thumbnail. |
- Products created by an import are marked as needing a check rather than treated as verified. Nothing plans against a number nobody has looked at.
- This is also the one file you can send as a spreadsheet. Stock counts and order history have to be CSV.
What's on the shelf right now
| Column | Needed? | What it is |
|---|---|---|
| skualso reads product_sku | Required | Must match a product already in Skuvelo. |
| locationalso reads location_name, warehouse | Required | The place the stock is. It has to be a location you have already named in Skuvelo. Capitalization does not matter, the rest of the name does. |
| on_handalso reads onhand, quantity, stock_level | Required | The number you would get by walking over and counting. A whole number, zero or more. Not a change, not an adjustment. The count. |
- Skuvelo works out the difference between your count and what it currently believes, and files that difference as one dated entry. It does not overwrite a quantity and it does not rewrite what came before, so you can always see what changed and when.
- The first stock movement for a SKU at a location is recorded as its opening balance rather than a correction, so your starting position is never mistaken for someone changing a number later. If that SKU has already moved at that location, for example a receipt against a purchase order, then your file is a correction, because the starting position was already set.
- Your column headings do not have to match ours. “Item Code”, “Qty On Hand” and “Warehouse” are all understood. What Skuvelo will not do is guess: if it cannot tell which column holds your count, or two columns could both be it, the file is refused and nothing is imported.
- If you keep everything in one room, that room still needs a name. One location is a perfectly normal setup.
- The same SKU and location twice in one file is rejected rather than guessed at. Decide which count is right and keep that row.
Your sales history
| Column | Needed? | What it is |
|---|---|---|
| order_numberalso reads order_id, external_order_id | Required | Whatever your platform calls the order. Rows sharing this number are treated as one order. |
| skualso reads product_sku, line_sku | Required | What was on that line. |
| quantityalso reads line_quantity, qty | Required | How many of it. A whole number, at least one. |
| unit_pricealso reads price, line_price | Required | The price for one, with a period for the decimal. 1299, 1299.00, and 1,299.00 all read. £1,299.00 reads too, but only when the currency column says GBP. A symbol with no currency column behind it is refused rather than quietly imported as dollars. A comma decimal like 1299,50 is refused rather than guessed at, because there is no way to tell it apart from a thousands separator. |
| statusalso reads order_status | Required | Where the order got to. Send fulfilled for anything that has already shipped. On historical orders that is nearly every row. Skuvelo will not guess this one: an order with no status would be filed as still open, which reserves stock it is never going to ship and counts as no demand, so a blank comes back as a rejected row instead. |
| titlealso reads line_title, product_title | Optional | What the line was called on the order. Defaults to the SKU. |
| currency | Optional | Three letters, such as USD or GBP. Defaults to USD. |
| placed_atalso reads order_date, created_at | Optional | When the order was placed, written year-first: 2026-08-03, or a full timestamp like 2026-08-03T10:30:00Z. 03/08/2026 is refused, because that is 3 August to most of the world and 8 March to a US reader and guessing gets it wrong half the time. Leave the column out and the order is dated today: fine for something that just came in, wrong for four years of history. |
| quantity_fulfilledalso reads fulfilled_quantity, qty_fulfilled | Optional | How many of that line actually shipped, when it is not all of it. A fulfilled status already implies the whole line, so this is only needed alongside partially_fulfilled, where it is required because the status alone does not say how much went out. |
| quantity_cancelledalso reads cancelled_quantity, qty_cancelled | Optional | How many were cancelled. |
| quantity_returnedalso reads returned_quantity, qty_returned | Optional | How many came back. |
Statuses the importer recognizes: fulfilled, partially_fulfilled, cancelled, partially_cancelled, returned, partially_returned, imported, mapped, allocated.
Send fulfilled for anything that has already gone out. The last three (imported, mapped, allocated) describe an order that has not shipped: they reserve stock and count as no demand, which is right for a live order and wrong for history. The three partially_ statuses need their matching quantity column (quantity_fulfilled, quantity_cancelled, quantity_returned), because a status alone does not say how much moved; without it the row is refused rather than filed as though nothing shipped.
- Rows belonging to one order have to agree on currency, date, and status. They are describing the same order, so a disagreement is a sign the export split something oddly.
- History is what makes replenishment advice worth reading. A product list and a stock count tell Skuvelo what you have; only sales history tells it how fast it leaves.
- Mark shipped orders as shipped. Skuvelo measures how fast a product leaves from the orders that actually left, so a status is required on every row rather than assumed. A file without one is refused instead of quietly filing your history as a pile of open orders.
You Can't Break It by Uploading Again
And one bad line never sinks a file. The good rows land while the rest come back to be fixed.
The same file twice does nothing.
Stock and order imports recognize a file they have already processed and return the original result. No doubled counts, no duplicate orders.
A corrected file just corrects.
Products are matched on SKU, so a second file updates what is there rather than making a second copy of everything.
What a person set by hand stays set.
A cost or title someone on your team fixed is not quietly overwritten. Which source wins for which field is yours to control.
Nothing is edited away.
A stock correction is filed as a new dated movement, so what you believed and when survives the correction.
The Detail, If You Want It
None of this is required reading before you start. Open the one you hit.
Getting the file out of your platform
You are not converting anything or mapping fields in a wizard. You are exporting what you already have and renaming a header row.
Find the export. It is almost always there.
Nearly every selling platform can hand you a CSV, usually filed under Reports, Data, or a download link on the products or orders screen. If yours has buried it, its support team will know where. Ask them for a CSV of your products, your stock levels, and your orders.
Rename the header row. That is the mapping.
Do not reformat the data or delete columns you are unsure about. Anything Skuvelo does not recognize is ignored. The only row that matters is the first one. Capitalization does not count and a space works the same as an underscore, so Unit Cost and unit_cost are the same column.
If your export is not US-formatted, check three things.
This is the one part worth two minutes of attention, and it matters most outside the US. Fields must be separated by commas, not semicolons. A semicolon export arrives as one long column. Prices must use a period for the decimal: 12.50, not 12,50. Dates must be year-first: 2026-08-03, not 03/08/2026. Skuvelo refuses what it cannot read unambiguously rather than guessing, so you get the rows back instead of the wrong numbers, but it is faster to fix the file once than to fix a hundred rows. One catch worth knowing: a comma followed by exactly three digits is read as a thousands separator only when the currency is one that writes decimals with a period. In USD or GBP, 1,250 is one thousand two hundred fifty. In a currency that writes decimals with commas (EUR is the common one), the same cell could be either one thousand two hundred fifty or one and a quarter, so it comes back rather than being guessed at. Writing 1250.00 or 1.25 removes the question. If your decimals are commas, convert the whole column rather than trusting it row by row.
If your prices carry a symbol, send a currency column with them.
A currency symbol is read only when a currency column says the same thing. $ € £ ¥ ₹ ₽ ₩ ₪ ₺ are recognised, and a row whose symbol contradicts its currency column, or that has a symbol and no currency column at all, comes back rather than importing as dollars. Symbols written with letters (R$, CHF, kr, zł, Kč, A$) are not recognised at all, so send those prices as bare numbers with a currency column. What also cannot be read is a price with a note in it, a range, a blank where a number should be, or a cents mark like 50¢. Write fifty cents as 0.50. JPY, KRW, CLP are refused outright even with a matching symbol and currency column, because imports don't yet handle a currency with no decimal minor unit (¥1,299 is 1,299, not 1,299.00), and reading one today would store the amount 100× high. BHD, KWD, OMR are refused for the opposite reason: their minor unit is a thousandth, which imports cannot store exactly, so a price like 12.345 comes back rather than silently dropping the third digit.
Split anything enormous. Not into more files than you need.
The row limit is per file, not per business, so a large catalog or several years of orders goes in as a few files in sequence and nothing is lost by splitting them. Stock and order imports do each count against a daily allowance, though, so split into the fewest files that clear the row limit rather than one file per week of history.
Why a row would come back
Rejected rows come back as a list: the row number, the SKU or order number it was on, and what was wrong with it.
- A SKU that is not in Skuvelo yet
- Send the product list first, or add the missing SKU to it and resend.
- A location name that does not match one you have set up
- Check the spelling against your locations. Capitalization is the only difference that is forgiven.
- The same SKU and location twice in one stock file
- Two counts for one shelf is a question, not an instruction. Keep the row that is right.
- A count that is not a whole number, or is below zero
- on_hand is a plain whole number. Negative stock is a symptom to look at, not a figure to import.
- A count or quantity above one million
- A single line for more than a million units is almost always a stray digit or a unit-of-measure mix-up, so it is refused rather than filed.
- A price written with a comma decimal, such as 12,50
- Use a period: 12.50. A comma followed by one, two, or four-plus digits cannot be told apart from a thousands separator, and reading it wrong would multiply the line by a hundred, so it is refused instead. A comma followed by exactly three digits is the one shape that can still read, as a thousands separator: 1,250 imports as one thousand two hundred fifty, but only when the currency is one that writes decimals with a period. Send that shape in EUR or another comma-decimal currency and it comes back too, because there is no way to tell 1,250 from one and a quarter.
- A currency symbol that the currency column does not match
- Send a currency column whose code matches the symbol: £ with GBP, € with EUR, ¥ with CNY. Without one the file would be read as dollars, so the row is returned instead of being imported as the wrong money.
- A price in JPY, KRW, CLP, even with a matching symbol and currency column
- Imports don't yet support a currency with no decimal minor unit (¥1,299 is 1,299, not 1,299.00), so reading one today would store the amount 100× high. The row is refused rather than imported wrong; convert the file to a currency with cents first.
- A price in BHD, KWD, OMR
- Imports store two decimal places, and these currencies have three (a fils, a fil), so a price like 12.345 is refused rather than silently dropping the third digit. Convert the file to a currency with a standard 2-decimal minor unit first.
- A date that is not year-first
- Write 2026-08-03. 03/08/2026 means two different days depending on who exported it, so it is refused rather than guessed at.
- A price the importer cannot read for any other reason
- Numbers, currency symbols, and thousands separators are fine. Notes, ranges, and blanks are not.
- Lines of one order that disagree about currency, date, or status
- They describe a single order. Make the shared fields match across its rows.
- A status the importer does not recognize
- Use one of the listed values, and map whatever your platform calls a shipped order to fulfilled. The column is required, so dropping it is not a way around this. The upload is refused outright.
Sizes, formats, and limits
- File size
- Up to 8 MB per file
- Product file
- .csv or .xlsx, up to 5,000 rows per file. Upload as many files as you need
- Stock file
- .csv, up to 2,000 rows per file. Upload as many files as you need
- Order file
- .csv, up to 2,000 rows per file. Upload as many files as you need
- Encoding
- Comma-separated, UTF-8
- Decimals and dates
- Period for the decimal, year-first dates
- Fair use
- Stock and order imports count against a bounded daily allowance. The applicable limit is stated before your account is activated.
What file import is not
Worth being straight about, because a file and a live connection are not the same thing.
It is not live sync.
A file is a snapshot. Your numbers are right as of the last file you sent and stay that way until you send another. Nothing schedules that for you today, and there is no way to point Skuvelo at a folder and have it pick files up. A refresh is something you ask for, within a daily allowance, not something that happens overnight on its own.
It does not write back to your platform.
An imported channel is read-only in Skuvelo. Nothing here changes your listings, your prices, or the stock number your storefront shows.
It does not make a planned connector any closer.
Connector status is on the integrations page and nowhere else. A channel listed as planned is planned: not connected, and not on a date we have promised you.
What you put in can be exported back out.
Your product list exports to CSV from the Products screen, in exactly the columns the importer reads, so that one round-trips. Order history exports from the Orders screen, inventory levels export from the Inventory screen, and report views export too. A cost the workspace does not know exports as an empty cell rather than a zero, so a spreadsheet sum stays honest.
This Isn't a Waiting Room
Files are not the thing you use until the real thing arrives. Where a connector exists it takes over the data it owns, and the matching upload steps aside so a file can never double-write what the sync is already handling. Where there is no connector, a file is not a fallback — it is the whole path, and it stays the whole path. Both of those are the product working the way it should, not a gap in it.
Not Sure Your Export Has What We Need?
Tell us where you sell and what your export looks like. You will get an answer from someone who knows the importer.