ESP32 HTTP POST Request using Arduino IDE

In this tutorial, we will learn how to make HTTP POST requests with ESP32 and Arduino IDE. For demonstration, we will send HTTP POST requests to APIs like ThingSpeak and IFTTT. The ESP32 Dev board is quite powerful and also has built-in WiFi capability, which makes it an ideal choice for IoT projects. When working on IoT projects, we need to integrate a web server into our project to facilitate communication, simplify automation, or even control devices remotely. Web services and APIs are crucial in IoT projects, and we will show how we can incorporate ThingSpeak and IFTTT into our project with this tutorial.

This tutorial is adaptable to any other web service or API other than the ones discussed here. We just have to change the server’s name and parameters according to the service API documentation. 

ESP32 HTTP POST with Arduino IDE (ThingSpeak and IFTTT.com)

Prerequisites

We will program our ESP32 board in the Arduino IDE. Thus, make sure to have the latest version of the Arduino IDE. We will also require some ESP 32 plugins. If your Arduino IDE does not have the plugins installed and you are not familiar with the plugin installation process, please check this tutorial below:

Installing ESP32 library in Arduino IDE and upload code

What is HTTP POST Request?

HTTP (Hyper-Text Transfer Protocol) is a very common request-response-based protocol between a server and a client. This protocol ensures smooth communication between the server and the client. The HTTP protocol has many methods, but the two most widely used are GET and POST. HTTP is a fundamental protocol used to facilitate communication between networked systems. It plays a vital role in the World Wide Web, allowing users to access and interact with various resources across the internet.

The client, typically a web browser, sends a request to a server for a specific resource using the GET or POST method. The GET method is used to retrieve data from the server. It is commonly used when requesting a webpage or an API endpoint. The server processes the request and sends back the requested data in the response. This method is generally considered safe and idempotent, meaning it can be repeated without causing undesirable effects.

On the other hand, the POST method is used to send data to the server for processing or storage. It is commonly used when submitting forms, sending data to be saved, or performing any action that modifies resources on the server. Unlike the GET method, the POST method can have side effects and is not idempotent. It is important to handle and process POST requests with caution, ensuring proper validation and security measures are in place. With the widespread usage of the internet and web applications, understanding HTTP and its methods is crucial for developers and users alike. By utilizing the appropriate method based on the intended operation, the HTTP protocol ensures efficient and secure communication between servers and clients.

HTTP functionWorking of function
GETThe HTTP GET method requests data from a specified resource, this resource is indicated by a URL.
POSTThe HTTP POST method sends data to be processed on a specified resource on the web server.
Table 1: HTTP GET and POST methods

In this user guide, we will focus on the POST method of the HTTP protocol. We can use it to send information to the server or to update a resource. The request body of the HTTP POST protocol will include this information, but it will not show this information on the URL. This makes the HTTP POST protocol more secure in terms of security for IoT projects. For example:

POST /Updating Sensor Readings HTTP/1.1
Host: electronicshub.com
sensor_reading1=value1&sensor_reading2=value2

For learning more about HTTP GET method you can check our following tutorial: HTTP GET using ESP32 and Arduino IDE

Some Key Features of POST Requests

Here we will discuss some of the key features of HTTP POST request.

  • The HTTP POST request has no restrictions on the data length; this is due to the fact that data is submitted to the server through the body of the HTTP request.
  • This method will not cache or save our HTTP request in the browser’s history; hence, it is secure.
  • The values of the request body are not visible in the browser’s URL, which keeps the data private.
  • This method obtains input from the request body and the query string.
  • The request body can have different data types that are sent to the server.
  • The request cannot be bookmarked.

Required Components

  • ESP32 Development Board

Since this is a server-based tutorial, we won’t be requiring other components and modules in this project.

ESP32 HTTP POST Request Examples

Now, moving on to our project, we will learn how to send JSON objects and URL-encoded data from our ESP32 development board to the following APIs:

  1. ThingSpeak
  2. IFTTT

