If you do this consistently, then you have much of the side effecting code residing next to each other per process/input handler etc.
It's not always feasible or the right thing. But it's a good default way of structuring code and makes testing much more straight forward. And it makes more clear "at a glance" what happens because you can reason more locally about the side effecting parts.
> It also means you are less depedent on the concrete implementation of the API and don't leak types and behaviour from systems you don't control into your codebase
You are always dependent on that. Whether you hide it down the stack or lift it up, you still need to put your data into a specific shape, do the same essential checks etc.
I've never seen Go code that does anything else. That's not to say it doesn't exist, but it's seemingly not the norm amongst Go developers (probably exactly for the reasons you describe). That doesn't address what the parent is talking about, though. You have the exact same problem spoken of no matter where in the stack you put it.
But like with everything in life, there is no right solution. Just different tradeoffs. If interfaces best align with the trades you are willing to make, go for it.
If the software's logic is too complex and fiddly to lend itself to straightforward end-to-end testing (i.e. enterprise software), I just wouldn't write it in Go. I'd choose a higher level language like Python or Java where mocking (and other kinds of dynamism) are straightforward and require no boilerplate.