JSON to Schema and Zod
Turn a sample JSON payload into a draft-07 JSON Schema and a matching Zod validator, with email, URL and date formats detected.
Turn a sample payload into a JSON Schema and a matching Zod validator, with formats detected.
Detected shape
Formats are guessed from one sample. A field that is null here is marked optional, and a field that can hold more than one type will only show the type it had in this payload.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "User",
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"email": {
"type": "string",
"format": "email"
},
"site": {
"type": "string",
"format": "uri"
},
"joined": {
"type": "string",
"format": "date-time"
},
"score": {
"type": "number"
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"profile": {
"type": "object",
"properties": {
"city": {
"type": "string"
},
"verified": {
"type": "boolean"
}
},
"required": [
"city",
"verified"
],
"additionalProperties": false
}
},
"required": [
"id",
"email",
"site",
"joined",
"score",
"tags",
"profile"
],
"additionalProperties": false
}About the json to schema and zod
TypeScript types disappear at compile time, so they describe what you hope an API returns rather than what it actually returned. For data you do not control, you need a runtime validator as well, and writing one by hand from a large payload is tedious and error prone.
This generates both: a JSON Schema for tooling and documentation, and a Zod schema you can drop straight into a TypeScript codebase. Common string formats are recognised, so an email field becomes a validated email rather than a plain string.
How to use it
- 1Paste a real response from the API.
- 2Name the schema.
- 3Check the detected shape, especially the formats.
- 4Copy the JSON Schema or the Zod validator.
Questions
Why generate Zod as well as JSON Schema?
JSON Schema is the portable format for documentation and tooling. Zod is what most TypeScript codebases actually validate with, and it infers a static type for free.
Are the formats always right?
They are guessed from the value. A string that looks like an email is typed as an email. Check them, because a field that happens to contain a URL in this sample may not always.
How are optional fields decided?
A field that is null in the sample is marked nullable, since null usually means sometimes absent. A field missing entirely from the sample cannot be detected at all, so check the API docs.
Does an empty array work?
It produces an empty item schema, because an empty array carries no information about what it holds. Use a sample with data in it.