Working Process

This project works in a three-step process: These steps are listed here to understand the complete working:

  1. At first, the client (ESP32) will submit an HTTP request to the server (ThingSpeak or IFTTT).
  2. Then, after receiving the request, the server will return a response to the client.
  3. On the last step, the ESP32 will receive a response that will contain the status information and the requested content from the server.
ESP32 HTTP POST project overview
Working Process of communication between server and client

ESP32 HTTP POST Request to ThingSpeak API

In this section, we will look at how to send HTTP POST data using ESP32 to the ThingSpeak API. ThingSpeak is an open-source API that stores or retrieves data using the HTTP or MQTT protocols. This takes place over the Internet or through a LAN connection. We will use this API to publish random values for simplicity’s sake.

For practicality, the same procedure can be used to publish sensor values, e.g., data readings from the BME280 temperature sensor integrated with the ESP32 board. Our ESP32 (client) will make an HTTP POST request to send different random values to the server, which is ThingSpeak in this case. We will send both types of data inside the HTTP POST request body: URL-encoded and JSON-encoded.

ESP32 HTTP POST ThingSpeak working process

Using ThingSpeak API

The ThingSpeak API is free to use, but we will have to create a MathWorks account. Follow the steps below to successfully create a MathWorks account.
1. First, open the following website using this link: https://thingspeak.com/
2. The following window will appear: Click on the ‘Get Started for Free’ button.

ESP32 HTTP POST ThingSpeak get started

3. Now ThingSpeak will redirect us to the login window. If you already have an existing MathWorks account, you can use it to log in. Otherwise, follow the tutorial to create a new one. Click the Create One!’ option to make a new MathWorks account.

ESP32 HTTP POST ThingSpeak account

4. When we have successfully signed in, we will receive the following notification, click the ‘OK’ button.

ESP32 HTTP POST ThingSpeak account successful

5. Now go to the ‘New Channel’ button and click it.

ESP32 HTTP POST ThingSpeak new channel

6. After creating the channel, go to the API key tab and click it. We will now be able to access our unique API key. Save it and keep it secure, as we will need it later in the program code.

ESP32 HTTP POST ThingSpeak API KEY

ThingSpeak Example Arduino Sketch

Open the Arduino IDE and go to File > New to open a new file. Copy the code given below into that file. This code will work with any ESP32 development board. You will just have to replace the network credentials and the API key according to your configuration.

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

const char* ssid = "ENTER_YOUR_WIFI_NAME";
const char* password = "ENTER_YOUR_PASSWORD";

// Domain Name with full URL Path for HTTP POST Request
const char* server = "http://api.thingspeak.com/update";

String my_Api_key = "EnterYourApiKey";


unsigned long last_time = 0;
unsigned long timer_delay = 10000;

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

  WiFi.begin(ssid, password);
  Serial.println("Connecting to WIFI…");
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());
 
  Serial.println("After 10 seconds the first reading will be displayed");

  //initialize a random number 
  randomSeed(analogRead(23));
}

void loop() {
  //Send an HTTP POST request every 10 seconds
  if ((millis() – last_time) > timer_delay) {
 
    if(WiFi.status()== WL_CONNECTED){
      HTTPClient http;
      
   
      http.begin(server);
      
      http.addHeader("Content-Type", "application/x-www-form-urlencoded");
      // Data to send with HTTP POST
      String httpRequestData = "api_key=" + my_Api_key + "&field1=" + String(random(50));           
      // Send HTTP POST request
      int httpResponseCode = http.POST(httpRequestData);
      
      /*
      
      http.addHeader("Content-Type", "application/json");
      // JSON data to send with HTTP POST
      String httpRequestData = "{\"api_key\":\"" + my_Api_Key + "\",\"field1\":\"" + String(random(50)) + "\"}";           
      // Send HTTP POST request
      int httpResponseCode = http.POST(httpRequestData);*/
     
      Serial.print("HTTP Response code is: ");
      Serial.println(httpResponseCode);
      http.end();
    }
    else {
      Serial.println("WiFi is Disconnected!");
    }
    last_time = millis();
  }
}

