ESP8266 NodeMCU HTTP GET and HTTP POST with Arduino IDE (JSON, URL Encoded, Text)

In this guide, you’ll learn how to make HTTP GET and HTTP POST requests with the ESP8266 NodeMCU board with Arduino IDE. We’ll cover examples on how to get values, post JSON objects, URL encoded requests, and more.

ESP8266 NodeMCU HTTP GET and HTTP POST with Arduino IDE JSON URL Encoded Text

Recommended: ESP32 HTTP GET and HTTP POST with Arduino IDE (JSON, URL Encoded, Text)

HTTP Request Methods: GET vs POST

The Hypertext Transfer Protocol (HTTP) works as a request-response protocol between a client and server. Here’s an example:

  • The ESP8266 (client) submits an HTTP request to a Raspberry Pi running Node-RED (server);
  • The server returns a response to the ESP8266 (client);
  • Finally, the response contains status information about the request and may also contain the requested content.

HTTP GET

GET is used to request data from a specified resource. It is often used to get values from APIs.

For example, you can have:

GET /update-sensor?temperature=value1

Note that the query string (name = temperature and value = value1) is sent in the URL of the HTTP GET request.

Or you can use a simple request to return a value or JSON object, for example:

GET /get-sensor

(With HTTP GET, data is visible to everyone in the URL request.)

HTTP POST

POST is used to send data to a server to create/update a resource. For example, publish sensor readings to a server.

The data sent to the server with POST is stored in the request body of the HTTP request:

POST /update-sensor HTTP/1.1
Host: example.com
api_key=api&sensor_name=name&temperature=value1&humidity=value2&pressure=value3
Content-Type: application/x-www-form-urlencoded

In the body request, you can also send a JSON object:

POST /update-sensor HTTP/1.1
Host: example.com
{api_key: "api", sensor_name: "name", temperature: value1, humidity: value2, pressure: value3}
Content-Type: application/json

(With HTTP POST, data is not visible in the URL request. However, if it’s not encrypted, it’s still visible in the request body.)

HTTP GET/POST with ESP8266

In this guide, we’ll explore the following scenarios:

  1. ESP8266 HTTP GET: Value or Query in URL
  2. ESP8266 HTTP GET: JSON Data Object or Plain Text
  3. ESP8266 HTTP POST: URL Encoded, JSON Data Object, Plain Text

Prerequisites

Before proceeding with this tutorial, make sure you complete the following prerequisites.

Arduino IDE

We’ll program the ESP8266 NodeMCU board using Arduino IDE, so make sure you have the ESP8266 add-on installed.

Arduino_JSON Library

You also need to install the Arduino_JSON library. You can install this library in the Arduino IDE Library Manager. Just go to Sketch Include Library > Manage Libraries and search for the library name as follows:

Install Arduino JSON library Arduino IDE

Parts Required

For this tutorial you need the following parts:

You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!

Preparing Node-RED (optional)

As an example, we’ll create a web service with a Raspberry Pi and Node-RED to act as a web service (like an API). Basically, you’ll make HTTP GET and HTTP POST requests to your Raspberry Pi to get values or update them. You can use any other web service.

If you don’t have Node-RED installed, follow the next tutorials:

Having Node-RED running on your Raspberry Pi, go to your Raspberry Pi IP address followed by :1880.

http://raspberry-pi-ip-address:1880

The Node-RED interface should open. You can simply import the final flow:

Node-RED-Flow-HTTP-GET-POST-Request-Methods-ESP32-ESP8266-Arduino

Go to Menu > Import and copy the following to your Clipboard to create your Node-RED flow.

