This question is a bit opinion based, but either way.
The way i see it, 200 can serve "soft errors". When it comes to building API's i try to distinguish between "soft errors"these and "hard errors".
"Soft errors" will be served with a status code of 200, but will contain an error description and a success status of false. "Soft errors" will only occur when the result is "as expected", but not a success byin the strictest sense.
It's important to note that "soft errors" are more of a hint to the implementer. Therefor it is important to also provide more information about the error such as a human-readable error message and/or some sort of code that can be used to provide the end-user with feedback. These errors provide the implementer (and end-user) with more information about what happened on the server side of things.
For instance, say you have an API with a search function, but during a search, no results are yielded. This is not erroneous, but it's not a success"success" either, not in the strictest sense of the definition.
Example formatted as JSON:
{
"meta" {
"success": false,
"message": "Search yielded no results",
"code": "NORESULTS"
}
"data": []
}
"Hard errors" on the other hand, will be served with a status code which is recommended for the error. User not logged in? – 403 / 401. Malformed input? – 400. Server error? – 50X. And so on.
Again, it's a bit opinion-based. Some people want to treat all errors equally, "hard error" everything. No search results? That's a 404! On the other side of the coin, no search results? – This is as expected, no error.
HoweverAnother important factor to take into consideration is your architecture, for instance; if you interact with your API using JavaScript XHR requests and jQuery or AngularJS. These "hard errors" will have to be handled with a separate callback, whereas the "soft errors" can be handled with the "success"-callback. Not breaking anything, the result is still "as expected".
So your architecture is something you should take into consideration when making these decisions The client-side code may then look at the success-status and code (or message). And print that to the end-user.