How the Code Works?

Now, let us understand how each part of the code works.


Importing Libraries

In the first part, we will import the relevant libraries that are necessary for this project. We are using two libraries: WiFi.h and HTTPClient.h.
The WiFi.h library connects our ESP32 module with the local WiFi network. Also, HTTPClient.h will help us make HTTP POST requests easily.

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

Setting Network Credentials

Next, we will create two global variables to save the SSID and password of our wireless network. You have to replace both of them with your network credentials to successfully connect to your wireless router. Otherwise, the ESP32 will not be able to connect to the network and send requests to the server.

const char* ssid = "ENTER_YOUR_WIFI_NAME";
const char* password = "ENTER_YOUR_PASSWORD";

Setting Server

Also, we will create another global variable named ‘server, which will hold the URL path of the HTTP POST that we are going to use.

const char* server = "http://api.thingspeak.com/update";

Configuring the API key

Now, we will create a string variable to hold the unique API key we got from the ThingSpeak website. A quick reminder: this is the key that you saved previously after creating a new channel on the ThingSpeak website.

String my_Api_key = "EnterYourApiKey";

Setup() function

Inside the setup() function, we will open a serial connection at a baud rate of 115200.

Serial.begin(115200);

Moreover, we will connect our ESP32 board with the local network whose network credentials we already specified above using the WiFi.begin() function. After the connection is established, the IP address of the ESP32 board will be printed on the serial monitor of the Arduino IDE.

WiFi.begin(ssid, password);
  Serial.println("Connecting");
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());
 
  Serial.println("After 10 seconds the first reading will be displayed");

Here we will use the randomSeed() function to initiate a random number from a given starting point, which is known as the seed. The analogRead() function will be set to GPIO 23; this GPIO is not connected, and we will use it as a reference for the starting point.

randomSeed(analogRead(23));

Loop() function:

Inside the infinite loop() function, we will make the HTTP POST request. After every 10 seconds, the URL-encoded data will be sent from the client to the server (ESP32 to ThingSpeak).