[{"id":"599740b7.efde9","type":"http response","z":"b01416d3.f69f38","name":"","statusCode":"200","headers":{},"x":420,"y":689,"wires":[]},{"id":"1618a829.76f638","type":"json","z":"b01416d3.f69f38","name":"","property":"payload","action":"obj","pretty":true,"x":410,"y":809,"wires":[["d0089cc7.d25ac"]]},{"id":"c7410fa2.1c2fa","type":"debug","z":"b01416d3.f69f38","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":850,"y":709,"wires":[]},{"id":"75a22f74.f1aba","type":"ui_text","z":"b01416d3.f69f38","group":"2b7ac01b.fc984","order":1,"width":0,"height":0,"name":"","label":"Sensor Name","format":"{{msg.payload}}","layout":"row-spread","x":860,"y":769,"wires":[]},{"id":"1c8f9093.8bc2bf","type":"ui_gauge","z":"b01416d3.f69f38","name":"","group":"2b7ac01b.fc984","order":2,"width":0,"height":0,"gtype":"gage","title":"Temperature","label":"ÂşC","format":"{{value}}","min":0,"max":"38","colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","x":850,"y":829,"wires":[]},{"id":"a5bd2706.54e108","type":"ui_gauge","z":"b01416d3.f69f38","name":"","group":"2b7ac01b.fc984","order":3,"width":0,"height":0,"gtype":"gage","title":"Humidity","label":"%","format":"{{value}}","min":0,"max":"100","colors":["#0080ff","#0062c4","#002f5e"],"seg1":"","seg2":"","x":840,"y":889,"wires":[]},{"id":"105ac2cc.7b3cfd","type":"ui_gauge","z":"b01416d3.f69f38","name":"","group":"2b7ac01b.fc984","order":4,"width":0,"height":0,"gtype":"gage","title":"Pressure","label":"hPa","format":"{{value}}","min":0,"max":"1200","colors":["#b366ff","#8000ff","#440088"],"seg1":"","seg2":"","x":840,"y":949,"wires":[]},{"id":"d0089cc7.d25ac","type":"function","z":"b01416d3.f69f38","name":"JSON or URL Encoded","func":"var msg0 = { payload: msg.payload.api_key };\nvar msg1 = { payload: msg.payload.sensor };\nvar msg2 = { payload: msg.payload.value1 };\nvar msg3 = { payload: msg.payload.value2 };\nvar msg4 = { payload: msg.payload.value3 };\n\nreturn [msg0, msg1, msg2, msg3, msg4];","outputs":5,"noerr":0,"x":610,"y":809,"wires":[["c7410fa2.1c2fa"],["75a22f74.f1aba"],["1c8f9093.8bc2bf"],["a5bd2706.54e108"],["105ac2cc.7b3cfd"]]},{"id":"5d9ab0d2.66b92","type":"http in","z":"b01416d3.f69f38","name":"","url":"update-sensor","method":"post","upload":false,"swaggerDoc":"","x":200,"y":740,"wires":[["599740b7.efde9","c7410fa2.1c2fa","1618a829.76f638"]]},{"id":"7f5cf345.63f56c","type":"http response","z":"b01416d3.f69f38","name":"","statusCode":"200","headers":{},"x":540,"y":420,"wires":[]},{"id":"6530621.95b429c","type":"http in","z":"b01416d3.f69f38","name":"","url":"/get-sensor","method":"get","upload":false,"swaggerDoc":"","x":180,"y":600,"wires":[["9471d1a0.68588"]]},{"id":"5ddc9f47.4b555","type":"http response","z":"b01416d3.f69f38","name":"","statusCode":"200","headers":{},"x":540,"y":560,"wires":[]},{"id":"9471d1a0.68588","type":"function","z":"b01416d3.f69f38","name":"","func":"msg.payload = {\"value1\":24.25, \"value2\":49.54, \"value3\":1005.14};\nreturn msg;","outputs":1,"noerr":0,"x":350,"y":600,"wires":[["5ddc9f47.4b555","13aea59.7430e5a"]]},{"id":"13aea59.7430e5a","type":"debug","z":"b01416d3.f69f38","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":550,"y":628,"wires":[]},{"id":"e71c7a7d.e7c598","type":"debug","z":"b01416d3.f69f38","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":550,"y":500,"wires":[]},{"id":"c7807102.3f433","type":"http in","z":"b01416d3.f69f38","name":"","url":"/update-sensor","method":"get","upload":false,"swaggerDoc":"","x":190,"y":460,"wires":[["60410cde.562a34"]]},{"id":"60410cde.562a34","type":"function","z":"b01416d3.f69f38","name":"","func":"msg.payload = msg.payload.temperature;\nreturn msg;","outputs":1,"noerr":0,"x":390,"y":460,"wires":[["e71c7a7d.e7c598","7f5cf345.63f56c"]]},{"id":"2b7ac01b.fc984","type":"ui_group","z":"","name":"SENSORS","tab":"99ab8dc5.f435c","disp":true,"width":"6","collapse":false},{"id":"99ab8dc5.f435c","type":"ui_tab","z":"","name":"HTTP","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

View raw code

Other Web Services or APIs

In this guide, the ESP8266 performs HTTP requests to Node-RED, but you can use these examples with other services like ThingSpeak, IFTTT.com (Web Hooks service), OpenWeatherMap.org, PHP server, etc… All examples presented in this guide will also work with other APIs.

In summary, to make this guide compatible with any service, you need to search for the service API documentation. Then, you need the server name (URL or IP address), and parameters to send in the request (URL path or request body). Finally, modify our examples to integrate with any API you want to use.

1. ESP8266 HTTP GET: Value or Query in URL

In the first example, the ESP8266 will make an HTTP GET request to update a reading in a service. This type of request could also be used to filter a value, request a value or return a JSON object.

HTTP GET ESP8266 NodeMCU Get Sensor Value Plain Text Status 200 OK

Code ESP8266 HTTP GET with Arduino IDE

After installing the necessary board add-ons and libraries, copy the following code to your Arduino IDE, but don’t upload it yet. You need to make some changes to make it work for you.

/*
  Rui Santos
  Complete project details at Complete project details at https://RandomNerdTutorials.com/esp8266-nodemcu-http-get-post-arduino/

  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  
  Code compatible with ESP8266 Boards Version 3.0.0 or above 
  (see in Tools > Boards > Boards Manager > ESP8266)
*/

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>

const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

//Your Domain name with URL path or IP address with path
String serverName = "http://192.168.1.106:1880/update-sensor";

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastTime = 0;
// Timer set to 10 minutes (600000)
//unsigned long timerDelay = 600000;
// Set timer to 5 seconds (5000)
unsigned long timerDelay = 5000;

void setup() {
  Serial.begin(115200); 

  WiFi.begin(ssid, password);
  Serial.println("Connecting");
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());
 
  Serial.println("Timer set to 5 seconds (timerDelay variable), it will take 5 seconds before publishing the first reading.");
}

void loop() {
  // Send an HTTP POST request depending on timerDelay
  if ((millis() - lastTime) > timerDelay) {
    //Check WiFi connection status
    if(WiFi.status()== WL_CONNECTED){
      WiFiClient client;
      HTTPClient http;

      String serverPath = serverName + "?temperature=24.37";
      
      // Your Domain name with URL path or IP address with path
      http.begin(client, serverPath.c_str());
  
      // If you need Node-RED/server authentication, insert user and password below
      //http.setAuthorization("REPLACE_WITH_SERVER_USERNAME", "REPLACE_WITH_SERVER_PASSWORD");
        
      // Send HTTP GET request
      int httpResponseCode = http.GET();
      
      if (httpResponseCode>0) {
        Serial.print("HTTP Response code: ");
        Serial.println(httpResponseCode);
        String payload = http.getString();
        Serial.println(payload);
      }
      else {
        Serial.print("Error code: ");
        Serial.println(httpResponseCode);
      }
      // Free resources
      http.end();
    }
    else {
      Serial.println("WiFi Disconnected");
    }
    lastTime = millis();
  }
}

View raw code

Setting your network credentials

Modify the next lines with your network credentials: SSID and password. The code is well commented on where you should make the changes.

// Replace with your network credentials
const char* ssid     = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Setting your serverName

You also need to type your domain name or Node-RED IP address, so the ESP publishes the readings to your own server.

String serverName = "http://192.168.1.106:1880/update-sensor";

Now, upload the code to your board and it should work straight away.

Read the next section, if you want to learn how to make the HTTP GET request.

HTTP GET Request

In the loop() is where you actually make the HTTP GET request every 5 seconds with sample data:

String serverPath = serverName + "?temperature=24.37";

// Your Domain name with URL path or IP address with path
http.begin(client, serverPath.c_str());

// If you need Node-RED/server authentication, insert user and password below
//http.setAuthorization("REPLACE_WITH_SERVER_USERNAME", "REPLACE_WITH_SERVER_PASSWORD");

// Send HTTP GET request
int httpResponseCode = http.GET();

Note: if Node-RED requires authentication, uncomment the following line and insert the Node-RED username and password.

// If you need Node-RED/server authentication, insert user and password below
//http.setAuthorization("REPLACE_WITH_SERVER_USERNAME", "REPLACE_WITH_SERVER_PASSWORD");

The ESP8266 makes a new request in the following URL to update the sensor field with a new temperature.

http://192.168.1.106:1880/update-sensor?temperature=24.37

Then, the following lines of code save the HTTP response from the server.

if (httpResponseCode>0) {
  Serial.print("HTTP Response code: ");
  Serial.println(httpResponseCode);
  String payload = http.getString();
  Serial.println(payload);
}
else {
  Serial.print("Error code: ");
  Serial.println(httpResponseCode);
}

Demonstration

With your board running the new sketch, open the Node-RED debug window. You’ll see that the sample values are being printed successfully (24.37).

2. ESP8266 HTTP GET: JSON Data Object or Plain Text

This next example shows how to make an HTTP GET request to get a JSON object and decode it with the ESP8266. Many APIs return data in JSON format.

HTTP GET ESP8266 NodeMCU Get Sensor JSON Data

Copy the next sketch to your Arduino IDE (type your SSID and password):

/*
  Rui Santos
  Complete project details at Complete project details at https://RandomNerdTutorials.com/esp8266-nodemcu-http-get-post-arduino/

  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  
  Code compatible with ESP8266 Boards Version 3.0.0 or above 
  (see in Tools > Boards > Boards Manager > ESP8266)
*/

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <Arduino_JSON.h>

const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

//Your Domain name with URL path or IP address with path
const char* serverName = "http://192.168.1.106:1880/get-sensor";

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastTime = 0;
// Timer set to 10 minutes (600000)
//unsigned long timerDelay = 600000;
// Set timer to 5 seconds (5000)
unsigned long timerDelay = 5000;

String sensorReadings;
float sensorReadingsArr[3];

void setup() {
  Serial.begin(115200);

  WiFi.begin(ssid, password);
  Serial.println("Connecting");
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());
 
  Serial.println("Timer set to 5 seconds (timerDelay variable), it will take 5 seconds before publishing the first reading.");
}

