JSON to Pydantic BaseModel Converter — Offline & Private
Turn any JSON payload into Pydantic v2 models: BaseModel classes emitted children-first, keys missing from array elements become Optional with a None default, ISO-8601 strings map to datetime, and camelCase keys get Field(alias=...) with populate_by_name. The converter runs in a Web Worker in your browser — zero uploads.
Zero upload, ever
Inference and code generation run in a Web Worker inside your browser — payloads with PII never touch a server.
Live 300 ms conversion
Output updates as you type, with mixed-array unions, merged objects, and ISO-8601 dates inferred automatically.
v2-native output
model_config = ConfigDict, Field aliases, and typing imports — idiomatic modern Pydantic.
Paste JSON to generate a schema
JSON input
Generated schema
Paste JSON on the left — Zod, TypeScript, Pydantic, and Go schemas appear here instantly, generated entirely in your browser.
Technical documentation
How JSON maps to BaseModel classes
Each nested object in your payload becomes its own BaseModel class, emitted children-first so the file imports cleanly top to bottom. Scalars map to their Python equivalents — str, float, bool — arrays become List[T], and mixed arrays such as [1, "a"] fold into Union[float, str] wrapped in Optional when null is present. A root that is not an object gets a module-level alias (Root = List[RootItem]) instead of a class.
Optionality is inferred from the data: when an array of objects contains records with different keys, any key missing from at least one element is emitted as Optional[T] = None — the contract FastAPI and Pydantic users actually want for partial API responses. Nulls map to Any, or Optional[...] inside unions, keeping validation lenient exactly where the evidence is ambiguous.
Aliases, datetimes, and populate_by_name
camelCase JSON keys are converted to snake_case field names, and every renamed field carries Field(alias="originalKey") so the model still validates the wire format byte-for-byte. Classes with aliases set model_config = ConfigDict(populate_by_name=True), letting you construct models with either the snake_case name or the original alias — the pattern the Pydantic docs recommend for camelCase APIs.
Strings matching ISO 8601 — dates or full timestamps with timezone offsets — are typed as datetime, so Pydantic parses them into aware datetime objects on validation. Keys that are already snake_case stay untouched with no alias, and Python keywords are suffixed safely (a class key becomes class_), so the generated module is valid Python no matter what your API names its fields.
Why offline conversion matters for JSON with user data
Pydantic models are usually written against real payloads: user records, order histories, support tickets. That JSON contains exactly the personally identifiable information — names, emails, addresses, phone numbers — that GDPR, CCPA, and internal security policies restrict. Running it through a server-hosted converter means transmitting your users' data to an unknown third party, where it may sit in logs or object storage indefinitely; for healthcare or fintech payloads that can be a reportable breach.
This tool has no backend to receive anything. The page is statically exported HTML and JavaScript, and the model generator — pure TypeScript — runs inside a Web Worker in your browser, capped by a 3-second watchdog. Nothing is uploaded, nothing is logged, and the tool keeps working offline once loaded, which makes it safe for production payloads on corporate laptops and in restricted networks.
Using the generated models
The output targets Pydantic v2 with its modern APIs: model_config with ConfigDict, Field(alias=...), and standard typing imports computed from what your payload actually uses. Validate with Model.model_validate(json.loads(payload)) and serialize back with model_dump(mode="json") — datetimes and aliases round-trip correctly because the aliases mirror the original keys.
On Pydantic v1, the output needs only mechanical tweaks — replace model_config with an inner class Config containing populate_by_name = True — everything else (typing imports, Field aliases, Optional defaults) is unchanged. The models drop straight into FastAPI request bodies, SQLModel bases, or data-processing pipelines.
Frequently asked questions
Does the JSON I paste leave my browser?
No. The converter is a static page and the generator runs in a Web Worker locally — payloads containing customer names, emails, or tokens are never transmitted, stored, or logged by anyone.
How are camelCase keys handled in the models?
They become idiomatic snake_case fields with Field(alias="originalKey") so validation still accepts the raw JSON, and the class sets model_config = ConfigDict(populate_by_name=True) so you can instantiate with either spelling.
Are ISO date strings converted to datetime?
Yes. Strings matching ISO 8601 — including date-only values and timestamps with timezone offsets — are typed as datetime, and Pydantic parses them into real datetime objects at validation time.
What happens when array objects have inconsistent keys?
Keys present in every element become required; keys missing from at least one element become Optional[T] = None. Merged this way, the models accept the full range of shapes a real paginated API returns.
Does the output target Pydantic v1 or v2?
v2 — the output uses model_config = ConfigDict(...) and Field aliasing. For v1 projects, swap model_config for an inner Config class with populate_by_name = True; everything else works as-is.
How are null values represented?
A null-only field maps to Any, and null inside a mixed array wraps the union in Optional — so Optional[Union[float, str, bool]] for [1, "a", true, null]. Validation stays lenient precisely where the sample data is ambiguous.