{ }jsonkit
Tools/Convert/JSON to Pydantic
Search tools…⌘K
Format
{ }JSON Formatter
≡→JSON Minifier
\"JSON Escape / Unescape
a→zJSON Sorter
⇄{}JSON Flattener
Validate
JSON Validator
±JSON Diff / Compare
§JSON Schema Generator
JWT Decoder
ΔJSON Patch / Merge Patch
kbJSON Size Analyzer
Convert
→csvJSON to CSV
csv→CSV to JSON
⇄ymlJSON ⇄ YAML
⇄xmlJSON ⇄ XML
→tsJSON to TypeScript
b64Base64 Encode / Decode
%2FURL Encode / Decode
clkTimestamp Converter
→zJSON to Zod
→pyJSON to Pydantic
→goJSON to Go
→javaJSON to Java
⇄jsonlJSON ⇄ JSONL
5→JSON5 / JSONC to JSON
Query
$.JSONPath / JQ Tester
.*Regex Tester
Generate
Mock JSON Data Generator
idUUID / NanoID Generator
#Hash Generator
→py

JSON to Pydantic Model Generator

Infer Pydantic v2 models with nested classes from sample JSON.
processes as you type · client-side
Sample
Upload
Optional detection
snake_case fields
⧉ Copy output ⌘C
Download
Share
Clear
Input343 B · paste or drop a file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
Pydantic model
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
from typing import Any from pydantic import BaseModel, Field class Profile(BaseModel): display_name: str = Field(alias="displayName") avatar_url: Any = Field(alias="avatarUrl") class Post(BaseModel): id: int title: str pinned: bool | None = None class Root(BaseModel): user_id: int = Field(alias="userId") user_name: str = Field(alias="userName") is_active: bool = Field(alias="isActive") account_balance: float = Field(alias="accountBalance") roles: list[str] profile: Profile posts: list[Post]
✓ valid (RFC 8259)343 B → 549 B0.0 msLn 1, Col 1UTF-8

About JSON to Pydantic

Paste a JSON sample and get ready-to-use Pydantic v2 models. The generator infers a class(BaseModel) for the root and a separate named class for every nested object, emitting each class before the one that references it so the file imports and runs top to bottom without forward-reference errors.

Types are inferred from the values: whole numbers become int, decimals become float, true/false become bool, strings become str, and null becomes Any. Arrays are inspected element by element to produce list[...] annotations, and arrays of objects are merged into a single list[Model].

Everything runs client-side in your browser. Your JSON is never uploaded to a server, so pasting a real API response, a config file or a webhook payload stays completely private. It is free, needs no signup, and keeps working offline.

How it works

Nested objects become their own classes

Each nested object is promoted to its own BaseModel class named after the field, and arrays of objects are named from the singular of the field (posts becomes a Post class used as list[Post]). Because Python requires a class to be defined before it is used, nested classes are always emitted above the class that references them.

Optional detection across arrays

With Optional detection on, the generator scans every object in an array and marks any field that is missing from at least one element as field: X | None = None. This mirrors how real API collections drift over time, so the model accepts records with or without the sparse field instead of failing validation.

snake_case fields with aliases

With snake_case fields on, keys like userId become user_id and the original key is preserved with Field(alias="userId") so parsing still matches the incoming JSON. Turn it off to keep the original key names wherever they are valid Python identifiers; invalid keys (spaces, hyphens, leading digits) and Python keywords are always renamed and aliased.

Clean, minimal imports

The output starts with from pydantic import BaseModel, adding Field only when at least one alias is emitted and from typing import Any only when a null or empty array forces an Any. The result is syntactically valid Python you can paste straight into a models.py file.

Frequently asked questions

Is my JSON uploaded anywhere?

No. The conversion runs entirely in your browser with JavaScript — nothing is sent to a server. You can disconnect from the internet and it still works, which makes it safe for production payloads.

Which Pydantic version does it target?

Pydantic v2. It uses modern syntax like list[X] and X | None, and Field(alias=...) for renamed keys. The output works with any Pydantic 2.x release and requires Python 3.10+ for the | union syntax.

Why did my field get a Field(alias=...)?

Whenever the emitted attribute name differs from the JSON key — for example userId turned into user_id, or a key contained a space or hyphen — an alias is added so Pydantic still reads the original key from the incoming data while your code uses the clean Python name.

How are optional fields decided?

When Optional detection is on, a field present in some but not all objects of an array is treated as optional and typed X | None = None. A field that is always present stays required. Turn the toggle off to make every field required.

What happens with null values or empty arrays?

A null gives no type to infer, so the field is typed Any, and an empty array becomes list[Any]. Provide a fuller sample with non-null values and populated arrays to get more precise types.