I have an endpoint that takes a Pydantic model, Foo, as a query parameter. from typing import Annotated import uvicorn from fastapi import FastAPI, Query from pydantic import BaseModel app = FastAPI() class Foo(BaseModel): bar: str baz: dict[str, str] @app.get("/") def root(foo: Annotated[Foo, Query()]): return foo if __name__ == "__main__": uvicorn.run("test:app") I'm defining my query params using Swagger, so the encoding should be correct. I know the baz param syntax looks redundant because I've nested a dictionary, but parsing fails even without nesting. But when I call the endpoint... curl -X 'GET' \ 'http://127.0.0.1:8000/?bar=sda&baz=%7B%22abc%22%3A%22def%22%7D' \ -H 'accept: application/json' FastAPI does not seem to read in Foo.baz correctly, returning { "detail": [ { "type": "dict_type", "loc": [ "query", "baz" ], "msg": "Input should be a valid dictionary", "input": "{\"abc\":\"def\"}" } ] } I've read similar questions and I know I can ingest the dictionary by accessing dict(request.query_params), but this bypasses FastAPI's validation and I'd prefer to keep the endpoint simple and consistent with the rest of my codebase by keeping the param as a Pydantic model. How can I get FastAPI to parse Foo as a query param? Continue reading...