if ((millis() – last_time) > timer_delay) {
    
    if(WiFi.status()== WL_CONNECTED){
      HTTPClient http;
      http.begin(server);

The following section of code shows the URL-encoded data that is sent to the server. Inside the message body, we will send our API key and a random number between 0 and 49.

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

      String httpRequestData = "api_key=" + my_Api_key + "&field1=" + String(random(50));           

      int httpResponseCode = http.POST(httpRequestData);

If you want to send the data in JSON format, then uncomment the following block of code and comment the previous block of code.

/*    http.addHeader("Content-Type", "application/json");
      String httpRequestData = "{\"api_key\":\"" + my_Api_Key + "\",\"field1\":\"" + String(random(50)) + "\"}";           
      // Send HTTP POST request
      int httpResponseCode = http.POST(httpRequestData);
*/
Difference between URL Encoded Message and JSON Format
Example URL encoded POST:
POST /update HTTP/1.1
Host: api.thingspeak.com
api_key=api&field1=12
Content-Type: application/x-www-form-urlencoded
Example JSON POST:
POST /update HTTP/1.1
Host: api.thingspeak.com
{api_key: "api", field1: 12}
Content-Type: application/json
Displaying Response Code

The following lines of code will print the server’s response code on the serial monitor of our Arduino IDE.

Serial.print("HTTP Response code is: ");
Serial.println(httpResponseCode);

Demonstration

After we have uploaded the code to the ESP32 development board, we will press its ENABLE/RESET button.

ESP32 enable reset button
Press ENABLE Button

Now, open the serial monitor of the Arduino IDE, and we will be able to see the IP address of our ESP module. Additionally, the time delay message will also be displayed. Now, if successful client-server communication takes place, the server will send the response code 200. This code corresponds to ‘OK’ from the server, which means the connection is successful. We can view our connection status on the serial monitor.

ESP32 HTTP POST ThingSpeak serial monitor demo
Serial Monitor demo


Next, open the ThingSpeak API, and we will see that different random values are updating after 10 seconds on our dashboard.

ESP32 HTTP POST ThingSpeak dashboard demo
Random values on Dashboard

ESP32 HTTP POST Request to IFTTT API

Now, we will look at how to send HTTP POST data from ESP32 to IFTTT. In return, we will trigger the IFTTT API to send us email notifications about our data.
IFTTT means ‘If This, Then That.’ It is an open-source service that gives its users the freedom to program a response to an event according to their preferences. Here, we can create an applet. Applets are the series or chains of conditional statements formed by the combination of several app services and triggering parameters.

ESP32 HTTP POST IFTTT working process
Working Process

In this project, whenever the ESP32 makes a request to the server, the IFTTT applet will send three random values to our provided email address. In practical situations, these values can be read from a sensor such as the BME280. 
To work with this web service, you will need to follow the steps provided below to set up its proper functionality.


Creating an Account

Although the IFTTT service is a free to use service, we will have to create an account.
1. Open the following website using this link: https://ifttt.com/.
2. The following window will appear: Click on the ‘Get Started’ button.

Getting started with IFTTT 1

3. The website will redirect us to the sign-in or sign-up page shown below. We can select any one of these options (Apple, Google, or Facebook) to connect to this service. Or we can simply ‘sign up’ with our own email. We will be following this scheme.

IFTTT sign up page 2

4. Click on the ‘sign up’ tag, and you will see the following window pop up: Enter your email address and password and click the ‘Sign Up button to start working with IFTTT.

IFTTT sign up page 3

Note: This process is free only for the first 3 applets using IFTTT, and we will have to subscribe to their plan for creating more applets.

Creating an Applet:


After creating our account, the website will again redirect us to another page (see the figure below), where we will create our applet. Click on the ‘Create’ button.

IFTTT create applets 4

The following window will open up: Click on the ‘Add‘ button in the ‘If This’ section.

IFTTT create applets webhock alert 5

Another page will open where we will have to choose our service. There are a lot of options to choose from. Write down ‘webhooks’ in the search menu, and the webhooks icon will appear:

IFTTT search webhock from available services 7

Next, set the trigger to ‘Receive a web request’ by clicking on it. Now, whenever webhooks receive a web request, it will perform some action. We will define this action in ‘Then That’ section.

IFTTT webhock create an alert web request 8

After clicking the Receive a web request, the following window will open up: We will write down the event name as “sensor_readings” for the web request. You can use any other name of your choice. Now, click on the Create Trigger’ button.

ESP32 HTTP POST IFTTT event name

After the trigger is created, we are redirected to the web page where we first added the service for the ‘IF THIS’ section. Now we will click on the ‘ADD’ button for the ‘THEN THAT’ section.

IFTTT create gmail service 10

Setting up the Service

Now, IFTTT will ask us to select a service that takes place when a web request is received. We will choose this service as an email. Thus, we will type ‘email’ in the search menu and click on its icon. This is because we want to send an email whenever a POST request is received.

ESP32 HTTP POST IFTTT email service

The following window opens up: We will click on the ‘Send me an email’ button as highlighted in the red box below.

ESP32 HTTP POST IFTTT email action

Click on the ‘Connect’ button as shown in the figure below.

ESP32 HTTP POST IFTTT connect service

Next, write down the email address and click on the ‘Send Pin’ button as shown below:

ESP32 HTTP POST IFTTT connect email

After successfully entering the PIN, a new window will open up. Fill in all the entries as given below and then click on the ‘Create Action’ button.

Subject:
The event named “your_event_name_here” occurred on the Maker Webhooks service.

Body:
What: “your_event_name_here”<br>Time Stamp: OccurredAt <br> Readings: Value_1, Value_2, Value_3,

ESP32 HTTP POST IFTTT create action

After the action is successfully created, the IFTTT website will direct us to the initial web page. Click on the ‘Continue’ button to proceed.

IFTTT save settings 16

After this, click on the ‘Finish button’. Make sure to turn on the notifications when the applet is running.

ESP32 HTTP POST IFTTT review

The following message indicates that we have successfully created the applet, as shown below.

ESP32 HTTP POST IFTTT connected

Testing the Applet


Go to the Applet and select “My Services” or open a webpage with this link: https://ifttt.com/my_services. The following window will appear: Now, click on the Webhooks option.

ESP32 HTTP POST IFTTT testing webhooks

This will take us to the following web page: Click on the ‘Documentation’ button.

IFTTT testing applet 20

We will receive a key; this key secures our applet. Next, enter the details as shown in the figure below to trigger the event. We will give hypothetical values for the three variables for now. Our setup is complete; now click on the ‘Test it’ button at the end.

ESP32 HTTP POST IFTTT key

We will get a notification at the top of the web page: Event has been triggered. Now go to the email account provided during setup and check for any notifications that came from the IFTTT service. Open the message, and it will display the dummy values we have entered above.

ESP32 HTTP POST IFTTT testing email

If you also received a message with the same readings that you entered in the optional JSON body, then this means that your applet is running successfully.


IFTTT Example Arduino Sketch


We have provided a simple sketch to connect the ESP32 board with the IFTTT service. Open the Arduino IDE and go to File > New to open a new file. Copy the code given below into that file. This code will work with any ESP32 development board. You just have to replace the network credentials and server name.

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

const char* ssid = "Write_your_WIFI_name";
const char* password = "Write_your_password";

const char* server_name = "http://maker.ifttt.com/trigger/Replace_with_your_eventName/with/key/Replace_With_Your_Api_Key";

unsigned long last_time = 0;
unsigned long timer_delay = 10000;

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

  WiFi.begin(ssid, password);
  Serial.println("Connecting to WIFI…");
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());
 
  Serial.println("After 10 seconds the first set of readings will be displayed");

  // initialize a pseudorandom number 
  randomSeed(analogRead(23));
}

