Quoting a website project: why the first number is almost never the right one

A couple of years back I quoted a real estate client forty hours of development. By the end of the project we’d billed seventy-two. It wasn’t because they kept asking for new things every week, though that happened too — it was because the original quote didn’t set aside a single hour for what I call “things we don’t know we don’t know.” In this case, their CRM had an undocumented API, and hooking up the contact form to it cost us nearly three weeks of back and forth with their vendor.
Since then I quote differently. Not better in the sense of “cheaper” or “faster”: different in structure. I used to put a number on each feature and add them up. Now I split things into three buckets: what I know how to build because I’ve built it fifteen times (login, blog, forms, a simple cart), what depends on a third party I don’t control (payment gateways, someone else’s CRM, APIs owned by the client’s own vendors), and what’s really design uncertainty — decisions the client hasn’t actually made yet, even if they think they have.
That second bucket has blown more quotes for me than anything else. When someone says “we just need to connect it to our ERP,” I already know from experience that sentence is hiding anywhere between zero and forty hours of work, and I won’t know which until I see the documentation, if it even exists. Now I quote that part separately, as a range, and I put it in writing that the final number depends on what we find once we’re in there. Some clients get uneasy with that ambiguity. I’d rather they get uneasy at the proposal stage than at the final invoice.
There’s one more thing I changed: I stopped quoting loose hours per task and started quoting in weeks of actual dedication. It doesn’t matter that a task “should” take six hours if in practice a developer also has meetings, other projects running in parallel, and the client takes four days to answer a one-line email. A project that’s “six weeks of work” ends up taking ten or twelve calendar weeks in practice, and if the quote doesn’t account for that, the client gets blindsided halfway through — which is the worst possible time to break that news.
What I still haven’t solved, and I doubt it ever gets fully solved, is the fixed quote with an open scope. A client wants a final number before signing, and at the same time doesn’t yet know exactly what they want. I can tweak the process, break it into phases, charge for a week of discovery before giving a firm figure — but at some point someone has to decide with incomplete information, and that someone is almost always me. The last time I skipped the discovery phase, on a mid-sized online store project, I ended up eating eight hours out of my own margin just to avoid the awkward conversation about raising the price midway through. I don’t know if that was the right call. I do know that next time the discovery phase is going in the contract, whether we end up using it or not.