LearnThatStack Ace your next interview
API Design · question
Question 6 of 92

How do you handle validation errors in APIs?

beginner
← All API Design questions
Re-explain
Visual ↓

Reject the request with 422 Unprocessable Content and list every failing field, so the client can fix them all in one round trip. Use 400 Bad Request instead when the body can't be parsed at all, such as malformed JSON.

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed",
    "details": [
      {
        "field": "email",
        "code": "INVALID_FORMAT",
        "message": "Email must be valid format"
      },
      {
        "field": "password",
        "code": "TOO_SHORT",
        "message": "Password must be at least 8 characters"
      }
    ]
  }
}

Each entry carries three things.

  • A field that names the input, so a form can highlight it.
  • A stable error code, such as TOO_SHORT, that clients can handle in code.
  • A human message for display.

Validate the whole body before acting, and return all the errors at once rather than stopping at the first. Keep the shape consistent with your other errors, or use the standard problem details format from RFC 9457 with an errors member.

Rewriting in plainer words…

This answer doesn't lend itself to a diagram - it reads best . No credits were charged.

Why there's no diagram: “”

The interactive diagram is below the answer - jump to diagram ↓ · Below it, the related concept . Jump to it ↓

The diagram below the answer is the concept . Jump to it ↓

Tailored explanation · switch back to · ·
What should the new diagram focus on?
Guided practice for API Design One question at a time. Answer out loud, get graded, see what you missed.
Related concept

Status codes and error design: how an API says NO

The status code tells machines whose fault the failure was and whether to retry. The error body tells a developer what to fix, and it is never an apology.

For this question · chapter 2 of 3Watch the details row split into email and password, so each entry sits with its own input field. This answer describes that field-level shape, with a 422 in the response head and a stable code above the 422.

2/3 Error parts go to their fields
contractError parts go to their fieldsread by code, not by eyeresponseclientstatus422something went wrongemail and password are invalidVALIDATION_ERRORemail passwordreq_7t4k29at db.query (pg.js:212)refusedstatus 422VALIDATION_ERRORemail and password are invalidreq_7t4k29 email and password are invalidemailpassword
contractError parts go to their fieldsresponseclientstatus422something went wrongemail and password are invalidVALIDATION_ERRORemail passwordreq_7t4k29at db.query (pg.js:212)refusedstatus 422VALIDATION_ERRORemail and password are invalidreq_7t4k29 email and password are invalidemailpassword

Error parts go to their fields

  1. The status code is for machines. The body is for the person who has to fix the problem. Here the code is 422, which is correct, so the client takes the error path. But the body only says something went wrong. So the message helps nobody: not the client, not the user, and not the API owner (you).
  2. The error body contains a code, VALIDATION_ERROR, and the client matches that exact string. The code exists for branching, so the wording never changes and the code is never a sentence. Treat the code like an enum you have published. Clients depend on the code from the day it ships.
  3. The message is written for a person: email and password are invalid. No client logic should depend on the message, so you may reword the message at any time. The message is for a developer reading a log. The error code is for a program.
  4. The details list has two entries, email and password. Each entry names its field, so the form can show the error where the user is looking. A validation error with no field name does not say where the problem is. So the user has to search the form for the field that is wrong.
  5. The error body carries a request id. The log line records the same id next to the error message. Support asks for that id, because the id links a complaint in a ticket to a line in your logs. You search by timestamp when the id is missing.
  6. The error body should never include a stack trace. Internal details such as file paths, SQL, and driver messages are not transparency. Those details show an attacker what runs behind the API. RFC 9457, called problem details, is the standard to cite if you want one.
Chapter 2 · step 1 of 6

The status code is for machines. The body is for the person who has to fix the problem. Here the code is 422, which is correct, so the client takes the error path. But the body only says something went wrong. So the message helps nobody: not the client, not the user, and not the API owner (you).

1 of 6 Use ← → or swipe See the concept: all 3 chapters in it

© LearnThatStack - diagrams may not be republished without permission.

How well did you know this?
AI:

Saved in this browser - sign in to keep your review list.

How should your speech become text?

Listening… your words appear above as you speak - tap Stop when you're done.

Recording · cr - tap Stop & transcribe when you're done.

Transcribing with AI…

Voice:

Keep going - a few more words and AI can grade it.

Interview lens How interviewers actually use this question

Likely follow-ups

  • How would you report an error on a nested field, like the quantity of the third item in an order? Use a path to the exact input, such as items[2].quantity or a JSON Pointer like /items/2/quantity, so the client can map it back.
  • The email is well-formed but already registered. Is that still a 422? Separate format checks from state conflicts. Many APIs use 409 Conflict here, and a unique constraint must back it, since check-then-insert can race.
  • If the browser already validates the form, why check again on the server? Client checks give fast feedback, and anyone can bypass them. The server is the authority. One shared schema, like OpenAPI, keeps both sides on the same rules.
  • How do you keep this shape consistent with your other errors, like 404 or 500? Use one envelope for every error, or RFC 9457 problem details, with a stable code. A 500 gets a generic message and no stack trace.
  • How would you return the same field-level errors from a gRPC service? Return INVALID_ARGUMENT and attach a google.rpc.BadRequest detail listing field violations, rather than packing everything into the message string.

What you can say

  1. When a request fails validation, I reject it with 422 Unprocessable Content and list every field that failed, so the client can fix them all in one round trip.
  2. Each error has three parts: the field name so a form can highlight it, a stable code like TOO_SHORT that client code can branch on, and a human message to display.
  3. I validate the whole body before doing anything, and I collect every error instead of stopping at the first one.
  4. I keep that shape the same as my other errors, or use RFC 9457 problem details with an errors member, so clients only parse one format.
  5. The one place I don't use 422 is a body that can't be parsed at all, like malformed JSON. That gets a 400 Bad Request.

Weak answers to avoid

  • Returns 200 with an error flag in the body Every client, proxy and monitor that reads status codes will treat the failure as a success. Use 422 with an error body so a failure looks like one.
  • Stops at the first failing field The user fixes one field, resubmits, and hits the next error. Validate the whole body and return every failure in one response.
  • Only a free-text message, no field or code Clients end up parsing English strings, which break when the wording changes. Give each error a field name and a stable code, and keep the message for display.
  • Can't say when 400 fits and when 422 does Many APIs send 400 for everything, so explain the split. Use 400 when the body can't be parsed, like malformed JSON, and 422 when it parses but breaks the rules.
Interview lens

Likely follow-ups, what you can say, and the weak answers to avoid.

Sign in free to open it Free account - the lens opens as soon as you're back.

Want a quick review of the fundamentals? See the API Design cheatsheet.

← Back to all API Design questions
Pro · $10/mo

74 of 92 API Design answers are in Pro.

Full answers, code samples, and AI explanations that go simpler or deeper. Cancel anytime.

  • Full answers + code
  • AI explanations, simpler or deeper
  • 1,000 AI credits / month
  • Cancel anytime