void loop() {
  //Send an HTTP POST request every 10 seconds
  if ((millis() – last_time) > timer_delay) {
    //Check WiFi connection status
    if(WiFi.status()== WL_CONNECTED){
      HTTPClient http;
     
      http.begin(server_name);
      
      // Specify content-type header
      http.addHeader("Content-Type", "application/x-www-form-urlencoded");
      // Data to send with HTTP POST
      String httpRequestData = "value1=" + String(random(50)) + "&value2=" + String(random(50))+ "&value3=" + String(random(50));           
      // Send HTTP POST request
      int httpResponseCode = http.POST(httpRequestData);
      
     /*
      http.addHeader("Content-Type", "application/json");

      String httpRequestData = "{\"value1\":\"" + String(random(50)) + "\",\"value2\":\"" + String(random(50)) + "\",\"value3\":\"" + String(random(50)) + "\"}";
 
      int httpResponseCode = http.POST(httpRequestData);
      */
     
      Serial.print("HTTP Response code is: ");
      Serial.println(httpResponseCode);
        
      
      http.end();
    }
    else {
      Serial.println("WiFi Disconnected");
    }
    last_time= millis();
  }
}

How the Code Works?

The code works similarly to the one we previously did for ThingSpeak.


Setting Network Credentials

Next, we will create two global variables to save the SSID and password values of the network. You have to replace both of them with your own network credentials in order to successfully connect the ESP32 to your router. Otherwise, the ESP32 will not be able to connect with the IFTTT service.

const char* ssid = "Write_your_WIFI_name";
const char* password = "Write_your_password";

Configuring API Key

After importing all the necessary libraries and configuring your network credentials, you will have to enter your server’s name. This part is a little different, and the URL path for the HTTP POST request has to be carefully given. We will create a global variable of type char and call it server_name. The server_name will hold the domain name for the POST request. You will need your event name and your API key for this. To get access to your event name and API key, go to Documentation at https://ifttt.com/maker_webhooks.

