# Fix FastAPI 422 Error: Value Is Not a Valid Dict

> Resolve the FastAPI 422 validation error by converting a Pandas DataFrame to a dictionary with to_dict instead of sending a JSON list to a Pydantic model endpoint

**URL:** https://sentry.io/answers/post-request-to-fastapi-endpoint-produces-error-422-value-is-not-a-valid-dict/

---

## The Problem

I have a Python script that sends a POST request to an API I've built using FastAPI. The POST request fails with error code 422 and the following details:

```json
{
  "detail": [
    {
      "loc": [ "body" ],
      "msg": "value is not a valid dict",
      "type": "type_error.dict"
    }
  ]
}
```

My client script looks like this:

```python
import requests, pandas, json

dataframe = pandas.DataFrame({
    "Firstname": ["Joaquin"],
    "Surname": ["Phoenix"],
    "Age": [49]
})

df_json = dataframe.to_json(orient="records")
response = requests.post('http://localhost:8000/create-user/',
                           json=json.loads(df_json),
                           headers={"Content-Type": "application/json"})
print(response.json())
```

The relevant API endpoint and Pydantic model look like this:

```python
from pydantic import BaseModel
from fastapi import FastAPI

app = FastAPI()

class User(BaseModel):
    firstname: str
    surname: str
    age: int

@app.post("/create-user/")
async def create_users(user: User):
    # ... user creation operations ...
    return {"Message": "User created."}
```

What's going wrong? Is it a problem with my client script or my API code?

## The Solution

The problem is in the client script. The `requests.post` function expects a dictionary to be passed to the `json` keyword argument, which it will automatically convert to JSON.

This script first converts a Pandas DataFrame to a JSON string ([`dataframe.to_json(orient="records")`](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_json.html)), which looks like this:

```
[{"Firstname":"Joaquin", "Surname": "Phoenix","Age": 49}]
```

The script then uses [`json.loads`](https://docs.python.org/3/library/json.html#json.loads) to convert it back into a Python object. Because of the argument `orient="records"` in the original conversion, the object created here will be a list rather than a dictionary, leading to the 422 error when it is submitted.

We can fix this problem by converting the DataFrame [to a dictionary](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_dict.html) instead of a JSON string:

```python
import requests, pandas

dataframe = pandas.DataFrame({
    "Firstname": ["Joaquin"],
    "Surname": ["Phoenix"],
    "Age": [49]
})

userdata = dataframe.to_dict(orient="records")
# will be a list: [{"Firstname":"Joaquin", "Surname": "Phoenix","Age": 49}]
userdata = userdata[0] # take the first item from the list
# will be a dictionary: {"Firstname":"Joaquin", "Surname": "Phoenix","Age": 49}
prediction = requests.post('http://localhost:8000/create-users/',
                           json=userdata,
                           headers={"Content-Type": "application/json"})
```

This altered code should produce the expected results.

---

*Source: [sentry.io/answers/post-request-to-fastapi-endpoint-produces-error-422-value-is-not-a-valid-dict/](https://sentry.io/answers/post-request-to-fastapi-endpoint-produces-error-422-value-is-not-a-valid-dict/)*
