Tools · Pydantic

# 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.

no signup · runs entirely in your browser · ⌘V works anywhere on this page

## 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

{"id": 1, "status": "paid"}from __future__ import annotations from pydantic import BaseModel class Order(BaseModel): id: int status: str

[{"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]

{"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

{"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.

clean-order-example.json → Pydantic, as Convert writes it — pydantic v2 · 7 models · 34 fields · 933 b

```
from __future__ import annotations

from datetime import datetime
from pydantic import BaseModel


class Customer(BaseModel):
    id: str
    email: str
    name: str
    verified: bool
    loyalty_tier: str
…
```

## 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.

## Behind this page

## Try it on the file that broke your afternoon.

free · no signup

---

Canonical: https://unstringify.com/tools/json-to-pydantic