void loop() {
  // Send an HTTP POST request depending on timerDelay
  if ((millis() - lastTime) > timerDelay) {
    //Check WiFi connection status
    if(WiFi.status()== WL_CONNECTED){
              
      sensorReadings = httpGETRequest(serverName);
      Serial.println(sensorReadings);
      JSONVar myObject = JSON.parse(sensorReadings);
  
      // JSON.typeof(jsonVar) can be used to get the type of the var
      if (JSON.typeof(myObject) == "undefined") {
        Serial.println("Parsing input failed!");
        return;
      }
    
      Serial.print("JSON object = ");
      Serial.println(myObject);
    
      // myObject.keys() can be used to get an array of all the keys in the object
      JSONVar keys = myObject.keys();
    
      for (int i = 0; i < keys.length(); i++) {
        JSONVar value = myObject[keys[i]];
        Serial.print(keys[i]);
        Serial.print(" = ");
        Serial.println(value);
        sensorReadingsArr[i] = double(value);
      }
      Serial.print("1 = ");
      Serial.println(sensorReadingsArr[0]);
      Serial.print("2 = ");
      Serial.println(sensorReadingsArr[1]);
      Serial.print("3 = ");
      Serial.println(sensorReadingsArr[2]);
    }
    else {
      Serial.println("WiFi Disconnected");
    }
    lastTime = millis();
  }
}

