ESP32: HTTP POST Requests

The objective of this tutorial is to explain how to make HTTP POST requests using the ESP32 and the Arduino environment support. We will use the HTTPClient.h library to hide the low level implementation details.

Introduction

The objective of this tutorial is to explain how to make HTTP POST requests using the ESP32 and the Arduino environment support. We will use the HTTPClient.h library to hide the low level implementation details.

So, we don’t need to worry about building the HTTP protocol on top of a socket connection, since we will have methods available to deal with that. For sending HTTP GET requests with the same library, please check this previous tutorial.

Important: At the time of writing this tutorial, the HTTPClient.h library had just been merged to the ESP32 libraries for the Arduino environment. So, you will most likely need to update to for the latest code available. Check here how to do it.

If you prefer a video version of this tutorial, please check below.

The code

The initial portion of the code will be the same needed for the HTTP GET requests with the ESP32. So, we will start by including the libraries needed, declaring some global variables to hold the WiFi network credentials and, in the Arduino setup function, connect to the WiFi network. If you need a detailed guide on how to connect to a WiFi network with the ESP32, please check this previous tutorial.

Important: At the time of writing, there was the need for making a small delay before calling the WiFi.begin function, for connecting to the WiFi network. Before updating the ESP32 libraries, this delay was not needed. Nevertheless, this may eventually not be needed anymore when you test the code, so you can play with this delay and check if the ESP32 can connect to the WiFi network without it. You may also need to increase it if you experience problems with the connection.

#include <WiFi.h>
#include <HTTPClient.h>

const char* ssid = "yourNetworkName";
const char* password =  "yourNetworkPassword";

void setup() {

  Serial.begin(115200);
  delay(4000);   //Delay needed before calling the WiFi.begin

  WiFi.begin(ssid, password); 

  while (WiFi.status() != WL_CONNECTED) { //Check for the connection
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }

  Serial.println("Connected to the WiFi network");

}

After the initialization code, we will go for the main loop, where we will write the code needed for making the HTTP POST requests. We will declare an object of class HTTPClient, which makes available the methods needed for handling the HTTP protocol.

Then, we call the begin method on the previously declared object and pass as input the URL for the website where we want to make the POST request. We will use a fake online REST API website, suitable for testing. You can check it here.

HTTPClient http;

http.begin("http://jsonplaceholder.typicode.com/posts"); //Specify destination for HTTP request

After that, we will call the addHeader method, which will allow us to specify the HTTP request headers. In this case, we will define the content-type header, which specifies the media type of the body of the request [1] we will send. We will specify it as “text/plain“, since we are only going to send a simple textual message, without any particular format.

As can be sen bellow, this method receives as first input the header we want to specify, and as second input its value.

http.addHeader("Content-Type", "text/plain"); //Specify content-type header

Now, to send the actual HTTP request, we call the POST method, passing as input the body content of the request. We will send a simple message just for illustration purposes. Since we are contacting a fake API, it will always accept out content.

This method will return the HTTP response code, which we will store in a variable. Note that if the value returned is lesser that zero, then an error occurred on the connection. If it is greater than zero, then it’s a standard HTTP code.

int httpResponseCode = http.POST("POSTING from ESP32"); //Send the actual POST request

Since we stored the HTTP response code, we will use it for error handling, as we will see the code bellow. If our request was successfully sent, we will get the HTTP answer by calling the getString method. Then, we will print the answer and the HTTP code. In case of error, we will print a informative message.

if(httpResponseCode>0){
 
    String response = http.getString();  //Get the response to the request
 
    Serial.println(httpResponseCode);   //Print return code
    Serial.println(response);           //Print request answer
 
}else{
 
    Serial.print("Error on sending POST: ");
    Serial.println(httpResponseCode);
 
}

Finally, we will call the end method on our http object to free the resources. This call is important and mustn’t be forgotten. Check the full source code bellow, which already includes this call. It also includes a delay between each request, and a conditional block to check if we are still connected to the WiFi network before sending a request.

#include <WiFi.h>
#include <HTTPClient.h>
 
const char* ssid = "yourNetworkName";
const char* password =  "yourNetworkPassword";
 
void setup() {
 
  Serial.begin(115200);
  delay(4000);   //Delay needed before calling the WiFi.begin
 
  WiFi.begin(ssid, password); 
 
  while (WiFi.status() != WL_CONNECTED) { //Check for the connection
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }
 
  Serial.println("Connected to the WiFi network");
 
}
 
void loop() {
 
 if(WiFi.status()== WL_CONNECTED){   //Check WiFi connection status
 
   HTTPClient http;   
 
   http.begin("http://jsonplaceholder.typicode.com/posts");  //Specify destination for HTTP request
   http.addHeader("Content-Type", "text/plain");             //Specify content-type header
 
   int httpResponseCode = http.POST("POSTING from ESP32");   //Send the actual POST request
 
   if(httpResponseCode>0){
 
    String response = http.getString();                       //Get the response to the request
 
    Serial.println(httpResponseCode);   //Print return code
    Serial.println(response);           //Print request answer
 
   }else{
 
    Serial.print("Error on sending POST: ");
    Serial.println(httpResponseCode);
 
   }
 
   http.end();  //Free resources
 
 }else{
 
    Serial.println("Error in WiFi connection");   
 
 }
 
  delay(10000);  //Send a request every 10 seconds
 
}

Testing the code

The procedure for testing the code is the same as usual. Just upload the code for the ESP32 using the Arduino IDE and open the serial monitor to check the output. You should get something similar to figure 1.

Output of the program to send HTTP POST Requests with the ESP32
Figure 1 – Output of the program to send HTTP POST Requests with the ESP32.

