Back to Learn

Course 10 min read

From JSON to a web page: how an API's answer becomes what you see

At the end of Part 2, the weather API had answered with JSON: a block of labelled values, such as a temperature of 11.6 and a weather code of 2. That's not what anyone sees on the weather page. They see "12°", "Partly cloudy" and a little sun behind a cloud. This part is about the gap between the two, because it's where a lot of product decisions quietly get made. It's also where you'll hear one of the most common words in any API conversation: parsing.

Three moves

The JSON that comes back is just text. Turning it into the page you see takes three moves, and they're the same on almost any site that uses an API.

Three moves from JSON to a web page

LikeGoods-in keying a delivery note into the stock system, field by field

Parse it

The answer arrives as text. Parsing (response.json()) turns it into structured values the code can pick out, such as data.current.temperature_2m.

LikeRewriting a supplier's codes into words your customers understand

Translate it

Raw values aren't ready for people. 11.6 becomes "12°", a date becomes "Thu" and weather code 2 becomes "Partly cloudy".

LikeA departures board: the board is built once, and the live times drop into their slots

Place it

The page's HTML already has a labelled spot for each value. The code finds each spot and writes the value in.

The browser redraws the page as each spot is filled, usually faster than you can notice. Nothing is reloaded: only the slots change.

The best comparison I know is the departures board at a train station. The board itself (the page) is built once, with a slot for each destination, time and platform. A live feed from the railway (the JSON) supplies the details, and the board's system (the code) drops each one into its slot, turning a code like "DLY" into the word "Delayed" on the way. When something changes, only that slot flips over. The board is never rebuilt, and the weather page works the same way.

Step 1: parsing