String httpGETRequest(const char* serverName) {
  WiFiClient client;
  HTTPClient http;
    
  // Your IP address with path or Domain name with URL path 
  http.begin(client, serverName);
  
  // If you need Node-RED/server authentication, insert user and password below
  //http.setAuthorization("REPLACE_WITH_SERVER_USERNAME", "REPLACE_WITH_SERVER_PASSWORD");
  
  // Send HTTP POST request
  int httpResponseCode = http.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http.getString();
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  // Free resources
  http.end();

  return payload;
}

View raw code

Setting your serverName

Enter your domain name or Node-RED IP address, so the ESP requests the sensor readings that will be retrieved in a JSON object.

String serverName = "http://192.168.1.106:1880/get-sensor";

Now, upload the code to your board.

HTTP GET Request (JSON Object)

In the loop(), call the httpGETRequest() function to make the HTTP GET request:

sensorReadings = httpGETRequest(serverName);

The httpGETRequest() function makes a request to Node-RED address http://192.168.1.106:1880/get-sensor and it retrieves a string with a JSON object.

String httpGETRequest(const char* serverName) {
  WiFiClient client;
  HTTPClient http;

  // Your IP address with path or Domain name with URL path 
  http.begin(client, serverName);

  // If you need Node-RED/server authentication, insert user and password below
  //http.setAuthorization("REPLACE_WITH_SERVER_USERNAME", "REPLACE_WITH_SERVER_PASSWORD");

  // Send HTTP POST request
  int httpResponseCode = http.GET();

  String payload = "{}"; 

  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http.getString();
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  // Free resources
  http.end();

  return payload;
}

Note: if Node-RED requires authentication, uncomment the following line and insert the Node-RED username and password.

// If you need Node-RED/server authentication, insert user and password below
//http.setAuthorization("REPLACE_WITH_SERVER_USERNAME", "REPLACE_WITH_SERVER_PASSWORD");

