Back to all postsA paper triangle, circle, and square resting in a row on a dark bar

Customer Data Onboarding: A Guide for B2B SaaS

Customer data onboarding is everything between a customer choosing your product and their existing records being usable inside it. Whatever they need on day one already exists somewhere else. It sits in a spreadsheet a team has maintained for years, in an export from the tool they are leaving, or in a report someone pulled from a system nobody has admin access to any more. Onboarding is the work of moving those records out of that shape and into yours: getting the file, reading it, matching its columns to your fields, translating its values, checking the rows against your rules, and fixing what is wrong before any of it is submitted. This guide walks through those stages in the order a real customer hits them.

That work has an owner, and the owner is often not the person you would expect. Usually it is a customer success manager with the client's spreadsheet open in one window and your admin panel in the other. Sometimes it is an engineer writing a script for one client and a second script for the next. And sometimes it is the customer, alone in an upload screen you shipped two years ago, guessing what your fields expect.

Onboarding, migration, integrations, and pipelines

Data migration is the one time bulk move of records out of an old system into a new one, run by your team as a project with an end date. Onboarding overlaps with it and then keeps going after the project closes, because every new customer arrives with the problem the last one had.

An integration is a live connection between two systems over an API, where data keeps flowing without anyone exporting anything. Where one exists, onboarding gets far easier. Often there is none, because the tool your customer is leaving has no API worth using, or because the data was never in a tool at all.

A data pipeline moves files on a schedule. A partner drops a file on a server every night, a job picks it up, and nobody watches it unless it breaks. That is a real category with real products in it, and a different shape of work from a person sitting down with one file on their first day.

Product onboarding is a different thing again: the tours, the checklists, the welcome emails. A customer can finish every step of a product tour and still have an empty account.

Nothing in the product works until the data is in

The account is created, the team is invited, and then someone has to put the data in. Until that happens the product is a set of empty screens and the value the customer paid for is theoretical. The dashboard, the first report, the automation that saves them an afternoon, all of it waits on the data being there, which is why onboarding gets attention out of proportion to how small it looks on a roadmap.

Getting the file, in whatever shape it arrives

You do not control the format. The customer exports from what they have, so CSV arrives from one team and XLSX from another, with XLS, XLSB, or ODS turning up from a machine nobody has updated in a while. JSON and XML appear when a developer on their side handled the export. Any tool promising to accept any file is promising something it cannot check, and the useful question is which formats it reads and what it does with the ones it cannot.

The source of a file tells you more than its extension does. Payroll data comes out of Workday or ADP. Accounting data comes out of QuickBooks, Xero, or NetSuite. Product catalogs come out of Shopify, and contact lists come out of Outlook or Google Contacts. Each of those exports has its own habits: a title row sitting above the headers, a column of internal IDs nobody needs, a total row at the bottom that is not a record at all.

Reading what the file says

Reading a file sounds like the technical part, and it has the most solved problems in it. Parsers are mature and mostly free. The difficulty is that the file is often not the clean grid a parser expects. A spreadsheet saved in Germany separates its columns with semicolons, a file saved as Latin-1 turns accented names into nonsense when it is read as UTF-8, and rows arrive with more cells than the header row promised.

I wrote that whole catalog up separately in common CSV import errors, so I will leave it there. It is the smallest part of the job, and the rest of this guide is about what comes after it.

Matching their columns to your fields

Take one file and follow it through the rest of this guide: a staff export from the payroll system your customer is leaving, forty thousand employees, saved out of Excel that morning.

Your product has fields, the file has columns, and column matching is the step that decides which column feeds which field. It cannot be hardcoded, because the same field arrives under a different name from every customer. In the staff export the identifier is headed Staff No, in the next customer's file it is Employee ID or EmpID, and all three feed the same employeeId field, the way First Name, fname, and Contact First all mean firstName. Write a parser for one customer's header set and you have written the first of many.

The general solution is to match automatically where the names are close enough, then show the person what was matched and let them correct it. Fuzzy matching gets a good share of the columns on its own and the person handles the rest. That correction half carries the weight. A confident wrong guess is harder to spot than an empty dropdown, so automatic matching the person cannot override does more damage than no matching at all.

The values inside the columns

Getting the column right does not mean the values inside it are right, and in practice this is the stage that takes the longest. The staff export has an employment type column, and it matched your employment type field cleanly. Your field accepts Full time, Part time, and Contractor. The column contains FT, PT, Contract, Temp, Freelance, and a blank. The same gap opens everywhere else: a country field expecting a two letter code meets United States, USA, US, and America, and a status field expecting active or inactive meets Y, N, TRUE, FALSE, 1, and 0, sometimes in the same column.

None of this is broken data. It is one company's vocabulary meeting another company's vocabulary, and the translation between them is a decision a person has to make. Nothing in the file says whether Temp belongs in Part time or in Contractor, and only your customer can settle that.

