Separate OpenAPI Schemas for Input and Output or Not¶
SincePydantic v2 was released, the generated OpenAPI is a bit more exact andcorrect than before. 😎
In fact, in some cases, it will even havetwo JSON Schemas in OpenAPI for the same Pydantic model, for input and output, depending on if they havedefault values.
Let's see how that works and how to change it if you need to do that.
Pydantic Models for Input and Output¶
Let's say you have a Pydantic model with default values, like this one:
fromfastapiimportFastAPIfrompydanticimportBaseModelclassItem(BaseModel):name:strdescription:str|None=None# Code below omitted 👇👀 Full file preview
fromfastapiimportFastAPIfrompydanticimportBaseModelclassItem(BaseModel):name:strdescription:str|None=Noneapp=FastAPI()@app.post("/items/")defcreate_item(item:Item):returnitem@app.get("/items/")defread_items()->list[Item]:return[Item(name="Portal Gun",description="Device to travel through the multi-rick-verse",),Item(name="Plumbus"),]Model for Input¶
If you use this model as an input like here:
fromfastapiimportFastAPIfrompydanticimportBaseModelclassItem(BaseModel):name:strdescription:str|None=Noneapp=FastAPI()@app.post("/items/")defcreate_item(item:Item):returnitem# Code below omitted 👇👀 Full file preview
fromfastapiimportFastAPIfrompydanticimportBaseModelclassItem(BaseModel):name:strdescription:str|None=Noneapp=FastAPI()@app.post("/items/")defcreate_item(item:Item):returnitem@app.get("/items/")defread_items()->list[Item]:return[Item(name="Portal Gun",description="Device to travel through the multi-rick-verse",),Item(name="Plumbus"),]...then thedescription field willnot be required. Because it has a default value ofNone.
Input Model in Docs¶
You can confirm that in the docs, thedescription field doesn't have ared asterisk, it's not marked as required:

Model for Output¶
But if you use the same model as an output, like here:
fromfastapiimportFastAPIfrompydanticimportBaseModelclassItem(BaseModel):name:strdescription:str|None=Noneapp=FastAPI()@app.post("/items/")defcreate_item(item:Item):returnitem@app.get("/items/")defread_items()->list[Item]:return[Item(name="Portal Gun",description="Device to travel through the multi-rick-verse",),Item(name="Plumbus"),]...then becausedescription has a default value, if youdon't return anything for that field, it will still have thatdefault value.
Model for Output Response Data¶
If you interact with the docs and check the response, even though the code didn't add anything in one of thedescription fields, the JSON response contains the default value (null):

This means that it willalways have a value, it's just that sometimes the value could beNone (ornull in JSON).
That means that, clients using your API don't have to check if the value exists or not, they canassume the field will always be there, but just that in some cases it will have the default value ofNone.
The way to describe this in OpenAPI, is to mark that field asrequired, because it will always be there.
Because of that, the JSON Schema for a model can be different depending on if it's used forinput or output:
- forinput the
descriptionwillnot be required - foroutput it will berequired (and possibly
None, or in JSON terms,null)
Model for Output in Docs¶
You can check the output model in the docs too,bothname anddescription are marked asrequired with ared asterisk:

Model for Input and Output in Docs¶
And if you check all the available Schemas (JSON Schemas) in OpenAPI, you will see that there are two, oneItem-Input and oneItem-Output.
ForItem-Input,description isnot required, it doesn't have a red asterisk.
But forItem-Output,description isrequired, it has a red asterisk.

With this feature fromPydantic v2, your API documentation is moreprecise, and if you have autogenerated clients and SDKs, they will be more precise too, with a betterdeveloper experience and consistency. 🎉
Do not Separate Schemas¶
Now, there are some cases where you might want to have thesame schema for input and output.
Probably the main use case for this is if you already have some autogenerated client code/SDKs and you don't want to update all the autogenerated client code/SDKs yet, you probably will want to do it at some point, but maybe not right now.
In that case, you can disable this feature inFastAPI, with the parameterseparate_input_output_schemas=False.
Info
Support forseparate_input_output_schemas was added in FastAPI0.102.0. 🤓
fromfastapiimportFastAPIfrompydanticimportBaseModelclassItem(BaseModel):name:strdescription:str|None=Noneapp=FastAPI(separate_input_output_schemas=False)@app.post("/items/")defcreate_item(item:Item):returnitem@app.get("/items/")defread_items()->list[Item]:return[Item(name="Portal Gun",description="Device to travel through the multi-rick-verse",),Item(name="Plumbus"),]Same Schema for Input and Output Models in Docs¶
And now there will be one single schema for input and output for the model, onlyItem, and it will havedescription asnot required:








