E10. HTTP Client, JSON and Cloud APIs
Ask a free weather website for today's temperature, print the reply, then pick the temperature out of the JSON.
Learning outcomes
- Explain the difference between a web server and a web client
- Fetch data from a website and check the status code
- Read a JSON reply and find a value inside it
- Pick out one number with ArduinoJson
Parts and preparation
ESP32 DevKit, USB, Wi-Fi with internet access. Library: ArduinoJson by Benoit Blanchon. Optional for the challenge: LED + resistor on GPIO 2.
Before power: inspect wiring, confirm supply voltage and ensure all connected circuits share GND.
Libraries for this lesson
In Arduino IDE 2 open Tools → Manage Libraries…. Search by the Library Manager name and install the package by the exact author below. Similar names from other authors can use different APIs and will break the example.
| Include | Library Manager name | Author | Install note |
|---|---|---|---|
WiFi.h | WiFi | Espressif | Built into the esp32 Arduino core. |
HTTPClient.h | HTTPClient | Espressif | Built into the esp32 Arduino core. |
ArduinoJson.h | ArduinoJson | Benoit Blanchon | Install ArduinoJson by Benoit Blanchon via Library Manager. |
What you will do
Open-Meteo is a free weather website that answers in a format called JSON. It needs no account.
Sketch 1 asks for the current temperature and prints the whole reply. Sketch 2 picks the temperature number out of the reply.
Server and client
In ESP32 Lesson 09 the ESP32 was the server: your browser asked it for a page. Now the ESP32 is the client: it asks another website, just like a browser does.
Status codes
Every reply starts with a number that says how it went. Only read the reply when the code is 200.
| Code | Meaning |
|---|---|
| 200 | OK - the reply holds your data |
| 404 | Not found - check the web address |
| Below 0 (e.g. -1) | No connection - check Wi-Fi and the address |
Reading JSON
JSON is text made of names and values inside curly brackets. Here is a shortened Open-Meteo reply:
{ "latitude": 51.5, "current": { "time": "2026-10-07T09:45", "temperature_2m": 14.2 } }
The temperature sits inside current. With ArduinoJson you write the path in square brackets: doc["current"]["temperature_2m"] gives 14.2.
More on JSON: ESP32 Reference - JSON for IoT.
| You want | You write |
|---|---|
| latitude | doc["latitude"] |
| temperature_2m inside current | doc["current"]["temperature_2m"] |
Your location
The web address in the sketches asks about London (latitude 51.5, longitude -0.12). Change the two numbers to your own town - search the web for your town's latitude and longitude.
http, not https
Most websites use https, which needs extra security setup on the ESP32. Open-Meteo also answers on plain http, so this lesson can focus on JSON.
Wiring and safe build sequence
- USB only
- Wi-Fi network with internet access
- Challenge only: GPIO 2 -> 220-330 ohm -> LED -> GND
Worked sketch 1: Ask a website for the weather
Download .inoWhat this sketch is for: Upload and read the reply in Serial. Press EN (reset) to ask again.
#include <WiFi.h> // the Wi-Fi commands
#include <HTTPClient.h> // the commands for asking websites
String ssid = "YOUR_WIFI_SSID"; // your Wi-Fi network name
String password = "YOUR_WIFI_PASSWORD"; // your Wi-Fi password
// the question: current temperature at latitude 51.5, longitude -0.12 (London)
String url = "http://api.open-meteo.com/v1/forecast?latitude=51.5&longitude=-0.12¤t=temperature_2m";
void setup() { // runs once
Serial.begin(115200); // start Serial at the ESP32 speed
WiFi.begin(ssid, password); // start joining the network
Serial.print("Connecting"); // tell the user we are trying
while (WiFi.status() != WL_CONNECTED) { // repeat until we have joined
delay(500); // wait half a second
Serial.print("."); // print a dot each time
}
Serial.println(" connected"); // we are on the network
HTTPClient http; // something that can ask websites
http.begin(url); // the address to ask
int code = http.GET(); // ask, and keep the status code
Serial.print("Status code: "); // a label
Serial.println(code); // 200 means OK
Serial.println(http.getString()); // print the whole reply
http.end(); // finished with this request
}
void loop() { // nothing to repeat in this sketch
}How the code works
- http.GET() sends the question and waits for the reply.
- Look for temperature_2m inside "current" in the printed reply - sketch 2 picks it out.
Worked sketch 2: Pick out the temperature
Download .inoWhat this sketch is for: Same question, but now ArduinoJson finds the temperature in the reply. Install ArduinoJson by Benoit Blanchon first.
#include <WiFi.h> // the Wi-Fi commands
#include <HTTPClient.h> // the commands for asking websites
#include <ArduinoJson.h> // the commands for reading JSON
String ssid = "YOUR_WIFI_SSID"; // your Wi-Fi network name
String password = "YOUR_WIFI_PASSWORD"; // your Wi-Fi password
// the question: current temperature at latitude 51.5, longitude -0.12 (London)
String url = "http://api.open-meteo.com/v1/forecast?latitude=51.5&longitude=-0.12¤t=temperature_2m";
void setup() { // runs once
Serial.begin(115200); // start Serial at the ESP32 speed
WiFi.begin(ssid, password); // start joining the network
Serial.print("Connecting"); // tell the user we are trying
while (WiFi.status() != WL_CONNECTED) { // repeat until we have joined
delay(500); // wait half a second
Serial.print("."); // print a dot each time
}
Serial.println(" connected"); // we are on the network
HTTPClient http; // something that can ask websites
http.begin(url); // the address to ask
int code = http.GET(); // ask, and keep the status code
if (code == 200) { // only read the reply if it is OK
JsonDocument doc; // a place to keep the decoded JSON
deserializeJson(doc, http.getString()); // decode the reply into doc
float temperature = doc["current"]["temperature_2m"]; // find the number
Serial.print("Temperature: "); // a label
Serial.print(temperature); // the number, e.g. 14.20
Serial.println(" C"); // the unit
} else { // anything else went wrong
Serial.print("Request failed, code "); // say so
Serial.println(code); // and show the code
}
http.end(); // finished with this request
}
void loop() { // nothing to repeat in this sketch
}How the code works
- deserializeJson turns the reply text into something you can look inside.
- doc["current"]["temperature_2m"] follows the path: inside current, find temperature_2m.
- Change latitude and longitude in the url line for your own town.
Test and record evidence
Practical evidence checklist
Common faults and checks
- Status code -1 or another negative number: check Wi-Fi has internet, and the url is typed exactly.
- ArduinoJson.h not found: install ArduinoJson by Benoit Blanchon in Library Manager.
- Temperature: 0.00: the path is wrong - compare it with the JSON printed by sketch 1.
- School or office network blocks it: try a phone hotspot.
Check your understanding
Q1. In this lesson, is the ESP32 a server or a client?
Show answer
A client - it asks another website.
Q2. What status code means OK?
Show answer
200.
Q3. Why check the status code before reading the reply?
Show answer
If the request failed, there is no JSON to read.
Q4. What is JSON?
Show answer
Text made of names and values, used to send data between devices and websites.
Q5. How do you read temperature_2m inside current?
Show answer
doc["current"]["temperature_2m"].
Q6. Which library reads JSON?
Show answer
ArduinoJson by Benoit Blanchon.
Q7. Why does this lesson use http and not https?
Show answer
https needs extra security setup on the ESP32.