I spent the first half of my career wiring systems together after the fact. The ERP was chosen, the CRM was live, the warehouse tool was already spewing CSVs, and then someone would ask me to make them all talk. So I'd build connectors, write mapping scripts, and pray. It worked often enough that I didn't question the approach. But every project had this hidden tax: brittle integrations that broke whenever a vendor updated a field or a business rule shifted.
Then a manufacturing client asked us to connect six systems in six months, including a legacy MES that had no real API. We started exactly like I always did, by inventorying what existed and stitching from the outside in. Three weeks in, the lead developer pulled me aside and said something I still think about. "We're not integrating systems. We're integrating their current data shapes." He was right. Every endpoint we discovered was an accident of history, not a deliberate contract.
That was the pivot. We stopped trying to reverse engineer existing endpoints and instead defined the APIs we wished existed. We wrote an OpenAPI spec for a canonical order object, a canonical inventory event, and a canonical shipment update. Then we built small adapters that translated each vendor's weirdness into that spec. The MES didn't have an API, so we wrapped its database views behind a thin REST layer. It felt like overkill for the first sprint, but by the third month we were shipping features while other teams were still arguing about field names.
I made a real mistake during that project, though. I assumed the canonical spec was set in stone once we published it. The business decided to support drop shipments, which meant an order could have multiple fulfillment locations. Our order object had a single warehouse field. The adapter teams were furious because they'd built against version one. We ended up versioning the API and migrating two adapters in a weekend. The lesson stuck: API-first doesn't mean API-final. You have to treat your internal contracts like external products, with deprecation windows and migration paths.
Now when I walk into an enterprise integration project, I ask a different first question. Instead of "what systems do we have?" I ask "what business capabilities do we need to expose?" That shift changes everything. You stop negotiating with legacy schema and start designing for the workflows that actually drive revenue. The adapters become a known, contained cost instead of an endless integration tax. And the weird part is, the vendors eventually catch up. Three years later, that MES vendor shipped a real API, and our adapter got deleted in an afternoon because the canonical layer had already done the hard work.
I wish I'd learned this ten years ago. I'd have fewer gray hairs and a lot fewer midnight calls about a field breaking in production.