Decoding JSON Object

To get access to the values, decode the JSON object and store all values in the sensorReadingsArr array.

JSONVar myObject = JSON.parse(sensorReadings);

// JSON.typeof(jsonVar) can be used to get the type of the var
if (JSON.typeof(myObject) == "undefined") {
  Serial.println("Parsing input failed!");
  return;
}

Serial.print("JSON object = ");
Serial.println(myObject);

// myObject.keys() can be used to get an array of all the keys in the object
JSONVar keys = myObject.keys();

for (int i = 0; i < keys.length(); i++) {
  JSONVar value = myObject[keys[i]];
  Serial.print(keys[i]);
  Serial.print(" = ");
  Serial.println(value);
  sensorReadingsArr[i] = double(value);
}
Serial.print("1 = ");
Serial.println(sensorReadingsArr[0]);
Serial.print("2 = ");
Serial.println(sensorReadingsArr[1]);
Serial.print("3 = ");
Serial.println(sensorReadingsArr[2]);

HTTP GET Demonstration

After uploading the code, open the Arduino IDE and you’ll see that it’s receiving the following JSON data:

{"value1":24.25,"value2":49.54,"value3":1005.14}

Then, you print the decoded JSON object in the Arduino IDE Serial Monitor.

For debugging purposes, the requested information is also printed in the Node-RED debug window.

3. ESP8266 HTTP POST: URL Encoded, JSON Data Object, Plain Text

Finally, you’ll learn how to make an HTTP POST request with an ESP8266.

With this example, your ESP8266 can make HTTP POST requests using three different types of body requests: URL encoded, JSON object or plain text. These are the most common methods and should integrate with most APIs or web services.

HTTP POST ESP8266 NodeMCU URL Encoded JSON Object Data Plain Text

Copy the next sketch to your Arduino IDE (type your SSID and password):

/*
  Rui Santos
  Complete project details at Complete project details at https://RandomNerdTutorials.com/esp8266-nodemcu-http-get-post-arduino/

  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  
  Code compatible with ESP8266 Boards Version 3.0.0 or above 
  (see in Tools > Boards > Boards Manager > ESP8266)
*/

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>

const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

//Your Domain name with URL path or IP address with path
const char* serverName = "http://192.168.1.106:1880/update-sensor";

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastTime = 0;
// Timer set to 10 minutes (600000)
//unsigned long timerDelay = 600000;
// Set timer to 5 seconds (5000)
unsigned long timerDelay = 5000;

void setup() {
  Serial.begin(115200);

  WiFi.begin(ssid, password);
  Serial.println("Connecting");
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());
 
  Serial.println("Timer set to 5 seconds (timerDelay variable), it will take 5 seconds before publishing the first reading.");
}

void loop() {
  //Send an HTTP POST request every 10 minutes
  if ((millis() - lastTime) > timerDelay) {
    //Check WiFi connection status
    if(WiFi.status()== WL_CONNECTED){
      WiFiClient client;
      HTTPClient http;
      
      // Your Domain name with URL path or IP address with path
      http.begin(client, serverName);
  
      // If you need Node-RED/server authentication, insert user and password below
      //http.setAuthorization("REPLACE_WITH_SERVER_USERNAME", "REPLACE_WITH_SERVER_PASSWORD");
  
      // Specify content-type header
      http.addHeader("Content-Type", "application/x-www-form-urlencoded");
      // Data to send with HTTP POST
      String httpRequestData = "api_key=tPmAT5Ab3j7F9&sensor=BME280&value1=24.25&value2=49.54&value3=1005.14";           
      // Send HTTP POST request
      int httpResponseCode = http.POST(httpRequestData);
      
      // If you need an HTTP request with a content type: application/json, use the following:
      //http.addHeader("Content-Type", "application/json");
      //int httpResponseCode = http.POST("{\"api_key\":\"tPmAT5Ab3j7F9\",\"sensor\":\"BME280\",\"value1\":\"24.25\",\"value2\":\"49.54\",\"value3\":\"1005.14\"}");

      // If you need an HTTP request with a content type: text/plain
      //http.addHeader("Content-Type", "text/plain");
      //int httpResponseCode = http.POST("Hello, World!");
     
      Serial.print("HTTP Response code: ");
      Serial.println(httpResponseCode);
        
      // Free resources
      http.end();
    }
    else {
      Serial.println("WiFi Disconnected");
    }
    lastTime = millis();
  }
}

View raw code

Setting your serverName

