How to use JSON to Go Struct
- Paste a representative sample into JSON. For a list, paste an array with several items so the tool can see which fields are optional.
- Set the Struct name for the top-level type.
- Tick Add omitempty to every tag if empty values should be dropped when you marshal the struct.
- Tick Inline nested structs for anonymous struct types instead of separate named types.
- Keep Use pointers for nullable fields ticked to use pointer types where the sample has nulls. Copy or download
types.go.
What it does and when to use it
Before you can json.Unmarshal an API response in Go, you need structs that match it. Writing them by hand for a large payload is slow, and a single mistyped tag silently leaves a field empty. Paste one real response here and you get a starting point you can drop into your package, then adjust.
It suits webhook payloads, third-party API clients, config files and test fixtures. For the same sample in other languages, see JSON to TypeScript and JSON to Python. If the sample does not parse, fix it first with JSON repair.
How it works
The tool infers a shape from the whole sample. For an array, every item is merged, so a field missing from some items is marked optional and gets ,omitempty in its tag. Types map as follows: numbers written without a decimal point or exponent to int64 (or json.Number when they do not fit int64, with a note to import encoding/json), other numbers to float64, strings to string, booleans to bool, arrays to slices of the merged item type, and objects to their own struct, named after the key in singular form (items gives Item). Fields are aligned the way gofmt does. Nothing is sent anywhere; the code is built in your browser.
Worked examples
An order with a nested customer, a list of items and an empty list (struct name Order):
type Order struct {
OrderID string `json:"order_id"`
Total float64 `json:"total"`
Qty int64 `json:"qty"`
Paid bool `json:"paid"`
Coupon any `json:"coupon"`
Customer Customer `json:"customer"`
Items []Item `json:"items"`
Tags []any `json:"tags"`
}
type Customer struct {
ID int64 `json:"id"`
Email string `json:"email"`
}
type Item struct {
Sku string `json:"sku"`
Price float64 `json:"price"`
Gift bool `json:"gift,omitempty"`
}
Price is float64 because one item has 9.5. Gift is optional because only one item has it.
A root array of users where nick is null in one item gives type Users []User and the field Nick *string.
Limits and tips
- Integers too large for int64 are still typed
int64. Useuint64,json.Numberor a string for such IDs. anyneeds Go 1.18 or later; on older Go, replace it withinterface{}.
Frequently asked questions
Why is a field typed any?
Why is my price an int64?
When does a field get a pointer?
What do the field names look like?
How do we know nothing is uploaded? Test it yourself on the privacy proof page.