The Article Initially was published on https://www.linkedin.com/pulse/demystifying-status-codes-api-response-clear-guide-custom-jahid-hasan-d68hc/
Introduction
The last few months, I have been working on a client-side project with React and React Native technology. While I was integrating APIs, I encountered some confusion regarding HTTP status codes. Let me explain one scenario below.
Problem
Let's say a user has signed up for an account to our system but our system will not allow him/her to login until he/she verify his email with an OTP code. When the user tries to log in under these circumstances, we should redirect them to the OTP input page to verify their email address first. In this scenario, I found the backend was sending a status code 404 (Not Found), which conveys a completely different meaning.
When I asked about this then more confusion arose regarding which status code to use. If we send a 401, it means 'Unauthorized,' and we are using it for access token invalidation. If we send a 403, it means 'Forbidden,' and we are using it for a different scenario. So what should we can return in this case?
Custom Status Code
Hence Custom Status Code comes to save us,
We are usually send error response like this, (Let's focus on the custom status codes we can control within our API responses, rather than the default HTTP status codes)
{
"error": {
"code": 401,
.........
.........
},
"metadata": {
"version": "1.0",
"timestamp": "2024-05-22T12:34:56Z"
}
} If we notice the above error.code, it's 401. which one we mostly use to send when a token is expired/invalid.
We can send our custom code as error.code: 40100 here to indicate specific issues, such as unauthorized access due to an invalid or expired token.
{
"error": {
"code": 40100,
......
......
},
"metadata": {
"version": "1.0",
"timestamp": "2024-05-22T12:34:56Z"
}
}
And we can send our custom code as error.code: 40101 to indicate specific issues, such as unauthorized access due to an unverified email ID.
// A sample error response of Level 3 API
{
"error": {
"code": 40101,
"message": "Email verification required before login.",
"trace_id": "abcd1234-ef56-7890-gh12-ijkl3456mnop",
"hints": [
"Ensure the user has received the OTP email.",
"Use the verify email link to send or resend the OTP."
],
"links": {
"self": {
"href": "https://api.example.com/users/12345"
},
"verify_email": {
"href": "https://api.example.com/users/12345/verify-email",
"method": "POST",
"description": "Send verification email"
},
"resend_otp": {
"href": "https://api.example.com/users/12345/resend-otp",
"method": "POST",
"description": "Resend OTP code"
}
}
},
"metadata": {
"version": "1.0",
"timestamp": "2024-05-22T12:34:56Z"
}
} We can use custom codes in other scenarios too, such as providing a clear concept of 404 Not Found:
40400: User not found
40401: ABC product not found
40402: Resource not found
etc.
We can use custom codes as providing a clear concept of 201: Created,
20100: User created.
20101: ABC product created.
20102: Resource created.
etc.
{
"code": 20100,
"message": "User created successfully.",
"info": "Please verify your email to complete the registration process.",
"data": {
"user_id": "12345",
"username": "johndoe",
"email": "johndoe@example.com",
"status": "pending_verification"
},
"links": {
"self": {
"href": "https://api.example.com/users/12345"
},
"verify_email": {
"href": "https://api.example.com/users/12345/verify-email",
"method": "POST",
"description": "Send verification email"
}
},
"metadata": {
"version": "1.0",
"timestamp": "2024-05-22T12:34:56Z"
}
} This approach helps us in identifying the specific issue correclty and it is making easier for the client-side developer to handle different cases more effectively.
Conclusion
Understanding and utilizing the HTTP status codes is really needed for effective API communication. HTTP status codes like 401, 403, 404, 422 etc. serve different purpose and they should be used to convey the state of a request accurately. However in a certain scenarios the custom status codes can provide more precise information. And it can enhance the clarity and usability of API responses.
Custom codes like ```40101``` for an unverified email or ```20100``` for user created successfully help the client-side developers to handle specific conditions with more effectively. These codes must be well documented and implemented to ensure they add value to the API's design.
