JSON to Pydantic Model
Generate a Pydantic model from a JSON document.
Related Tools
Generate Python dataclasses from a JSON document.
Generate a Zod validation schema and TypeScript type from a JSON document.
Generate TypeScript interfaces or type aliases from JSON.
Beautify and pretty-print JSON with configurable indentation.
Convert CSV to JSON with delimiter detection and header toggle.
Generate Go structs with JSON tags from a JSON document.
Documentation
What is JSON to Pydantic?
This tool converts a JSON sample into Pydantic BaseModel classes — Python models that both describe a shape and validate real data against it at runtime, which is why they're the default choice for FastAPI request/response bodies and for parsing any untrusted JSON.
How it works
Nested JSON objects each become their own class Name(BaseModel), printed child-first. Field names are converted from the JSON key to snake_case, matching Python convention. When that conversion changes the name — a camelCase JSON key like isActive becoming is_active — the generator adds Field(alias="isActive") so the model still accepts and serializes the exact original wire key while your Python code reads idiomatically. A field whose sample value was null becomes Optional[T] with a default of None — distinct from a field that's simply missing from the JSON, which can't be detected from one sample. A field name that collides with a Python keyword (like class or from) gets a trailing underscore.
Features
- Automatic camelCase-to-snake_case field renaming with a matching
Field(alias=...)so the wire format is unaffected - Nullable sample values map to
Optional[T] = None, not silently dropped - Nested objects and arrays (
List[T]) supported at any depth - Only imports
FieldandAnywhen the generated code actually needs them - Compatible with both Pydantic v1 and v2 — no version-specific syntax
Example
Input: { "id": 101, "username": "alice_dev", "isActive": true, "signupBonus": null, "address": { "city": "Berlin", "zipCode": "10115" }, "tags": ["admin", "beta"] }
Output:
from typing import Any, List, Optional
from pydantic import BaseModel, Field
class Address(BaseModel):
city: str
zip_code: str = Field(alias="zipCode")
class Root(BaseModel):
id: int
username: str
is_active: bool = Field(alias="isActive")
signup_bonus: Optional[Any] = Field(alias="signupBonus", default=None)
address: Address
tags: List[str]Common errors
A null sample value becomes Optional[Any] — Pydantic will accept literally anything for that field until you narrow it to a real type. Remember that Field(alias=...) means the model only accepts input under the alias by default; if you also need attribute-style construction using the Python name, set populate_by_name = True (v2) or allow_population_by_field_name = True (v1) in your model config.
Best practices
Use model_config = ConfigDict(populate_by_name=True) (Pydantic v2) if your codebase constructs models directly from Python kwargs as well as from JSON, so both the snake_case name and the camelCase alias work as input. Replace Optional[Any] fields with a concrete union or type as soon as you know what the field can actually hold — leaving it as Any defeats the point of validating the payload at all.
Frequently Asked Questions
Why Pydantic instead of a plain dataclass?▾
A dataclass only describes shape — it does nothing at runtime to check that the data you actually received matches. Pydantic validates real data (an API response, request body) against the model and raises a clear error if it doesn't match, which is why it's the default choice for FastAPI request/response models and any code parsing untrusted JSON.
Why do some fields have Field(alias=...)?▾
JSON keys are often camelCase; Python convention is snake_case. When a field name would change from the original JSON key, the generator adds Field(alias="originalKey") so the model still accepts and serializes the exact original key over the wire while your Python code reads idiomatically.
How are nullable fields handled?▾
A field whose sample value is null becomes Optional[T] with a default of None, matching how Pydantic represents an optional field — distinct from a field that's simply absent from the JSON, which the generator can't detect from a single sample.
Does this target Pydantic v1 or v2?▾
The generated code (BaseModel, Field(alias=...)) works on both v1 and v2 — it doesn't use v2-only syntax like model_config or the newer validator decorators, so it drops into either version without changes.