Enter your domain name or Node-RED IP address, so the ESP posts sample sensor readings.

String serverName = "http://192.168.1.106:1880/update-sensor";

Now, upload the code to your board.

HTTP POST URL Encoded

To make an HTTP POST request of type URL encoded, like this

POST /update-sensor HTTP/1.1
Host: 192.168.1.106:1880
api_key=tPmAT5Ab3j7F9&sensor=BME280&value1=24.25&value2=49.54&value3=1005.14
Content-Type: application/x-www-form-urlencoded

You need to run the following in your Arduino code:

// Your Domain name with URL path or IP address with path
http.begin(client, serverName);

// If you need Node-RED/server authentication, insert user and password below
//http.setAuthorization("REPLACE_WITH_SERVER_USERNAME", "REPLACE_WITH_SERVER_PASSWORD");

// Specify content-type header
http.addHeader("Content-Type", "application/x-www-form-urlencoded");

// Data to send with HTTP POST
String httpRequestData = "api_key=tPmAT5Ab3j7F9&sensor=BME280&value1=24.25&value2=49.54&value3=1005.14";

// Send HTTP POST request
int httpResponseCode = http.POST(httpRequestData);

Note: if Node-RED requires authentication, uncomment the following line and insert the Node-RED username and password.

// If you need Node-RED/server authentication, insert user and password below
//http.setAuthorization("REPLACE_WITH_SERVER_USERNAME", "REPLACE_WITH_SERVER_PASSWORD");

HTTP POST JSON Object

Or if you prefer to make an HTTP POST request with a JSON object:

POST /update-sensor HTTP/1.1
Host: example.com
{api_key: "tPmAT5Ab3j7F9", sensor_name: "BME280", temperature: 24.25; humidity: 49.54; pressure: 1005.14}
Content-Type: application/json

Use the next snippet:

http.addHeader("Content-Type", "application/json");

int httpResponseCode = http.POST("{\"api_key\":\"tPmAT5Ab3j7F9\",\"sensor\":\"BME280\",\"value1\":\"24.25\",\"value2\":\"49.54\",\"value3\":\"1005.14\"}");

HTTP Plain Text

If you want to send plain text or a value, use the following:

http.addHeader("Content-Type", "text/plain");

int httpResponseCode = http.POST("Hello, World!");

Note: the Node-RED flow we’re using (web service) is not setup to receive plain text, but if the API that you plan to integrate only accepts plain text or a value, you can use the previous snippet.

HTTP POST Demonstration

In the Node-RED debug window, you can view that your ESP is making an HTTP POST request every 5 seconds.

And in this example, those values are also sent to 3 Gauges and are displayed in Node-RED Dashboard:

http://raspberry-pi-ip-address:1880/ui

Wrapping Up

In this tutorial you’ve learned how to integrate your ESP8266 with online services using HTTP GET and HTTP POST requests.

HTTP GET and HTTP POST are commonly used in most web services and APIs. These can be useful in your projects to: publish your sensor readings to a web service like IFTTT, ThingSpeak; to an ESP8266 or Raspberry Pi web server or to your own server; to request data from the internet or from your database, and much more.

If you’re using an ESP32 board, read: Guide for ESP32 HTTP GET and HTTP Post Requests.

You might also like reading:

I hope you liked this project. If you have any questions, post a comment below and we’ll try to get back to you.

If you like ESP8266, you might consider enrolling in our eBook “Home Automation using ESP8266“. You can also access our free ESP8266 resources here.

Thank you for reading.



Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Enjoyed this project? Stay updated by subscribing our newsletter!