Note that a HTTP 201 code is returned, which corresponds to “created” [2]. This means a resource was created in the server, which is the expected simulated behavior since we are doing a POST.

So, the answer includes an ID, telling us the identifier of the new resource. Since this is a fake testing website, nothing is happening on the backend and this is a simulated response, so all the following POST requests will return the same ID. Also, there is no checking for the structure of the content we are sending.

Related Posts

Related Videos

References

[1] https://www.tutorialspoint.com/http/http_header_fields.htm

[2] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

84 thoughts on “ESP32: HTTP POST Requests”

  1. Hello guys!
    I’m a begginer at programming with ESP8266, Arduino IDE and C++.
    I’ve made small progress by connecting the ESP8266 to my home wifi, however I’d like to send some data to my uncle web server through a POST request and I’m not making any progress.
    I’ve already tried to send the data using the WiFiClient library and the ESP8266HTTPClient library but none of them worked. I’m starting to think that maybe the web server data that my uncle gave me are not correct.
    Here is the data he gave me:

    POST /rods/airlo/firstmodule/ HTTP/1.1

    Host: iotsystem.synology.me:314

    Content-Type: application/json

    Cache-Control: no-cache

    Postman-Token: (it’s a long code with numbers and letters but I won’t poste here for security reasons)

    The way I see there’s only two reasons why I can’t send the data: I’m not puting these data correctly in my code or he gave me wrong data.
    Can anyone help me?

    Thanks a lot!!

    1. Hi!

      How are you adding the parameters to your request?

      In principle, the HTTPClient is the simplest and cleanest way to send the requests.
      Using the WiFi client should be more error prone, since you need to basically handle all the details of HTTP yourself.

      Nonetheless, since you are not sure if the problem is on the ESP code or in the backend, my suggestion is that you test the server using the Postman app:
      https://www.getpostman.com/

      With that tool, you can easily send HTTP POST requests to your server and check if it works. If it doesn’t work with Postman, then most likely the problem is with the backend.

      Let us know if this helps 🙂

      Best regards,
      Nuno Santos

  2. Hello guys!
    I’m a begginer at programming with ESP8266, Arduino IDE and C++.
    I’ve made small progress by connecting the ESP8266 to my home wifi, however I’d like to send some data to my uncle web server through a POST request and I’m not making any progress.
    I’ve already tried to send the data using the WiFiClient library and the ESP8266HTTPClient library but none of them worked. I’m starting to think that maybe the web server data that my uncle gave me are not correct.
    Here is the data he gave me:
    POST /rods/airlo/firstmodule/ HTTP/1.1
    Host: iotsystem.synology.me:314
    Content-Type: application/json
    Cache-Control: no-cache
    Postman-Token: (it’s a long code with numbers and letters but I won’t poste here for security reasons)
    The way I see there’s only two reasons why I can’t send the data: I’m not puting these data correctly in my code or he gave me wrong data.
    Can anyone help me?
    Thanks a lot!!

    1. Hi!
      How are you adding the parameters to your request?
      In principle, the HTTPClient is the simplest and cleanest way to send the requests.
      Using the WiFi client should be more error prone, since you need to basically handle all the details of HTTP yourself.
      Nonetheless, since you are not sure if the problem is on the ESP code or in the backend, my suggestion is that you test the server using the Postman app:
      https://www.getpostman.com/
      With that tool, you can easily send HTTP POST requests to your server and check if it works. If it doesn’t work with Postman, then most likely the problem is with the backend.
      Let us know if this helps 🙂
      Best regards,
      Nuno Santos

  3. Pingback: Raspberry Pi 3 Flask: Receiving HTTP POST Request from ESP32 | techtutorialsx

  4. Pingback: Raspberry Pi 3 Flask: Receiving HTTP POST Request from ESP32 | techtutorialsx

  5. kevinform31gmailcom

    Thank you for this tutorial,

    I have tried your tutorial and it works perfectly if I doesn’t change anything.
    But when I use the URL of my NGINX web-server like this :
    http.begin(“http://82.145.56.62:151/postfile”);

    I get on my serial monitor this return :
    301

    301 Moved Permanently

    301 Moved Permanently
    nginx/1.10.3

    Would you have an idea of my issue ?
    Thank you

    1. Hi!

      You’re welcome 🙂

      Well, it’s hard to say but it can be some problem with the server.

      For example, if you try do to the same request to your server using another tool (ex: Postman), does the same happen?

      Unfortunately I’ve never worked with NGINX so I cannot help much with that part :/

      Best regards,
      Nuno Santos

  6. kevinform31gmailcom

    Thank you for this tutorial,
    I have tried your tutorial and it works perfectly if I doesn’t change anything.
    But when I use the URL of my NGINX web-server like this :
    http.begin(“http://82.145.56.62:151/postfile”);
    I get on my serial monitor this return :
    301
    301 Moved Permanently
    301 Moved Permanently
    nginx/1.10.3
    Would you have an idea of my issue ?
    Thank you

    1. Hi!
      You’re welcome 🙂
      Well, it’s hard to say but it can be some problem with the server.
      For example, if you try do to the same request to your server using another tool (ex: Postman), does the same happen?
      Unfortunately I’ve never worked with NGINX so I cannot help much with that part :/
      Best regards,
      Nuno Santos

  7. Pingback: ESP32 Arduino: HTTP PUT request – techtutorialsx

  8. Pingback: ESP32 Arduino: HTTP PUT request – techtutorialsx

  9. Pingback: ESP8266 Arduino: HTTP PUT request – techtutorialsx

  10. Pingback: ESP8266 Arduino: HTTP PUT request – techtutorialsx

Leave a Reply