From a sample to a type
Paste the JSON an API returned and get the type a compiler accepts for it. The generator reads every object, array, and scalar in the sample, merges objects that appear in the same position, and emits one declaration per distinct shape. The engine is quicktype-core, the same inference that powers the quicktype command line, running in a worker on this page.
Pick the language, set the top-level type name, and the output updates as you type. Each language exposes the options its renderer supports: TypeScript can emit type aliases instead of interfaces, Go can add omitempty, Kotlin can switch between Jackson and kotlinx.serialization, C# between System.Text.Json and Newtonsoft, Python between dataclasses and pydantic models.
Example
This sample:
{
"id": 7,
"name": "Ada",
"email": null,
"tags": ["a", "b"],
"orders": [
{ "sku": "X1", "qty": 2 },
{ "sku": "X2", "qty": 1, "gift": true }
]
}
becomes these TypeScript interfaces with Types only checked:
export interface Customer {
id: number;
name: string;
email: null;
tags: string[];
orders: Order[];
}
export interface Order {
sku: string;
qty: number;
gift?: boolean;
}
Two details show the inference at work. gift is optional because only one of the two orders carries it. email is typed null because the sample never shows another value; a second sample with a string there would widen it to null | string.
What inference decides
Every rule below is a judgement about the sample, and each one has a toggle under Inference.
- Enums. A string property that repeats a small set of values across many objects becomes an enum (or a union of literals in TypeScript). With few objects the set is too small to trust, and the property stays a plain string.
- Dates. Strings in ISO 8601 form become the language’s date type:
Datein TypeScript,DateTimeOffsetin C#,OffsetDateTimein Java. - Integer strings. A string holding only digits, such as a postal code, becomes an integer. This is the rule most worth turning off:
"zip": "75001"is a string in every real system. - Maps. An object whose values all share one type and whose keys look like data rather than field names becomes a map type (
Record<string, T>,map[string]T) instead of a class with hundreds of properties. - All properties optional. Marks every property optional regardless of the sample, for when the sample is one record and the real API omits fields freely.
Numbers are typed by what the sample contains. A property that is 1 in every object comes out as an integer type (int64, Long, number in TypeScript); one 1.5 anywhere widens it to a floating type. Mixed arrays become unions where the language has them and a loose any-style type where it does not.
Options per language
The row of controls changes with the language. Booleans are checkboxes; choices are selects; the one free-text field a language needs (Go package, C# namespace, Java and Kotlin package, Swift type prefix) is a text input. Edited options are written to the URL, so a configured generator can be shared or bookmarked.
Types only, available in most languages, strips the parsing helpers and leaves bare declarations. Leave it off when the target has no built-in JSON support for the generated shape (Go, Rust, and Swift do; TypeScript needs the Convert class to validate at runtime).
JSON Schema input
A pasted document with a top-level $schema key is read as a schema rather than a sample. Property types, required, enum, $defs, and local $ref pointers all carry into the output, and the result is often tighter than sample inference because the schema says what is optional instead of leaving it to be guessed. Remote references are not fetched. The sibling JSON Schema Generator goes the other way, from a sample to a schema.
Limits
Names come from keys. A property called data produces a type called Data, and two unrelated objects under the same key name collide into one merged type. Rename the keys in the sample or split the sample when that happens.
Inference knows structure, not meaning. It cannot tell an id from a count, or a string that happens to parse as a date from a date, which is why the Inference toggles exist.
One sample is one sample. If the API sometimes returns a field the sample lacks, the type lacks it too. Paste a larger or more varied sample, or switch to a schema.