30 thoughts on “ESP8266 NodeMCU HTTP GET and HTTP POST with Arduino IDE (JSON, URL Encoded, Text)”

  1. what sensor are we talking about and what Ip are you talking about ? Does this have to have a node-Red. Do I have to access a web site, my own? I am sorry I usually get your stuff but this is remiss.

    Reply
    • Hello John, I apologize for the confusion.
      This guide is meant to be used with any service that supports HTTP GET or HTTP POST requests (like IFTTT.com, ThingSpeak.com, etc…).
      In this tutorial I’ve used a local installation of Node-RED in a Raspberry Pi (so, in the ServerName you should type your RPi IP address for Node-RED or modify it to work with any service that you desire).
      The “sensor” is just dummy data to be used as an example. The ESP is not reading any sensor, instead it’s sending sample values to Node-RED or to requesting them.
      Regards,
      Rui

      Reply
  2. It would be nice to see some simple examples of the web server side using php to reply to a request that works with each option.

    Reply
  3. Does anyone know how I can solve this problem?
    ‘JSONVar’ was not declared in this scope
    JSONVar myObject = JSON.parse(sensorReadings);

    Reply
  4. Hi Rui and Sara,
    Thanks for ESP8266 NodeMCU HTTP GET and HTTP POST with Arduino IDE project.

    I am getting following error when doing verify/compile with ESP8266,
    call to ‘HTTPClient::begin’ declared with attribute error: obsolete API, use ::begin(WiFiClient, url).
    On at line http.begin(serverName);

    What to do?

    Reply
  5. float sensorReadingsArr[3];
    sensorReadingsArr[i] = double(value);

    Hi, I want to ask. How if I want the data “sensorReadingsArr” only number not float? What code I should use?

    Like this maybe?
    int sensorReadingsArr[3];
    sensorReadingsArr[i] = value;

    Thank you.

    Reply
  6. hi
    I have problem with http.getstring(), I’m trying to fetch json data from php file it work’s fine but when connect esp8266 to some specific network this function get weird characters like this:
    Fr⸮99⸮⸮⸮b8h0ԑ⸮⸮⸮⸮ ⸮⸮pP⸮cgF⸮⸮m5⸮⸮g1⸮b⸮?{L⸮ӔSӚ⸮⸮n⸮d⸮⸮⸮⸮⸮⸮{0}qu⸮⸮B⸮⸮T⸮⸮<⸮⸮⸮BJ⸮⸮⸮`
    and actual data should like this:
    {“mac”:”EC:FA:BC:DD:2F:3E”,”burner1″:”0000000″,”info”:”1000010″,…}
    any idea how to solve this?
    thank you

    Reply
  7. Hello Rui and Sara,
    I’m trying to send data to my own webserver (apache2 on Raspi4). The esp connects well, but answer is 401. So I need to include username/password in my POST request. But how? Can you give me a short description or code snippet how to do this in the above script?
    Thank you.

    Reply
  8. Hi Rui! Hi Sara! Very insightful projects! Thank you very much!
    Would be possible to POST a JSON Object but connecting via 2G instead of WiFi?

    Reply
      • Guau! Thank you Sara for your answer!

        I have implemented your code with small adjustment, basically the content type to json, to my application as follows:

        client.print(String(“POST “) + resource + ” HTTP/1.1\r\n”);
        client.print(String(“Host: “) + server + “\r\n”);
        client.println(“Connection: close”);
        client.println(“Content-Type: application/json”);
        client.print(“Content-Length: “);
        client.println(httpRequestData.length());
        client.println();
        client.println(httpRequestData);

        unsigned long timeout = millis();
        while (client.connected() && millis() - timeout < 10000L) {
        // Print available data (HTTP response from server)
        while (client.available()) {
        char c = client.read();
        SerialMon.print(c);
        timeout = millis();
        }
        }
        SerialMon.println();

        // Close client and disconnect
        client.stop();
        SerialMon.println(F("Server disconnected"));

        But the response I got reading the serial shows I am basically reading what was already transmitted to the server when I was connecting via WiFi. The new data doesn’t show up at the server. Seems like I am getting info from the server instead of posting!? Can you spot some gross mistake from my side? That’s what I am reading at the serial monitor:

        Connecting to APN: giffgaff.com OK
        Connecting to xxxxxxxxxxxxxxxxxxxxxxxxxxx.net OK
        Performing HTTP POST request…
        HTTP/1.1 200 OK
        content-type: text/html; charset=utf-8
        function-execution-id: wyorn5o1ib5z
        X-Cloud-Trace-Context: 42ffe95a4800312b7be39a82c2c6a5c6;o=1
        Date: Fri, 12 Aug 2022 12:01:17 GMT
        Server: Google Frontend
        Content-Length: 9871
        Connection: close

        [{“value9”: “28.50”, “api_key”: “tPmAT5Ab3j7F9”, “value6″: ” 50.0″, “value7″: ” 19.0″, “value3”: “28.50”, “value10″: ” 0.0″, “record_created”: “2022-08-11 14:19:10.687348+00:00”, “sensor”: “Reflections”, “value2”: “-3.27397”, “value4″: ” 0.0″, “value5″: ” 39.9″, “value1”: “51.46940”, “value8”: “-3.27397”, “value11″: ” 39.9\r”, “id”: “115aa065-0471-4669-82c3-6d25f8e325bc”}, {“value9”: “28.44”, “record_created”: “2022-08-11 14:56:55.472108+00:00”, “value1”: “51.46946”, “value2”: “-3.27396”, “api_key”: “tPmAT5Ab3j7F9”, “value11″: ” 0.0\r”, “value7″: ” 19.0″, “value3”: “28.44”, “value8”: “-3.27396”, “value4″: ” 0.0″, “value6″: ” 55.0″, “sensor”: “Reflections”, “value10″: ” 0.0″, “value5″: ” 0.0″, “id”: “141f686b-36e6-48f9-b975-8596be5e7e05”}, {“value1”: “01.11”, “value5”: “555.44”, “value9”: “999.44”, “value2”: “22.22.44”, “value3”: “333.33”, “value10”: “100.44”, “value8”: “885.44”, “value11”: “……………… “value1”: “01.11”, “record_created”: “2022-07-14 23:01:15.978830+00:00”, “value6”: “665.44”, “sensor”: “Reflections”, “value10”: “100.44”, “api_key”: “tPmAT5Ab3j7F9”, “value11”: “1100.44”, “value8”: “885.44”, “value4”: “444.44”, “value5”: “555.44”, “value2”: “22.22.44”, “value7”: “765.44”, “id”: “c82e2ae0-198e-4c31-ba1b-63451aba8fbf”}, {“value9”: “999.44”, “value10”: “100.44”, “record_created”: “2022-07-14 22:
        Server disconnected
        GPRS disconnected

        Reply
  9. I just found my mistake! Your code is flawless! I mistyped the server details. I have included the path to the area where the data is stored instead of stopping where the data is received. Working well now! Tks!

    Reply
  10. This is nice, but I want to clarify something:
    “http://192.168.1.106:1880/update-sensor” is not the server name.

    192.168.1.106 is the name (in this case, already resolved as the IP address)
    http is the protocol.
    1880 is the port
    /update-sensor is the path.

    structure of a url is:
    “{protocol}://{server_name_or_ip}{path}”
    or
    “{protocol}://{server_name_or_ip}:{port}{path}”

    Reply
  11. Hell0, Im trying to use your code for retrivieing the Json file on this webpage
    elprisetjustnu.se/api/v1/prices/2023/01-22_SE3.jsonhttps://www.elprisetjustnu.se/api/v1/prices/2023/01-22_SE3.json
    but i cant get it to work. I think the problem might be that it is an https page. Any ideas?
    The data is generated from this Swedish page elprisetjustnu.se/elpris-api,
    to get a fresh data page press the green box with the text “Testa själv” sorry for the swedish page

    Reply
  12. I have used express.js as a backend server to respond to the request created by the Arduino ESP8266 ,
    here is the code for express.js: filename:”server.js”
    const express = require(‘express’);
    const app = express();

    // Serve static files
    app.use(express.static(‘public’));

    // Handle incoming HTTP requests
    app.post(‘/update-sensor’, (req, res) => {
    console.log(‘Received request:’, req.query.state);
    console.log(‘posted’);
    res.status(200).send()
    });

    app.listen(5000, () => {
    console.log(‘Server started on port 3000’);
    });

    it is hosted in ngrok with https protocol, but it throws error like this:
    ……………
    Connected to WiFi network with IP Address: 172.29.107.223
    Timer set to 5 seconds (timerDelay variable), it will take 5 seconds before publishing the first reading.
    HTTP Response code: -5
    HTTP Response code: -5
    HTTP Response code: -5
    HTTP Response code: -5
    and so on….

    Reply
  13. Hello. I have the following setup. An arduino mega conected to a ESP8266 ESP-01. I’m trying to replicate first guide but I get the the following error: ESP8266WiFi.h: No such file or directory. Can you advise me on what should I do to get it to work on my setup?

    Reply
  14. Hi
    I found this post (and some other) after looking for a solution to use an external webservice with POST, thanks to Rui for all these explainations.
    Right now I’m stuck on a slight problem. with an ESP8266 I send data (the Mac Address of the esp8266) on a POST webservice (external web site), and this site returns me a status 200 and a JSON file which contains a token related to the transaction of which here is an example generated by the web service:
    { “token”: “39387e8a-6afe-40a7-b1dc-043173689112” }
    I can’t get this value, I only get the http:200
    with this line of code :
    // HTTP request with a content type: application/json, use the following:
    https.addHeader(“Content-Type”, “application/json”);
    int httpResponseCode = https.POST(json);
    Serial.println(httpResponseCode);

    Do you have any ideas? 2 or 3 lines of code to get me started?
    Thanks a lot!

    Reply

Leave a Comment

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.