Generate a Zod Schema from JSON Without Overfitting Samples
Infer nested Zod objects, arrays, unions, optional keys and null values, then refine the schema for your application.

A JSON sample is useful evidence about an API, but it is not a complete specification. One record may omit a rare field or show only one member of a broader union. A schema generator should preserve what was observed and make uncertain areas visible instead of fabricating constraints.
Use varied records to reveal optional keys
If a key is present in every observed object, the generated object schema requires it. If it is absent from some records, the field becomes optional. An explicit null adds a null alternative without making the key absent. These cases matter when validating update payloads. Include realistic records with empty strings, false, zero, null and missing keys rather than relying on one fully populated example.
Review empty arrays and mixed elements
An empty list provides no element-type information, so the tool uses an unknown element schema. Mixed samples produce unions, and object elements are merged into a shared shape. That merge does not infer correlations between fields. If the API uses a discriminator such as kind, define the separate variants manually and validate the relationship between kind and the remaining fields.
Choose your unknown-key policy deliberately
Strict object schemas reject keys outside the model. Standard object parsing normally strips unrecognized keys. Either choice can be appropriate, depending on whether the input is a tightly controlled command or a response that may gain harmless fields. The generated code does not coerce strings into numbers or infer email and timestamp formats from appearance. Add those decisions only when the documented contract supports them.
Worked example
// Missing name differs from explicit null:
z.object({ name: z.string().optional() });
z.object({ name: z.union([z.string(), z.null()]) });Why does an empty array use z.unknown()?
There is no observed element to infer from. Replace that placeholder with the documented item schema before relying on it as a contract.


