Bad-request vs Unprocessable-entity

Icons made by Freepik, Kiranshastry, and Smashicons from Flaticon.

TL;DR -> Checkout this repository to see how the bad-request and unprocessable-entity responses are managed at different levels of the core application.


One of the most important aspects of a great API is the way in which it responds to its clients. How it returns the expected results and how errors are reported with proper (and unique) codes and descriptions are a couple of topics to care about while you are developing an API.

During the development of a REST API, there are mainly two types of errors that our clients care about:

For example, let’s imaging we have an API with a single endpoint:

POST /process?

The rules to call this endpoint are:



The last couple of rules are meant to provide context about a business process. For the sake of this example, let’s say that there are two internal services that allow us to check those statements.

public interface IAccountRepository
Task<bool> IsAccountOpen(string accountId);
public interface IUserRepository
Task<bool> IsUserActive(string userId);

As you can imagine, there is a difference in terms of cost to check the format-rules (very fast and we don’t need any extra call) and the business-rules (Their cost is high since requiring extra operations inside our system).

How we do it

Compromising between speed and user-experience, we decided to:

Request and response provided by the example service using Postman.
Unprocessable entity response with error code and description when user status is inactive.


The implementation is quite straight-forward:

How to manage input format verification with ModelState class.
Business exception middleware.
Injection of the BusinessExceptionMiddleware.

After injecting your middleware, you can launch business exceptions that will be caught by your middleware. Example:

Launching exceptions when business rules are not verified.


We’ve seen our way to respond to our clients. We separate our responses into Bad-request and Unprocessable-entity. The first one provides all the errors the client did in an array as a response. The second one provides a single occurrence of the problem to avoid expensive flows and fast response.

And you? How do you do it? 😊

Happy coding!

Proud teacher-volunteer at Migracode and Cloud-engineer at Ohpen where I keep pushing my AWS+Serverless knowledge every day.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store