Quick answer
To build a JSON Schema that reflects real data, paste multiple JSON samples and merge them. A single sample marks every field as required and locks its type; merging several samples reveals which fields are optional (missing from some samples) and which are nullable (different types across samples). Everything runs in your browser — your JSON never leaves your device.
Why one sample isn't enough
Auto-generating a schema from a single JSON object is fast, but it makes two assumptions that are almost always wrong for real APIs:
- Every field is required. If your one sample happens to include
phone, the schema demandsphoneon every record — even though many records omit it. - Every type is fixed. If
deletedAtis a string in your sample, the schema rejects thenullthe API actually returns most of the time.
Collecting a handful of real responses and merging them fixes both. The merger keeps a field required only when it is present and non-null in every sample, and unions the types it sees for each field.
How merging decides required, optional, and nullable
| Across your samples… | Merged schema result |
|---|---|
| Field present and non-null in every sample | Stays in required |
| Field missing from at least one sample | Dropped from required (optional), kept in properties |
Field is null in at least one sample | Optional + nullable — type: ["string","null"] |
| Field is a string in one sample, a number in another | Union of both types — type: ["string","number"] |
| Nested objects with differing keys | Merged recursively — same rules applied at every depth |
All samples agree on a string format (e.g. email) | Format hint preserved; dropped when samples disagree |
Example — three user records where phone appears in one, is missing in another, and is null in a third:
// Sample 1: { "id": 1, "name": "Alice", "phone": "+1-202-555-0143" }
// Sample 2: { "id": 2, "name": "Bob", "role": "admin" }
// Sample 3: { "id": 3, "name": "Carol", "phone": null, "role": "editor" }
// Merged schema:
{
"$schema": "https://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"id": { "type": "integer" },
"name": { "type": "string" },
"phone": { "type": ["string", "null"] }, // ← optional + nullable
"role": { "type": "string" } // ← optional (missing in sample 1)
},
"required": ["id", "name"] // ← only the fields in every sample
}
Single sample vs. multiple samples vs. quicktype
| Approach | Detects optional fields? | Detects nullable types? | Where it runs |
|---|---|---|---|
| Single-sample generator | No — all fields required | No — type locked to the sample | Browser |
| This multi-sample merger | Yes — required intersection | Yes — type union per field | Browser (no upload) |
| quicktype | Yes | Yes | CLI / install required |
The merged schema is still a starting point — review and tighten it (add enum, minLength, numeric bounds), then confirm it with the JSON Schema Validator.
Frequently Asked Questions
Why generate a JSON Schema from multiple samples instead of one?
A single JSON sample cannot tell you which fields are optional or nullable. Inferring from one example marks every field as required and locks each type to whatever that sample contained. By merging several real samples, the generator sees the variation: a field missing from some samples becomes optional, and a field whose value differs in type across samples becomes a nullable or union type. The result is a schema that matches real data instead of one lucky example.
How does merging decide which fields are required?
A field is kept in the required list only if it is present and non-null in every sample. If any sample omits the field or sends it as null, the field is moved out of required and treated as optional. This is the intersection of the required fields across all samples.
How are fields with different types across samples handled?
When the same field appears with different types in different samples — for example a string in one and null in another — the merger combines them into a single type array such as ["string","null"], the pattern real APIs use for nullable fields.
How many JSON samples can I merge?
Between 2 and 5 samples. Use the Add sample button to add slots up to five, and the remove button on each slot to drop down to a minimum of two. More samples give the merger more variation to learn optional and nullable fields from.
Does it still infer formats like email, date-time, and UUID?
Yes. Each sample is inferred with the same engine as the single-sample generator, so string format hints (email, date-time, date, uuid, uri) are detected per field. When the merged samples agree on a format it is preserved; when they disagree the format hint is dropped.
Is my JSON sent to a server?
No. Every sample is parsed and merged entirely in your browser using JavaScript. Your JSON never leaves your device.