The plain-language guide
Why your spreadsheet doesn't have to match our template.
Two testers spent half their onboarding session renaming columns in a spreadsheet before they gave up. The fix wasn't a better template. It was asking one question before anything imports.
The short answer
Keep your own column names. When a file's headers don't match ours, ForeFlux guesses which is which — Branch Name becomes Name, SKU becomes Product ID — and shows you every guess, with the first row of your data next to it, before a single row gets read as data. You confirm or fix the guess. Only then does anything import.
The rename-your-sheet problem
We watched two owners try to bring their existing spreadsheets into ForeFlux during onboarding. Neither sheet was messy. Both were real business records: branches with their own IDs and addresses, products with their own SKUs and unit costs, in the columns each owner had already been using for months. Neither header row matched ours, and the templates said so plainly — missing columns: Name, Opens, Closes. Both owners did the same thing next: they left the product, opened the file in Sheets, and started renaming columns by hand. One asked an AI assistant to do the renaming for her. By the end of the session, neither had imported a row.
The template wasn't wrong. Every import needs to land under one set of names, or nothing downstream — the header check, the preview, the count that turns into a forecast — knows what a column means. The mismatch was real. Making the owner fix it by hand, in a different app, before she could even see whether the product worked, was the part that didn't have to be true.
A second bug hiding under the first
Pasting was worse than uploading. The import screen also takes pasted rows, copied straight out of a spreadsheet, and it decided whether the first row was a heading or data by checking whether two cells landed in the same position as two of our template's headings. A real sheet like Branch ID, Branch Name, Address, Opened, Days Open, Hours… scores exactly one positional hit against our Branch ID, Name, Opens, Closes, Open days — one column, not two — so the threshold was never met. The heading row silently became a data row. Somewhere in the product, "Branch ID" was about to be imported as the name of a real branch.
The fix wasn't a smarter threshold. It was dropping "position" from the rule entirely: a cell now counts as a heading the moment it matches any template heading or a known synonym, wherever it sits in the row. The bar stays at two matching cells — one column named "Name" by coincidence still reads as data — but a whole heading row under the owner's own names is recognized as a heading row again, on both the upload door and the paste door.
Three guesses, checked in order
Once a mismatch is caught, ForeFlux doesn't ask you to solve it blind. It proposes an answer, one guess per template column, tried in order until one lands:
- Exact match, loosely spelled. The same tolerance the header check already grants — case, extra spacing, column order — so a file that would have passed anyway is never asked anything.
- Same words, different order.
Days Open,open_days, andOpen daysall fold to the same set of words, so this tier catches formatting differences a strict match would miss — but it still counts as a guess, not a pass, because the header check itself would have refused it. - A synonym table.
Branch Name,Outlet, andStoreall mean the header we call Name.SKU,Item Code, andProduct Codeall mean Product ID.Unit CostandBuying Priceboth mean cost_price. One flat table, shared across every import screen, because "name" means the same thing on a branches file, a products file, or a suppliers file.
A column is only ever claimed once. If two template columns could plausibly want the same file column, the earlier one — checked first, in template order — gets it, so a synonym guess on one field can never steal an exact match that belongs to another.
| Your column | Our template column | Tier | |
|---|---|---|---|
| Branch ID | → | Branch ID | exact |
| Branch Name | → | Name | synonym |
| Days Open | → | Open days | same words |
| Address, Opened, Hours, Floor Area, Staff… | → | left out | no match |
Nothing imports on a guess
Every guess is shown, not applied. One row per template column, a dropdown pre-filled with the guess, and the actual value from your file's first line sitting next to it, so a wrong guess is a glance, not a surprise three screens later. A required column with no confident match still lets you continue — it lands empty, tinted so you notice, and you can type the value straight into the grid afterward instead of being blocked entirely. Columns nothing claims, like a notes field or a floor-area column, are listed by name under Left out, so you can see exactly what didn't come along, rather than wondering if it vanished.
One button accepts the mapping and rewrites the grid under our headings, ready for the same preview every template file goes through. A second button, Keep the file's own columns, is the escape hatch for when the guess is wrong or the file is closer to our template than it looks — it leaves the grid exactly as it landed.
Why a mismatch used to mean giving up
Before this, an owner's own spreadsheet met the header check with a flat refusal: a list of missing columns and a disabled Confirm button. Technically correct, and useless for anyone who had never seen our template before. The two testers who left for Sheets weren't confused about their own data. They were being asked to speak our language before we'd offered to learn a word of theirs.
Where ForeFlux picks up
The mapping runs on every bulk import door — branches, products, suppliers, sales history, stock counts — not just the first one you meet during onboarding. It never touches the numbers underneath: the header check, the preview, and the forecast engine all still work exactly as before, reading whatever grid lands in front of them. The mapping only decides which of your columns is which, once, before any of that runs. The rule stays the same as everywhere else in the product: we suggest, you decide. A guess is never final until you say so.
Questions owners ask
Past the basics.
What if none of my columns match?
You pick from a dropdown, one per template column, with the first row of your file shown beside each guess so you can check it before you commit. A required column with no match still imports — it lands empty, and you fill it in on the grid afterward. Nothing is refused outright.
What happens to columns I don't need, like a notes or floor-area column?
They're listed as left out, by name, so you can see nothing silently vanished. They're dropped from the import, not read as data and not flagged as an error.
Does this work if I paste rows instead of uploading a file?
Yes. Pasting used to be the riskier door: a heading row under your own names could be mistaken for a row of data and imported as if "Branch ID" were a real branch. Recognizing a heading row no longer depends on your columns landing in our order, so a pasted sheet gets the same question a file upload gets.
Bring your own spreadsheet, keep your own names
Know what you need, before you need it.
The demo needs no signup and no card. It is the real product running on demo data.
Open the order sheet