I Shipped an Undefined Interface Between Two Teams
The AI worked perfectly. It died the moment it left my team. Here’s the part nobody warns you about.
The thing worked. That was the problem.
My team built an AI workflow that took a messy, manual, soul-deadening process and ran it end to end. Inside our walls it was clean. Fast. The kind of thing you demo and people lean forward. We’d taken something that ate hours and turned it into something that produced a finished output in minutes, every time, without the human boredom errors that used to creep in around hour three.
And then the output had to go to another team. Because the next step in the process wasn’t ours. It was theirs. It always had been.
That’s where it died.
Not because our output was wrong — it was good. It died because the other team didn’t trust it, couldn’t validate it the way they validated their own work, had no idea what to do when it looked slightly off, and — this is the part that stung — experienced the whole thing as a pile of work landing on their desk at a speed they never agreed to. We’d built a beautiful engine and bolted it directly to a team that hadn’t asked for it, on terms we’d never discussed, in a format we’d decided was obviously correct.
My first reaction was the wrong one, and I’ll own it: I decided they were the bottleneck. They were slow. They didn’t get it. Build it, trust me — that’s been my instinct my whole career, and inside my own team it’s a superpower. So my read was that the technology was done and the people were the friction.
It took me longer than I’d like to admit to see what I’d actually done.
I’d shipped an undefined interface. I’d just done it between two teams instead of two services.
Say that to any engineer and watch their face. We know this. An undefined interface between two systems is where everything breaks — no agreed schema, no contract for what “done” looks like, no error handling, nobody owning what happens when the payload is malformed, no backpressure when one side floods the other. We would never ship that between two microservices and call it finished. We’d get torn apart in review.
I shipped exactly that between my team and theirs, and then I blamed the other service for failing the integration.
The resistance I was annoyed by wasn’t politics. It was the integration test failing, loudly, the way it’s supposed to. The other team was returning errors because I’d handed them a contract that didn’t exist. Their pushback was signal. I was treating it as noise.
Inside a team, implicit interfaces are fine. Across teams, they’re technical debt with a pulse.
Here’s why this catches good leaders off guard. Inside your own team, interfaces are implicit and that works — shared context, shared language, you can lean over and say “you know what I mean.” The handoffs are invisible because the bandwidth between people who sit together is enormous.
The instant you cross a team boundary, that bandwidth collapses. The shared context is gone. The assumptions you never had to state are now load-bearing and unspoken. Every implicit interface you got away with internally becomes a place where two groups quietly believe different things about whose job it is — and you don’t find out until the payload is already on fire.
AI makes this worse, fast, for a specific reason: it collapses the cost of building. When standing up a cross-team workflow took two quarters and a budget fight, you crossed those boundaries rarely, and the crossing got negotiated on the way. Now my five-person team can build something that reaches into another department’s domain in two weeks. We’re not crossing boundaries more recklessly than before. We’re crossing them faster than the organization’s process for renegotiating them was ever built to handle. We’re running new code against a stale map of who owns what.
Every interface that holds has four things. Ours had none of them.
Once I stopped treating it as a people problem and started treating it as an interface design problem, the fix got concrete. A handoff that works has the same things a good API has:
A contract. An agreed definition of what the output is and what “done” looks like — not what I think done looks like, what we agree it looks like. The schema, the fields, the format, the thing they can point to and say “yes, that’s what we accept.”
Error ownership. When the output is wrong — and sometimes it will be — whose problem is it, and how do they flag it back without filing a ticket into a void? Undefined error handling is where trust dies. The other team’s real fear wasn’t the good outputs. It was the bad ones, and not knowing who’d answer for them.
Backpressure. Their ability to say “not at this rate.” A consumer that can’t push back against a producer gets flooded, and a flooded team doesn’t experience your automation as a gift. They experience it as a denial-of-service attack with a friendly name.
Versioning and trust. A way for them to know what changed when we changed it, so the thing they validated last month is still the thing they’re getting today. Silent changes upstream are how you burn trust you’ll never fully earn back.
We’d defined exactly zero of these. I’d designed the engine with enormous care and the seam with none, which is precisely backwards, because the seam was the only part that touched anyone but us.
The tempo asymmetry is the load the interface has to carry
There’s one more thing, and it’s the one that quietly poisons everything if you don’t name it. My team iterates weekly. We ship, we learn, we adjust. The team we were handing off to plans in quarters and lives in a queue. That’s not a flaw in them — it’s the correct cadence for what they do.
But it means every handoff we sent arrived as a fire drill they hadn’t staffed for. We weren’t just stepping into their domain. We were doing it at a tempo they structurally couldn’t match, which turns even a willing partner defensive. The interface has to absorb that mismatch — through backpressure, through batching, through an agreed rhythm — or the speed itself becomes the thing they resist, no matter how good the output is.
The real reason the interface was undefined
Here’s the uncomfortable bottom of it. The interface wasn’t undefined by accident. It was undefined because defining it means saying out loud that the boundary moved — that a piece of work which used to live entirely in their lane now starts in mine. And nobody wants to be the one who signs that.
That’s the territory problem underneath the technical one, and you can’t refactor your way around it. The resistance isn’t pettiness. Territory is how people know their job still exists. When you automate the seam between two teams, the other side doesn’t feel efficiency — they feel the ground that justified their role shifting under them. That reaction is rational. It’s accurate. It’s information about a real thing you changed.
So the move that actually worked wasn’t a better output format. It was making them a co-owner of the capability instead of a consumer of my product. They own the validation. They own the definition of “done” in their domain. The thing stopped being “IT’s tool that dumps work on us” and became “our process, with an engine we trust because we have our hands on the controls.” The minute they owned a real part of it, the interface defined itself — because now both sides had a reason to write the contract.
What I tell my team now
Build it, trust me is the right instinct inside our four walls and the exact wrong reflex the moment our work touches another team. Inside, speed and conviction are everything. At the boundary, the job flips: slow down precisely where the bandwidth drops, design the seam with more care than the engine, and treat the other team’s resistance as the most honest code review you’ll get all quarter.
The hard part of this work was never the model. The model was the easy part. The hard part is that AI lets a small team build things that cross lines the org chart drew back when crossing them was expensive — and the org chart hasn’t caught up, and the people living inside it have every reason to defend the lines.
You can be right about the technology and still be the problem at the seam. I was. The fix wasn’t a better engine. It was finally designing the interface I’d pretended wasn’t there.
If you’ve shipped one of these — the thing that worked great right up until it had to leave your team — I want to hear where it broke for you. The seam is where most of us are quietly losing the value of this whole AI moment, and almost nobody’s writing about it.


