Python: Fixing FastAPI Error 422 with POST Request and JSON Data

FastAPI is a modern, high-performance web framework for building APIs with Python 3.6+ based on standard Python type hints. It’s known for its simplicity, speed, and automatic documentation support. However, one of the most common issues developers face when using FastAPI—especially for the first time—is the mysterious:

HTTP 422 Unprocessable Entity error

This error often pops up when you’re sending JSON data in a POST request, but FastAPI doesn’t know how to handle it.

In this blog post, we’ll go over:

  • What causes the 422 error in FastAPI
  • How to properly send JSON data
  • How to define the correct request body in FastAPI
  • Full working example
  • References for further learning

The Problem: 422 Error When Sending JSON

Let’s say you have this basic FastAPI code:

from fastapi import FastAPI

app = FastAPI()

@app.post("/")
def main(user):
    return user

You try sending a POST request using Python’s requests library or JavaScript (Axios):

Python Request

import requests

response = requests.post("http://127.0.0.1:8000", json={"user": "smith"})
print(response.text)

JavaScript (Axios)

axios.post("http://127.0.0.1:8000", { user: "smith" })
    .then(res => console.log(res.data));

Expected: The API should echo back the user.

Actual: You get:

{
  "detail": [
    {
      "loc": ["query", "user"],
      "msg": "field required",
      "type": "value_error.missing"
    }
  ]
}

Or simply a 422 Unprocessable Entity error.


##The Reason: FastAPI Expects Request Body, Not Query Parameters

In FastAPI, unless you explicitly tell it otherwise, it assumes basic parameters like user are query parameters — not body content.

So in the code above:

@app.post("/")
def main(user):
    return user

FastAPI thinks you’re expecting /?user=smith in the URL — not JSON data in the request body.

That’s why your JSON { "user": "smith" } is rejected, resulting in the 422 error.


The Fix: Use a Pydantic Model for JSON Body

To properly accept JSON data in a POST request, you need to define a Pydantic model that describes the expected body content.

Updated FastAPI Code:

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class UserInput(BaseModel):
    user: str

@app.post("/")
def main(user_input: UserInput):
    return user_input

Why this works:

  • FastAPI now knows to look in the request body for JSON that matches the UserInput schema.
  • It parses the input automatically, validates it, and returns 422 only if the input doesn’t match the schema.

Sample Request:

POST / HTTP/1.1
Content-Type: application/json

{
  "user": "smith"
}

This will now work correctly.


##Full Working Example

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class UserInput(BaseModel):
    user: str

@app.post("/")
def main(user_input: UserInput):
    return {"received_user": user_input.user}

Test it with:

curl -X POST http://127.0.0.1:8000/ \
     -H "Content-Type: application/json" \
     -d '{"user": "smith"}'

Or using Python:

import requests

response = requests.post("http://127.0.0.1:8000", json={"user": "smith"})
print(response.json())

Response:

{
  "received_user": "smith"
}

Bonus: Case Sensitivity and Type Hints

  • FastAPI relies heavily on Python type hints.
  • Always use proper capitalization and matching types in your models.
  • Use tools like Swagger UI (built-in at /docs) to test your APIs.

Conclusion

If you’re getting a 422 Unprocessable Entity error in FastAPI when sending JSON data via a POST request, the fix is simple:

Use a Pydantic model to define what your API expects in the request body.

FastAPI does the rest — parsing, validation, and error handling.