It happens quite often that it is necessary to invoke Rest JSON API using ESP8266. This is the case where it is necessary to call some Rest JSON API to integrate services with ESP8266.
Basically, it is necessary to develop an ESP8266 HTTPS client that handles the Rest JSON API calls. We will discover how to do it in the following parts of this tutorial. To better understand the steps to follow when invoking a Rest JSON API from an ESP8266, we will use, as an example, an HTTPS API of ClimaCell that returns the air pollution. Therefore, we will build a simple ESP8266 HTTPS client that invokes this ClimaCell’s API and parse the JSON result. Using this result, the ESP8266 manages a LEDs strip that uses colors to visualize the air quality.
Project scenario
We want that the ESP8266 invokes Web API/Rest API to send and receive data. For example, the ESP8266 has to invoke a weather service (such as ClimaCell) to get weather information. Therefore, this is a common scenario and it is useful to understand how to invoke HTTPS Rest API using ESP8266
Steps to call an HTTPS Rest JSON API from ESP8266
To invoke an HTTPS Rest JSON API from ESP8266, it is necessary to follow these steps:
- Get the OAuth2 token to have access to the API
- Develop an ESP8266 HTTPS client
- Call the JSON API
- Parse the JSON result
How to get OAuth2 token
Usually, a Rest JSON API uses OAuth2 protocol to manage the authorization process. Before going further in this tutorial, you need to get your token from ClimaCell. You can create an account on ClimaCell that is free for 14-days. When you have created your account, you will get the token to use in the API invocation from ESP8266.
This tutorial assumes you already know about OAuth2, but if you are new to this protocol, you can skip all the protocol’s details and focus your attention on the token only.
Normally, the Rest JSON client needs to send this token in the HTTP header. We will see later how to do it. You can referer to the provider API documentation to know more about the API.
How to develop an HTTPS ESP8266 client
The ESP8266 Rest client will manage all the HTTPS connection details. Therefore, to accomplish this task, we will use the ESP8266 HTTP Library, so that we don’t need to implement all the ESP8266 HTTP client manually.
Connecting the ESP8266 to WiFi
Firstly, the ESP8266 has to connect to the Wifi. I just write down the code without any explanations because it is trivial:
boolean connectWifi() {
// Let us connect to WiFi
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(5000);
Serial.print(".");
}
Serial.println(".......");
Serial.println("WiFi Connected....IP Address:");
Serial.println(WiFi.localIP());
return true;
}
Code language: C++ (cpp)
where ssid
and password
depend on your WiFi.
Connecting to an HTTPS JSON API from ESP8266
While invoking an HTTP API is very simple, invoking an HTTPS API could be quite complex. Unfortunately almost the API available uses the HTTPS protocol. So what do we have to do to implement an ESP8266 Rest Client to invoke and HTTPS API? The code below shows how to do it:
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecureBearSSL.h>
const char *server = "https://api.climacell.co/v3/weather/realtime";
HTTPClient http;
void loop() {
Serial.println("Connecting to the HTTP server....");
std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
client->setInsecure();
char apiURL[1024];
Serial.println("Building URL...");
sprintf(apiURL, "%s?lat=%f&lon=%f&fields=%s", server, lat,lon, fields );
Serial.printf("API URL=%s\r\n",apiURL);
if (http.begin(*client, apiURL)) {
Serial.println("Connected");
http.addHeader("Accept", "application/json");
http.addHeader("apikey", API_KEY);
int code = http.GET();
Serial.printf("HTTP Code [%d]", code);
if (code > 0) {
if (code == HTTP_CODE_OK || code == HTTP_CODE_MOVED_PERMANENTLY) {
Serial.println("GET OK");
String payload = http.getString();
Serial.println(payload);
Serial.println("...JSON..");
}
}
else {
Serial.printf("[HTTP] GET... failed, error: %s", http.errorToString(code).c_str());
}
}
Code language: C++ (cpp)
A few things to notice in the code above:
- at lines 7 and 8 a simple trick to invoke a Rest JSON API over HTTPS without using the certificate.
- At line 11, we build the URL to invoke passing the query parameters according to the PM10 API.
- Line 16 and 17 the ESP8266 HTTPS client passes the OAuth2 token in the header using the key
apikey
- Finally, in line 18 the ESP8266 makes the HTTP request using GET
- Line 23, we get the response. This response contains the JSON data as the result of the API invocation. We will parse this payload to get the value we are looking for that represents the air quality
Recommended:
- How to use expose API using Arduino
- Internet of Things with Android and Arduino: IoT Arduino project
- ESP8266 Web Server: How to develop a HTML Web Interface
- How to use ESP8266 with Telegram
- Smart Home tutorial: ESP8266, Alexa and Amazon Echo
How to parse JSON API payload using ESP8266
Generally, once we have invoked the JSON Rest API and we have the payload as the result, we can parse the JSON to extract the data we are looking for.
If the JSON is simple, we can think to parse it manually, but I suggest to use Arduino JSON Library. This library simplifies the process of serialization and deserialization. Let us add the following line at the beginning:
#include <ArduinoJson.h>
Code language: CSS (css)
Then, it is necessary to define the size of the object that will deserialize the JSON. To do it, it is necessary to know the JSON API response. The JSON below is a payload example:
{
"lat": 40.7127281,
"lon": -74.0060152,
"pm10": {
"value": 18,
"units": "µg/m3"
},
"observation_time": {
"value": "2020-01-21T20:56:39.000Z"
}
}
Code language: JSON / JSON with Comments (json)
In the response, there are four objects and one this object has two inner values while the other one has only one value. The dimension we are looking for is:
const int jsonSize = JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(2)
+ JSON_OBJECT_SIZE(1);
Code language: JavaScript (javascript)
To parse the JSON response returned by the Rest JSON API, we need the following code:
double parseJson(String jsonDoc) {
Serial.println("Parsing JSON...");
DynamicJsonDocument doc(jsonSize);
deserializeJson(doc, jsonDoc);
float value = doc["pm10"]["value"];
return value;
}
Code language: JavaScript (javascript)
- in line 3, we define a
DynamicJsonDocument
having the size of the value we have calculated in the step before. This is the JSON parser that we use to deserialize the JSON document. - in line 5, we retrieve the value representing the PM10 concentration.
How to control LEDs using Rest JSON API
In this last step, we will use air pollution (PM10) to manage a LED strip. In this way, it is possible to visualize the air quality using colors. This step is quite easy and we have covered it several times. The schematic is shown below:

Add the following code to select the LEDs color:
#include <Adafruit_NeoPixel.h>
#define PIN D2
#define NUM_LEDS 12
// LEDs
Adafruit_NeoPixel pixelsRing(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);
void setLedColor(int range) {
switch (range) {
case 0:
pixelsRing.fill(pixelsRing.Color(0x50,0xF0,0xE6));
break;
case 1:
pixelsRing.fill(pixelsRing.Color(0x50,0xCC,0xAA));
break;
case 2:
pixelsRing.fill(pixelsRing.Color(0xF0,0xE6,0x41));
break;
case 3:
pixelsRing.fill(pixelsRing.Color(0xFA,0x50,0x50));
break;
case 4:
pixelsRing.fill(pixelsRing.Color(0x96,0x00,0x32));
break;
}
pixelsRing.show();
}
void loop() {
......
if (http.begin(*client, apiURL)) {
Serial.println("Connected");
http.addHeader("Accept", "application/json");
http.addHeader("apikey", API_KEY);
int code = http.GET();
Serial.printf("HTTP Code [%d]", code);
if (code > 0) {
if (code == HTTP_CODE_OK || code == HTTP_CODE_MOVED_PERMANENTLY) {
Serial.println("GET OK");
String payload = http.getString();
Serial.println(payload);
Serial.println("...JSON..");
double value = parseJson(payload);
Serial.printf("PM10 Value [%f]\r\n", value);
if (value < 20)
setLedColor(0);
else if (value >= 20 && value < 35)
setLedColor(1);
else if (value >= 35 && value < 50)
setLedColor(2);
else if (value >= 50 && value < 100)
setLedColor(3);
else if (value >= 100)
setLedColor(4);
}
}
else {
Serial.printf("[HTTP] GET... failed, error: %s", http.errorToString(code).c_str());
}
}
http.end();
delay(60 * 1000);
}
Code language: PHP (php)
Wrapping up….
Finally, at the end of this tutorial, you learned how to develop an ESP8266 Rest Client to invoke a Rest JSON API. This is very useful because it happens quite often we want to integrate an external service that provides a set of API. There are other ways we can use to integrate ESP8266 with external systems. Another interesting way is using MQTT protocol with ESP8266 to publish and subscribe to MQTT channels where data is sent and received.
Through this tutorial, we have explored all the steps we have to follow to call a JSON API.
Goodmorning Francesco:
Quite a nice post. I am experimenting with the ESP8266. I faced the problem, this device is going to loose the connection to the WLAN. Have you faced this as well?
Sincerely yours Andreas
Hi Andreas,
well I tested the connection for one day and I didn’t have this problem. It didn’t happen this problem to me. Are you sure it isn’t a problem with your router? Let me know
Thanks for this article. It’s just what I was searching for. I am always interested in this subject. Will bookmark it. Definitely a great post. Hats off to you! The information that you have provided is very helpful.
danke