The obvious decision was to integrate with an existing payroll provider. Gusto has an API. ADP has partnerships. There’s a whole ecosystem of payroll vendors that will handle the withholding math, file the tax forms, and send the direct deposits — for a per-employee monthly fee that goes up as you grow.
We almost did it that way.
The problem isn’t the payroll providers themselves. They’re fine at payroll. The problem is that payroll is connected to everything else in a business: your employees, your contractors, your benefits, your accounting, your cost centers, your approval workflows. When payroll lives in a separate system, all of those connections become integrations. And integrations are where data goes to quietly become wrong.
I spent years as an accountant watching companies reconcile payroll exports against their accounting software at month end. It was always a mess. Not because of errors in the payroll itself — usually the numbers were right. But because the categories, the cost centers, the account codes — they never matched between systems. Someone had to translate, manually, every time. That translation introduced errors. Those errors compounded.
When we were designing Administry, I kept coming back to this problem. If payroll is a third-party integration, we’re just recreating the same mess in a nicer interface. The journal entries would still have to be mapped manually. The employee data would still be in two places. The benefits deductions would still require reconciliation.
So we built it ourselves.
What that actually meant
Building payroll means understanding the tax math well enough to implement it. Federal withholding tables change annually. State taxes vary by state and have their own quirks — flat rates, brackets, supplemental wage rules, family leave contributions. We built for 21 states initially and added more based on where customers are actually located.
It also means the payroll data lives in the same system as everything else. When a payroll run completes, the journal entries are created automatically using the same account codes the rest of the platform uses. There’s nothing to reconcile. The numbers match because they came from the same place.
The tradeoff
Building payroll in-house is slower to ship than writing an integration. It took longer to get right. There are edge cases we’re still handling — multi-state employees, mid-year changes, retroactive corrections — that a mature payroll API would have solved out of the box.
But the alternative was a platform where the most operationally critical function was also the most disconnected one. For a product that exists specifically to eliminate disconnected operations, that felt like a core contradiction.
Some things you have to own to do right.