To the code, the JSON that arrives is just a long line of characters, no more useful than a sentence. Parsing is the step that reads those characters, works out the structure (which labels go with which values, what's grouped inside what) and hands back data the code can actually use.

A good comparison is goods-in at a warehouse. A delivery note arrives on paper. Someone keys it into the stock system field by field, and the system checks each value is the right kind of thing: a quantity has to be a number, a date has to be a date. Only then can anyone search it, total it or put it on a shelf.

Parsing: from text to data the code can use

What arrivesOne long line of text. To the code, it's just characters, no different from a sentence.

{"current":{"temperature_2m":11.6,"weather_code":2,"is_day":1},"daily":{"time":["2026-11-04","2026-11-05"]}}
parse

What the code getsStructured data: every value labelled, sorted into groups and given a type

  • current group
    • temperature_2m 11.6 number
    • weather_code 2 number
    • is_day 1 number
  • daily group
    • time 2 dates list of text
Types matter. 11.6 is a number the code can round. "11.6" in quotes is text that only looks like one, and rounding it goes wrong. The other types are true or false, and null, which means deliberately empty (not the same as 0).

Most of the time parsing just works, and nobody mentions it. You'll hear the word when it doesn't:

When parsing fails

LikeGoods-in opening a delivery and finding a takeaway menu instead of a delivery note. Nothing on it fits the stock system, so it's rejected at the door.

A parse error

The code expected JSON but got something else. Often it's an error page from a struggling server, which starts with <html>. The parser stops at the very first character and reports Unexpected token '<', a message developers know well.

What the weather page does

It checks the status code first, then parses inside a safety net. If either fails, you see "The weather API didn't answer" and a Try again button, never a broken page or a raw error.

When a developer says "the response didn't parse", it usually means the API sent back something other than what was agreed: an error page, an empty answer, or JSON with a typo in it. It's worth asking what the customer sees when that happens.

Steps 2 and 3: translate and place

Once the answer is parsed, the code translates each value for people and places it on the page. Here's where each value in the weather answer ends up:

Where each value ends up

In the JSONWhat the code doesOn the page
"temperature_2m": 11.6Rounds it and adds a degree sign12° the big number
"apparent_temperature": 9.2Rounds it and adds °CFeels like 9°C
"wind_speed_10m": 9.8Rounds it and adds the unit it asked forWind 10 mph
"weather_code": 2Looks it up in the legend (below) Partly cloudy
"is_day": 1Picks the day icon, not the night oneA sun, not a moon
"time": "2026-11-04T14:15"Keeps just the clock timeUpdated 14:15
"daily": { 5 days }Fills one day tile, then repeats it for each dayToday, Thu, Fri, Sat, Sun
Before the answer arrives, each spot shows a placeholder ("--" and "Loading the latest weather"). What a spot should say while it waits, or if its value never comes, is a product decision worth writing into the acceptance criteria.

From a number to a picture

Translating is where most of the product decisions hide, and one translation deserves a closer look. The API never sends a picture, or even the words "partly cloudy". It sends a number from a standard list of weather codes, and the page does the rest. Try any of the 28 codes:

The weather code is a map legend

LikeThe key on a map: the map only prints a small symbol, and the legend tells you it means "church" or "car park"

The API sends only the number. The page's lookup table matches each of the 28 codes to some words and one of twelve icons, so the same data could look completely different in another product.

This split is the same in most products. The API sends compact, raw data, and the product decides how to present it. It's also why the answer is so small (around a kilobyte here) and so quick to arrive.

One example of that split: Open-Meteo has no code for sleet, so the page treats "freezing rain" and "freezing drizzle" as sleet. That's a presentation decision, made in the product, not in the API.

The code, simplified

You don't need to read code to follow this series, but if you're curious, here are the three moves in a few lines of JavaScript:

const response = await fetch(address);       // ask, and wait for the answer
const data = await response.json();          // 1. parse: text into structured data

const temp = Math.round(data.current.temperature_2m) + "°";   // 2. translate: 11.6 into "12°"
const sky = legend[data.current.weather_code];                // 2. translate: 2 into "Partly cloudy"

document.querySelector("[data-wx-temp]").textContent = temp;  // 3. place: into its spot
document.querySelector("[data-wx-condition]").textContent = sky.label;

fetch is built into every modern browser. [data-wx-temp] is the label on the spot in the page's HTML where the temperature goes, the empty slot on the departures board.

Words you'll hear

These come up whenever a team talks about an API's data. You don't need to use them, but knowing what they mean makes the conversation much easier to follow.

Words you'll hear

Parse

Turn text into structured data the code can use.

"We couldn't parse the response."

Serialise (or stringify)

The reverse: turn data into text, so it can be sent.

"We serialise the basket and post it to the API."

Payload

The data a request or response carries: the contents, not the envelope.

"What's in the payload?"

Schema

The agreed shape of the data: which fields, which types, which are required.

"Is that field in the schema?"

Field (or key) and value

A label and the thing next to it: temperature_2m and 11.6.

"Which field holds the price?"

Data type

What kind of value it is: number, string (text), boolean (true or false), array (list) or object (group).

"It comes back as a string, not a number."

Null

Deliberately empty. Not 0, and not missing either.

"What do we show if it's null?"

Nested

Data inside data, like temperature_2m inside current.

"It's nested under current."

Mapping

Matching the API's fields to the places they go in your product, like the table above.

"Can you send me the field mapping?"

Validation

Checking the data is what you expect before using it.

"We validate it before saving."

What this means for product managers

  • Ask what happens when the answer doesn't parse. An error page instead of JSON, an empty answer, a missing field: decide what the customer sees, and test it.

  • Every translation is a decision. Rounding 11.5 up or down, mph or km/h, "Thu" or "Thursday", what counts as sleet: none of it comes from the API. Someone chooses, so make sure it's written down.

  • Design the empty states. What does each spot show while it waits, if a value is missing, or if the whole answer fails? Put it in the acceptance criteria, or the team will guess.

  • Test with awkward values. Minus temperatures, a 0, a missing field, a very long place name. Real answers will contain all of them eventually.

  • Treat the field names as a contract. The page looks for temperature_2m by name. If the provider renames it in a new version, the page shows "--" until someone updates the code, so version changes belong on the roadmap.

Part 4 moves from the data to the small print: API keys, keeping them secret, and the limits and costs that come with them.

  • APIs
  • Product Management
  • JSON

Published 05 Nov 2026 Updated 09 Nov 2026