[{"data":1,"prerenderedAt":760},["ShallowReactive",2],{"post-\u002Frest-api-error-handling":3},{"page":4,"translation":645,"nav":647,"related":748,"random":753},{"id":5,"title":6,"body":7,"categories":627,"category":629,"date":630,"description":631,"draft":632,"extension":633,"image":634,"kind":629,"lang":635,"meta":636,"navigation":637,"path":599,"readingTime":111,"seo":638,"slug":639,"stem":639,"tags":640,"translationKey":639,"type":628,"updated":629,"__hash__":644},"posts\u002Frest-api-error-handling.md","How to Perform REST API Error Handling?",{"type":8,"value":9,"toc":621},"minimark",[10,19,48,51,54,57,60,139,142,168,171,177,245,250,422,424,429,432,526,528,532,535,538,540,544,547,550,556,558,563,571,573,577,617],[11,12,13,14,18],"p",{},"This article is part of the ",[15,16,17],"strong",{},"RESTful API Design"," series. If you haven't read the previous articles in the series, I highly recommend starting there:",[20,21,22,30,36,42],"ul",{},[23,24,25],"li",{},[26,27,29],"a",{"href":28},"\u002Frest-api-design","REST Api Design: Principles and Output Format",[23,31,32],{},[26,33,35],{"href":34},"\u002Frest-api-uri-structure","What Should the REST API URI Structure Be?",[23,37,38],{},[26,39,41],{"href":40},"\u002Fwhat-is-hateoas","What is HATEOAS in REST API?",[23,43,44],{},[26,45,47],{"href":46},"\u002Frest-api-authentication","How to Perform REST API Authentication?",[49,50],"hr",{},[11,52,53],{},"What's worse than encountering an error? Encountering an obscure, cryptic error that leaves you completely in the dark. If you want to keep developers who consume your API from tearing their hair out, you must clearly explain errors and their root causes. When doing so, always leverage standard HTTP status codes. Standard HTTP status codes are expressive enough to cover the general category of almost any error. If you pair them with a well-structured error body, your API consumers will thank you.",[11,55,56],{},"You should return the HTTP status code in the response headers. To make the consumer's job even easier, it's also helpful to include the status code inside the JSON payload.",[11,58,59],{},"Here is an example structure of a JSON error response:",[61,62,67],"pre",{"className":63,"code":64,"language":65,"meta":66,"style":66},"language-json shiki shiki-themes github-light github-dark","{\n \"status\": 429,\n \"message\": \"Too many requests\",\n \"code\": 10200,\n \"info\": \"http:\u002F\u002Fwww.evrenbal.com\u002Fapi\u002Fv1\u002Ferrors\u002F10200\"\n}\n","json","",[68,69,70,79,95,109,122,133],"code",{"__ignoreMap":66},[71,72,75],"span",{"class":73,"line":74},"line",1,[71,76,78],{"class":77},"sVt8B","{\n",[71,80,82,86,89,92],{"class":73,"line":81},2,[71,83,85],{"class":84},"sj4cs"," \"status\"",[71,87,88],{"class":77},": ",[71,90,91],{"class":84},"429",[71,93,94],{"class":77},",\n",[71,96,98,101,103,107],{"class":73,"line":97},3,[71,99,100],{"class":84}," \"message\"",[71,102,88],{"class":77},[71,104,106],{"class":105},"sZZnC","\"Too many requests\"",[71,108,94],{"class":77},[71,110,112,115,117,120],{"class":73,"line":111},4,[71,113,114],{"class":84}," \"code\"",[71,116,88],{"class":77},[71,118,119],{"class":84},"10200",[71,121,94],{"class":77},[71,123,125,128,130],{"class":73,"line":124},5,[71,126,127],{"class":84}," \"info\"",[71,129,88],{"class":77},[71,131,132],{"class":105},"\"http:\u002F\u002Fwww.evrenbal.com\u002Fapi\u002Fv1\u002Ferrors\u002F10200\"\n",[71,134,136],{"class":73,"line":135},6,[71,137,138],{"class":77},"}\n",[11,140,141],{},"In this response:",[20,143,144,150,156,162],{},[23,145,146,149],{},[68,147,148],{},"\"status\""," represents the standard HTTP status code.",[23,151,152,155],{},[68,153,154],{},"\"message\""," is a human-readable explanation of the error.",[23,157,158,161],{},[68,159,160],{},"\"code\""," is an internal, application-specific error code.",[23,163,164,167],{},[68,165,166],{},"\"info\""," provides a link to documentation or help resources associated with that error code.",[11,169,170],{},"This structure is flexible and can be adapted to suit your project's needs. For example:",[11,172,173],{},[174,175,176],"em",{},"Server-side error:",[61,178,180],{"className":63,"code":179,"language":65,"meta":66,"style":66},"{\n \"status\": 500,\n \"message\": \"An internal server error occurred\",\n \"description\": \"Detailed error log description...\",\n \"code\": 10201,\n \"info\": \"http:\u002F\u002Fwww.evrenbal.com\u002Fapi\u002Fv1\u002Ferrors\u002F10201\"\n}\n",[68,181,182,186,197,208,220,231,240],{"__ignoreMap":66},[71,183,184],{"class":73,"line":74},[71,185,78],{"class":77},[71,187,188,190,192,195],{"class":73,"line":81},[71,189,85],{"class":84},[71,191,88],{"class":77},[71,193,194],{"class":84},"500",[71,196,94],{"class":77},[71,198,199,201,203,206],{"class":73,"line":97},[71,200,100],{"class":84},[71,202,88],{"class":77},[71,204,205],{"class":105},"\"An internal server error occurred\"",[71,207,94],{"class":77},[71,209,210,213,215,218],{"class":73,"line":111},[71,211,212],{"class":84}," \"description\"",[71,214,88],{"class":77},[71,216,217],{"class":105},"\"Detailed error log description...\"",[71,219,94],{"class":77},[71,221,222,224,226,229],{"class":73,"line":124},[71,223,114],{"class":84},[71,225,88],{"class":77},[71,227,228],{"class":84},"10201",[71,230,94],{"class":77},[71,232,233,235,237],{"class":73,"line":135},[71,234,127],{"class":84},[71,236,88],{"class":77},[71,238,239],{"class":105},"\"http:\u002F\u002Fwww.evrenbal.com\u002Fapi\u002Fv1\u002Ferrors\u002F10201\"\n",[71,241,243],{"class":73,"line":242},7,[71,244,138],{"class":77},[11,246,247],{},[174,248,249],{},"Validation error with multiple fields:",[61,251,253],{"className":63,"code":252,"language":65,"meta":66,"style":66},"{\n \"status\": 422,\n \"message\": \"Unprocessable Entity\",\n \"errors\": [\n   { \n     \"code\": 20501,\n     \"field\" : \"username\",\n     \"message\": \"Username must be at least 5 characters long.\",\n     \"info\": \"http:\u002F\u002Fwww.evrenbal.com\u002Fapi\u002Fv1\u002Ferrors\u002F20501\"\n   },\n   {\n    \"code\": 20601,\n    \"field\": \"password\",\n    \"message\": \"Password must be at least 8 characters long.\",\n    \"info\": \"http:\u002F\u002Fwww.evrenbal.com\u002Fapi\u002Fv1\u002Ferrors\u002F20601\"\n   }\n ] \n}\n",[68,254,255,259,270,281,289,294,306,319,332,343,349,355,368,381,394,405,411,417],{"__ignoreMap":66},[71,256,257],{"class":73,"line":74},[71,258,78],{"class":77},[71,260,261,263,265,268],{"class":73,"line":81},[71,262,85],{"class":84},[71,264,88],{"class":77},[71,266,267],{"class":84},"422",[71,269,94],{"class":77},[71,271,272,274,276,279],{"class":73,"line":97},[71,273,100],{"class":84},[71,275,88],{"class":77},[71,277,278],{"class":105},"\"Unprocessable Entity\"",[71,280,94],{"class":77},[71,282,283,286],{"class":73,"line":111},[71,284,285],{"class":84}," \"errors\"",[71,287,288],{"class":77},": [\n",[71,290,291],{"class":73,"line":124},[71,292,293],{"class":77},"   { \n",[71,295,296,299,301,304],{"class":73,"line":135},[71,297,298],{"class":84},"     \"code\"",[71,300,88],{"class":77},[71,302,303],{"class":84},"20501",[71,305,94],{"class":77},[71,307,308,311,314,317],{"class":73,"line":242},[71,309,310],{"class":84},"     \"field\"",[71,312,313],{"class":77}," : ",[71,315,316],{"class":105},"\"username\"",[71,318,94],{"class":77},[71,320,322,325,327,330],{"class":73,"line":321},8,[71,323,324],{"class":84},"     \"message\"",[71,326,88],{"class":77},[71,328,329],{"class":105},"\"Username must be at least 5 characters long.\"",[71,331,94],{"class":77},[71,333,335,338,340],{"class":73,"line":334},9,[71,336,337],{"class":84},"     \"info\"",[71,339,88],{"class":77},[71,341,342],{"class":105},"\"http:\u002F\u002Fwww.evrenbal.com\u002Fapi\u002Fv1\u002Ferrors\u002F20501\"\n",[71,344,346],{"class":73,"line":345},10,[71,347,348],{"class":77},"   },\n",[71,350,352],{"class":73,"line":351},11,[71,353,354],{"class":77},"   {\n",[71,356,358,361,363,366],{"class":73,"line":357},12,[71,359,360],{"class":84},"    \"code\"",[71,362,88],{"class":77},[71,364,365],{"class":84},"20601",[71,367,94],{"class":77},[71,369,371,374,376,379],{"class":73,"line":370},13,[71,372,373],{"class":84},"    \"field\"",[71,375,88],{"class":77},[71,377,378],{"class":105},"\"password\"",[71,380,94],{"class":77},[71,382,384,387,389,392],{"class":73,"line":383},14,[71,385,386],{"class":84},"    \"message\"",[71,388,88],{"class":77},[71,390,391],{"class":105},"\"Password must be at least 8 characters long.\"",[71,393,94],{"class":77},[71,395,397,400,402],{"class":73,"line":396},15,[71,398,399],{"class":84},"    \"info\"",[71,401,88],{"class":77},[71,403,404],{"class":105},"\"http:\u002F\u002Fwww.evrenbal.com\u002Fapi\u002Fv1\u002Ferrors\u002F20601\"\n",[71,406,408],{"class":73,"line":407},16,[71,409,410],{"class":77},"   }\n",[71,412,414],{"class":73,"line":413},17,[71,415,416],{"class":77}," ] \n",[71,418,420],{"class":73,"line":419},18,[71,421,138],{"class":77},[49,423],{},[425,426,428],"h2",{"id":427},"http-status-codes","HTTP Status Codes",[11,430,431],{},"Here are the most common HTTP status codes you'll need when designing a REST API:",[20,433,434,442,450,458,466,474,486,494,502,510,518],{},[23,435,436,441],{},[15,437,438],{},[68,439,440],{},"200 OK"," - Returned after a successful GET, PUT, PATCH, or DELETE request.",[23,443,444,449],{},[15,445,446],{},[68,447,448],{},"201 Created"," - Returned after a successful POST request that creates a new resource.",[23,451,452,457],{},[15,453,454],{},[68,455,456],{},"204 No Content"," - Returned after a successful request that doesn't need to return a payload (common for DELETE requests).",[23,459,460,465],{},[15,461,462],{},[68,463,464],{},"400 Bad Request"," - Returned when the request is malformed or missing required parameters.",[23,467,468,473],{},[15,469,470],{},[68,471,472],{},"401 Unauthorized"," - Returned when the request lacks credentials or contains invalid authentication tokens.",[23,475,476,481,482,485],{},[15,477,478],{},[68,479,480],{},"403 Forbidden"," - Often confused with ",[68,483,484],{},"401",". This is used when the server understands who the user is, but the user does not have permission to access the requested resource.",[23,487,488,493],{},[15,489,490],{},[68,491,492],{},"404 Not Found"," - The classic error code returned when the requested resource does not exist on the server.",[23,495,496,501],{},[15,497,498],{},[68,499,500],{},"405 Method Not Allowed"," - Returned when the HTTP verb (method) used is not supported for the endpoint.",[23,503,504,509],{},[15,505,506],{},[68,507,508],{},"422 Unprocessable Entity"," - Typically used for validation errors (e.g., when inputs fail validation constraints).",[23,511,512,517],{},[15,513,514],{},[68,515,516],{},"429 Too Many Requests"," - Returned when the client has exceeded rate limits.",[23,519,520,525],{},[15,521,522],{},[68,523,524],{},"500 Internal Server Error"," - Usually represents an unhandled exception or server-side failure. Keeping a generic handler for this helps log details properly and present a clean error to the client.",[49,527],{},[425,529,531],{"id":530},"logging","Logging",[11,533,534],{},"An important aspect of error management is logging. Logging is not just for error tracking; depending on your system, it's also useful for transaction tracking. At a minimum, logging all error instances on the server makes debugging immensely easier. As developers, no matter how much we test, once our API is released into the wild, users will find creative ways to break it. Often, they won't even report the issue. Even if they do, duplicating the exact scenario is hard without detailed logs.",[11,536,537],{},"Logging is a broad topic in its own right. I plan to write an article about using Monolog in PHP, where I will discuss logging practices in more detail.",[49,539],{},[425,541,543],{"id":542},"my-most-common-mistake-unhandled-errors","My Most Common Mistake: Unhandled Errors",[11,545,546],{},"Personally, my most frequent oversight is designing perfect error responses on the backend but neglecting to handle them properly on the client side. When a client application doesn't respond as expected, I look at the API output and see a beautifully formatted error code—but if the client doesn't do anything with it, it's useless. Remember, error management is a two-way street; it must be implemented on both the client and the server.",[11,548,549],{},"See you in the next part: \"Security\".",[11,551,552],{},[26,553,555],{"href":554},"\u002Frest-api-security","How to Secure a REST API?",[49,557],{},[559,560,562],"h5",{"id":561},"changelog","Changelog",[20,564,565,568],{},[23,566,567],{},"2026-06-20: Modernized article structure and updated language bindings.",[23,569,570],{},"2021-02-15: Original Turkish article published.",[49,572],{},[425,574,576],{"id":575},"rest-api-series","REST API Series",[20,578,579,583,587,591,595,601,605,611],{},[23,580,581],{},[26,582,29],{"href":28},[23,584,585],{},[26,586,35],{"href":34},[23,588,589],{},[26,590,41],{"href":40},[23,592,593],{},[26,594,47],{"href":46},[23,596,597],{},[26,598,600],{"href":599},"\u002Frest-api-error-handling","How to Perform REST API Error Handling? (This article)",[23,602,603],{},[26,604,555],{"href":554},[23,606,607],{},[26,608,610],{"href":609},"\u002Frest-api-documentation-and-testing","How to Document and Test a REST API?",[23,612,613],{},[26,614,616],{"href":615},"\u002Ffull-stack-project-development","Sample REST API Project",[618,619,620],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":66,"searchDepth":81,"depth":81,"links":622},[623,624,625,626],{"id":427,"depth":81,"text":428},{"id":530,"depth":81,"text":531},{"id":542,"depth":81,"text":543},{"id":575,"depth":81,"text":576},[628],"technical",null,"2026-06-20","Designing consistent REST API error handling — the right HTTP status codes, useful logging, and never leaving errors unhandled.",false,"md","\u002Fimages\u002Fhero\u002Frest-api-error-handling.avif","en",{},true,{"title":6,"description":631},"rest-api-error-handling",[641,642,643],"api","error-handling","rest","I7wrfVI2uYfqwf8OYMMos5ae7Tlaq8aeSimm8qlNZg8",{"path":646},"\u002Ftr\u002Frest-api-hata-yonetimi",{"prev":648,"next":649,"others":650,"lucky":747,"readingTime":111},{"path":609,"title":610},{"path":554,"title":555},[651,652,653,655,656,657,658,661,664,667,670,673,676,679,682,685,688,691,694,697,700,703,706,709,712,715,718,721,724,727,730,733,736,739,741,744],{"path":615,"title":616},{"path":46,"title":47},{"path":28,"title":654},"REST API Design: Principles and Output Format",{"path":609,"title":610},{"path":554,"title":555},{"path":34,"title":35},{"path":659,"title":660},"\u002Ftroubleshooting-cyberpanel-inaccessibility-after-ubuntu-release-upgrade","Troubleshooting CyberPanel Inaccessibility After Ubuntu Release Upgrade",{"path":662,"title":663},"\u002Freset-wordpress-admin-password-using-wp-cli","Reset WordPress Admin Password Using WP-CLI",{"path":665,"title":666},"\u002Fgraphql-vs-rest-api-which-is-the-best-choice-for-headless-wordpress","GraphQL vs REST API: Which is the Best Choice for Headless WordPress?",{"path":668,"title":669},"\u002Fgrow-your-business-in-turkey-with-expert-wordpress-plugin-and-theme-localization-and-support-services","Grow Your Business in Turkey with Expert WordPress Plugin and Theme Localization and Support Services",{"path":671,"title":672},"\u002Fgetting-started-with-devops-understanding-the-principles-and-adopting-the-tools","Getting Started with DevOps: Understanding the Principles and Adopting the Tools",{"path":674,"title":675},"\u002Fphp-graphql-development-advanced-techniques-for-optimizing-your-apis","PHP GraphQL Development: Advanced Techniques for Optimizing Your APIs",{"path":677,"title":678},"\u002Fadvanced-techniques-for-dependency-injection-in-php-tips-code-samples-and-faqs","Advanced Techniques for Dependency Injection in PHP: Tips, Code Samples, and FAQs",{"path":680,"title":681},"\u002Fmaximize-the-potential-of-headless-wordpress-with-graphql","Maximize the Potential of Headless WordPress with GraphQL",{"path":683,"title":684},"\u002Fwriting-clean-modular-and-reusable-code-in-php","Best Practices for Writing Clean, Modular, and Reusable Code in PHP",{"path":686,"title":687},"\u002Fheadless-cmss-an-overview-of-popular-alternatives-to-contentful-and-wordpress","Headless CMSs: An Overview of Popular Alternatives to Contentful and WordPress",{"path":689,"title":690},"\u002Fci-cd-for-php-a-comprehensive-guide","CI\u002FCD for PHP: A Comprehensive Guide",{"path":692,"title":693},"\u002Fintroduction-to-php-namespaces-a-beginners-guide-to-structuring-your-code","Introduction to PHP Namespaces: A Beginner's Guide to Structuring Your Code",{"path":695,"title":696},"\u002Fwhat-is-graylog-a-powerful-tool-for-collecting-indexing-and-analyzing-log-data","What is Graylog? A Powerful Tool for Collecting, Indexing, and Analyzing Log Data",{"path":698,"title":699},"\u002Felevate-your-turkish-audience-experience-with-professional-wordpress-plugin-and-theme-translation","Elevate Your Turkish Audience Experience with Professional WordPress Plugin and Theme Translation",{"path":701,"title":702},"\u002Fhow-to-set-up-a-self-hosted-api-gateway-a-comprehensive-guide","How to Set Up a Self-Hosted API Gateway: A Comprehensive Guide",{"path":704,"title":705},"\u002Fdifference-between-generators-and-iterators-in-php","The Key Differences Between PHP Generators and Iterators",{"path":707,"title":708},"\u002Fphp-and-machine-learning-a-winning-combination-with-php-ml","PHP and Machine Learning: A Winning Combination with PHP-ML",{"path":710,"title":711},"\u002Fphp-generators-a-beginners-guide-to-iteration","PHP Generators: A Beginner's Guide to Iteration",{"path":713,"title":714},"\u002Fmastering-closures-in-javascript-a-beginners-guide","Mastering Closures in JavaScript: A Beginner's Guide",{"path":716,"title":717},"\u002Fthe-top-php-certification-programs-for-developers","The Top PHP Certification Programs for Developers",{"path":719,"title":720},"\u002Fhow-to-revalidate-next-js-isr-cache-on-demand-cache-regeneration","How to Revalidate Next.js ISR Cache? On-Demand Cache Regeneration",{"path":722,"title":723},"\u002Ftips-for-translating-a-wordpress-plugin-wordpress-theme-to-turkish","Tips for Translating a WordPress Plugin \u002F WordPress Theme to Turkish",{"path":725,"title":726},"\u002Fall-about-headless-wordpress","All About Headless WordPress",{"path":728,"title":729},"\u002Finstall-composer-on-ubuntu","How to Install Composer on Ubuntu \u002F Linux",{"path":731,"title":732},"\u002Fwhat-is-an-api-gateway","What is an API Gateway? Should You Use It?",{"path":734,"title":735},"\u002Fis-jwt-safe-or-is-it-vulnerable","Is JWT Safe or Is It Vulnerable?",{"path":737,"title":738},"\u002Ftailwind-css-to-use-or-not-to-use-that-is-the-question","Tailwind CSS! To use? Or not to use? That is the question.",{"path":40,"title":740},"What is HATEOAS?",{"path":742,"title":743},"\u002Fhello-world","Hello World: A New Multilingual Journey",{"path":745,"title":746},"\u002Fwhat-is-ecmascript","What is ECMAScript? What is not?",{"path":745,"title":746},[749,750,751,752],{"path":615,"title":616,"date":630},{"path":46,"title":47,"date":630},{"path":28,"title":654,"date":630},{"path":609,"title":610,"date":630},[754,756,758],{"path":674,"title":675,"date":755},"2023-01-19",{"path":659,"title":660,"date":757},"2023-10-14",{"path":668,"title":669,"date":759},"2023-01-23",1782141978588]