When you wrap an external API in Elixir, most of what a function like Acme.fetch_user/1 does is response handling: validate the status, parse the body, translate failures. That code almost always lives after the Tesla.get call, in a case or a handle_response/1 at the end of a |> pipeline. That's the wrong place. A middleware can return {:error, ...} from Tesla.run , which makes Tesla's telemetry event record the request as failed. A function called after Tesla.get can't do that. It only sees the result. Failures it detects don't reach telemetry, so your observability stack undercounts them. Code samples use Tesla. Same shapes apply to Req. Pick whichever you're using and translate as you go. Real APIs don't read their own docs Real APIs are dirtier than tutorial examples. A few I've run into: I've seen well-known, large providers respond with bodies that fail to parse. Yup, broken JSON A field documented as a boolean returns the JSON string "true" for true and, the JSON string "No" for false.…