const char* server_name = "http://maker.ifttt.com/trigger/Replace_with_your_eventName/with/key/Replace_With_Your_Api_Key";

We will enter the domain name as shown above. Make sure to replace your event name and API key in the specified places. For example, our event name is sensor_readings, and our key is gkb_HtIpE-FeOWMH20obLTvUR7_fPipDyj_.
Hence, we will specify the server name as:

const char* server_name = "http://maker.ifttt.com/trigger/sensor_readings/with/key/ gkb_HtIpE-FeOWMH20obLTvUR7_fPipDyj_********";

loop() function

Inside the infinite loop() function, we will make the HTTP POST request. Every 10 seconds, the URL-encoded data will be sent to the IFTTT service.

if ((millis() – last_time) > timer_delay) {
    if(WiFi.status()== WL_CONNECTED){
      HTTPClient http;
     
      http.begin(server_name);

The following section of code shows the URL-encoded data that will be sent. Inside the message body, we will send three values with random numbers between 0 and 49. For practical purposes, these values can be replaced with proper readings from a sensor such as BME280.

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

      String httpRequestData = "value1=" + String(random(50)) + "&value2=" + String(random(50))+ "&value3=" + String(random(50));           
    
      int httpResponseCode = http.POST(httpRequestData);

If you want to send the data in JSON format, then uncomment the following block of code and comment the one above it.

/*
      http.addHeader("Content-Type", "application/json");
    
      String httpRequestData = "{\"value1\":\"" + String(random(50)) + "\",\"value2\":\"" + String(random(50)) + "\",\"value3\":\"" + String(random(50)) + "\"}";

      int httpResponseCode = http.POST(httpRequestData);
 */

Difference between URL encoded message and JSON format
Example URL encoded POST
POST /trigger/sensor_readings/with/key/gkb_HtIpE-FeOWMH20obLTvUR7_fPipDyj_******** HTTP/1.1
Host: maker.ifttt.com
value1=10&value2=13&value3=6
Content-Type: application/x-www-form-urlencoded

Example JSON POST
POST /trigger/sensor_readings/with/key/gkb_HtIpE-FeOWMH20obLTvUR7_fPipDyj_******** HTTP/1.1
Host: maker.ifttt.com
{value1: 10, value2: 13, value3: 6}
Content-Type: application/json
Displaying Response Code

The following lines of code will print the server response code on our serial monitor.

Serial.print("HTTP Response code is: ");
Serial.println(httpResponseCode);

Demonstration

After we have uploaded the code to the ESP32 development board, We will press its ENABLE or RESET button.

ESP32 enable reset button
Press ENABLE/RESET Button

Now, we will open the serial monitor of the Arduino IDE, and we will look for the IP address of the ESP module. Additionally, the time delay message will also be displayed. Now, if successful client-server communication takes place, the server will send the response code 200. This code corresponds to ‘OK’ from the server, which means the connection is successful. We can view this connection status on the serial monitor.

ESP32 HTTP POST IFTTT serial monitor demo
Serial Monitor display

Next, open your email account and refresh it. Wait for a new email from IFTTT. This email will include three random values. After every 10 seconds, a new email will be sent from the IFTTT service with a set of readings available to us in our email.

ESP32 HTTP POST IFTTT email demo
Email


Conclusion

To summarize everything we have learned in this tutorial, a list is provided below.

  • Introduction to ThingSpeak and the IFTTT API
  • How to setup ThingSpeak and the IFTTT Web service for our projects
  • How to send HTTP POST requests from our ESP32 board to commonly used web services (ThingSpeak and IFTTT)

We can easily integrate our ESP32 development board with a temperature sensor such as the BME280 to get more insightful results from these two web services.

You may also like to read our previous post on posting sensor data to IFTTT with email notifications using ESP32 and MicroPython:

Leave a Comment