What makes this stage hard to build is that the list of distinct values is unknown until the file is open. A schema can be written in advance, but a value map depends on what this particular customer typed into their spreadsheet over the last three years. So the work is to collect every distinct value in the column, show them beside the options your field accepts, let the person map them once, and apply that decision to every row that uses it.

It is also the stage where a mistake is hardest to see. A column mapped to the wrong field shows up in the preview. A value mapped to the wrong option looks correct.

Checking the rows against your rules

Validation is the layer that decides whether a row is allowed into your system. It confirms that required fields are present, that the email column holds email addresses, that numbers are numbers even when they are written with a comma for a decimal point, and that identifiers meant to be unique are unique inside the file, so two people sharing a Staff No get caught before either of them lands. Dates need their own care, because a start date written as 03/04 has to be resolved to a real day rather than a guess.

The checks that matter most are often the ones only your own system can answer: whether this employee is already in your system, whether the manager ID in a row points at someone who is also in the file, whether a product code in a different customer's file is one you actually stock. None of those can be answered by looking at the file alone, which means an importer that validates shape and nothing else will pass rows your database later rejects.

One limit is worth stating plainly: validation confirms that a value is well formed, not that it is true. A phone number with the right number of digits, belonging to the wrong person, passes every check there is.

Where the person fixes what is wrong

By now the staff export has been read, matched, translated, and checked, and nine hundred of its forty thousand rows have something wrong with them: a missing start date, a Temp nobody decided about, the two people sharing a Staff No. The loop I saw over and over before building Updog went like this: the person downloads an error report, opens the file in Excel, hunts for the rows, fixes them, saves, and uploads again, then finds the next batch. That is where onboarding time goes, and it is avoidable, because everything needed to fix the data is already on the screen in front of them.

Fixing in place takes more than an editable table. The person needs to filter down to the rows with problems, so nine hundred are not hiding inside forty thousand, and they need to fix a repeated mistake once instead of nine hundred times, the way a spreadsheet fills a column. Undo matters too, because a bulk change applied to the wrong selection is otherwise a reason to start over. The screen also has to stay responsive with the full file loaded, since a table that stutters at forty thousand rows sends the person back to Excel, which handles that size without complaint.

The import that happens again next month

Onboarding gets described as a one time event, and it rarely is. The corrected file arrives two days later, new hires arrive at the start of the next month, and the catalog gets refreshed for the season. The same person comes back to the same screen, and they expect it to remember what they decided last time, or at least not to make them decide all of it again.

There is a point where this stops being onboarding. If the file arrives on the same day every month, from a machine rather than a person, and nobody is meant to be watching, you are describing a feed rather than an import. That is server work and it wants a different product. Knowing which of the two you have is worth more than any feature comparison, because the tools are built for different jobs.

Who does this work today

Four approaches are in active use. The first is doing it by hand for the customer. This works, it is often the right first move, and it stops working at the point where onboarding becomes a full time job for a person who was hired to do something else.

The second is an engineer building an import screen. Every team has done this. A file input, a parser, and a table appear in an afternoon, and the long tail after that is the real project. I went through that math in build vs buy a CSV importer.

The third is embedding an importer built for the job. It becomes a component inside your app, the customer does the work themselves, and your team stays out of the loop.

The fourth is running a file pipeline on a server, which is the right answer for recurring feeds between machines and a poor one for a person with a spreadsheet on their first day.

Where Updog fits

Updog is the third of those four, a JavaScript SDK you put inside your own app. It covers the stages above in the order they appear here. It reads CSV, JSON, XML, XLSX, XLS, XLSB, and ODS, matches columns to your schema, matches values to the options your fields accept, and validates against your rules. Then it hands the person a spreadsheet editor where they fix what is wrong before anything is submitted.

What is unusual is where the work happens. There is no Updog server in the path, and no setting or plan tier that puts one there. The SDK is a library that runs in your page, so the file is read, matched, validated, and edited in the browser of the person importing it, and the only data that moves is the rows you accept, sent to your API. For a security review, that shifts the question from which certifications a vendor holds to whether there is a vendor in the path at all.

Two limits are worth being honest about. There is no row cap in the SDK, so what bounds a file is the memory of the browser it opens in. We tested a million rows across twenty columns and treat that as a practical limit, though a stronger machine handles more without trouble, and a file large enough to strain the machine in front of the person is better served by server side tooling. I wrote up how the grid holds a file that size in a canvas grid that renders a million rows in the browser. Updog also ships no AI model of its own. Column and value matching call an endpoint you host if you want AI in the loop, and fall back to fuzzy matching if you do not, so the data goes nowhere you do not already send it.

It is free on localhost and on preview domains, and $19 a month per production domain.

Whichever of the four you choose, the work underneath is the same. Your customer has their data in their shape and needs it in yours, and the sooner that translation is done, the sooner they spend their first week looking at their own numbers inside the product they just bought.