Different layers: the call to the api was successful on the transport Layer, thus 200. You messed up something in the business logic or you asked for a resource that's not there. While often you will get a 404, this is wrong: the http call is successful. The endpoint did not vanish. You just asked for something the business end could not deliver. The Protocol is fine with your call.
> While often you will get a 404, this is wrong: the http call is successful. The endpoint did not vanish
According to RFC 7231, status code 404 means that the specified resource wasn't found. Not that the endpoint wasn't fount.
"The 404 (Not Found) status code indicates that the origin server did not find a current representation for the target resource or is not willing to disclose that one exists. A 404 status code does not indicate whether this lack of representation is temporary or permanent; the 410 (Gone) status code is preferred over 404 if the origin server knows, presumably through some configurable means, that the condition is likely to be permanent."
The problem is you can't differentiate between "resource not found" and "we never even got a chance to process the request for a resource" purely by status code. Maybe your upstream reverse proxy got mis-configured. Maybe DNS is broken.
But 404 is not the representation for not existing but for not found: if you return 404 you leave the user of the api wondering if he mistyped something, or the DNS broke, or some part of the routing went down.
> There's no HTTP result code for "your request was successful but your Smart Washing Machine is out of detergent", for example.
That comes down to your definition of success. Yeah, the client successfully connected and the server read the request, but it was unable to process said request.
To my mind, that's a 500, as in the server was not able to handle the request due to a circumstances beyond the clients control.
When used in an API, HTTP acts mostly as a transport layer. There's no HTTP result code for "your request was successful but your Smart Washing Machine is out of detergent", for example.
@number6 is right. There are all kinds of problems when you use HTTP status codes to represent something that was correct for HTTP but failed business logic. You don't want a tonne of errors logged because someone has violated business logic but otherwise called the API correctly otherwise good luck finding actual errors where you screwed up by deleting an endpoint (actual 404) or where you changed the request model (400) etc.
I'm sure people might disagree with that approach but it is very common and very reasonable.