JSON to Pydantic model
Paste JSON and get Pydantic v2 models — one class per nested object, str | None where the sample has null, the root model last so the file imports clean.
What you get
- Writes the API-response sample as pydantic v2 · 7 models · 34 fields
- One class per nested object, children first and the root model last, from __future__ import annotations at the top — the file imports as written
- str | None where the sample has null, X | None = None where a key is missing from some elements — the paginated list defaults failure_message
- datetime for an RFC 3339 string (and imports it), int for numbers written whole, float for the rest — 149.00 is a float — bool, list[Item] for a list
- Keeps a key that is not a Python name through Field(alias=…): class → class_, seat-row → seat_row
What it will not do
- Write Pydantic v1, dataclasses or TypedDict. v2 models with X | None unions — Python 3.10 or later.
- Add validators, defaults beyond None, or a model_config. Plain models you extend.
- Guess a null’s type beyond string: a field that is only ever null is str | None, said so here.
- Send your text anywhere. The page is static and the engine runs in this tab — open the network panel and watch it stay empty.
What you get
- An object → a BaseModel, named from the file
{"id": 1, "status": "paid"}from __future__ import annotations from pydantic import BaseModel class Order(BaseModel): id: int status: str- A key missing in some items → X | None = None
[{"id":1,"note":"x"},{"id":2}]from __future__ import annotations from pydantic import BaseModel class OrderItem(BaseModel): id: int note: str | None = None Order = list[OrderItem]- An RFC 3339 string → datetime, with its import
{"created_at": "2026-04-21T14:32:08Z"}from __future__ import annotations from datetime import datetime from pydantic import BaseModel class Order(BaseModel): created_at: datetime- A key that is not a Python name → Field(alias=…)
{"class": "economy", "seat-row": 12}from __future__ import annotations from pydantic import BaseModel, Field class Order(BaseModel): class_: str = Field(alias="class") seat_row: int = Field(alias="seat-row")
The sample
What the first sample opens — a real file, not an illustration written for this page.
in VS Code
Convert, then Pydantic — the models land in a new .py editor beside the JSON.
Questions
Pydantic v1 or v2?
v2. The models use X | None unions and Field(alias=…), which v2 reads as written; nothing here needs a validator import.
Why is the root model last?
Each class lands after the ones it names, so the root — which names them all — comes last. With from __future__ import annotations the order would not break, but a file that reads top-down needs no explaining.
What happens when a field is only ever null?
It is str | None. A lone null says nothing about the value, so this is the one guess the models make — and they guess str.