In this guide, you’ll learn how to make HTTP POST requests using the ESP32 board with Arduino IDE. We’ll demonstrate how to post JSON data or URL encoded values to two web APIs (ThingSpeak and IFTTT.com).

Recommended: ESP32 HTTP GET with Arduino IDE (OpenWeatherMap.org and ThingSpeak)
The Hypertext Transfer Protocol (HTTP) works as a request-response protocol between a client and server. Here’s an example:
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 HTTP/1.1 Host: example.com api_key=api&field1=value1 Content-Type: application/x-www-form-urlencoded
In the body request, you can also send a JSON object:
POST /update HTTP/1.1
Host: example.com
{api_key: "api", field1: value1}
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.)
Before proceeding with this tutorial, make sure you complete the following prerequisites.
We’ll program the ESP32 using Arduino IDE, so make sure you have the ESP32 add-on installed.
In this guide, you’ll learn how to setup your ESP32 board to perform HTTP requests to ThingSpeak and IFTTT.com. If you prefer to learn with a local solution you can use HTTP with Node-RED. All examples presented in this guide 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.
In this example, the ESP32 makes an HTTP POST request to send a new value to ThingSpeak.

ThingSpeak has a free API that allows you to store and retrieve data using HTTP. In this tutorial, you’ll use the ThingSpeak API to publish and visualize data in charts from anywhere. As an example, we’ll publish random values, but in a real application you would use real sensor readings.
To use ThingSpeak API, you need an API key. Follow the next steps:


Copy the next sketch to your Arduino IDE:
/* Rui Santos Complete project details at Complete project details at https://RandomNerdTutorials.com/esp32-http-post-ifttt-thingspeak-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. */ #include <WiFi.h> #include <HTTPClient.h> const char* ssid = "REPLACE_WITH_YOUR_SSID"; const char* password = "REPLACE_WITH_YOUR_PASSWORD"; // Domain Name with full URL Path for HTTP POST Request const char* serverName = "http://api.thingspeak.com/update"; // Service API Key String apiKey = "REPLACE_WITH_YOUR_API_KEY"; // THE DEFAULT TIMER IS SET TO 10 SECONDS FOR TESTING PURPOSES // For a final application, check the API call limits per hour/minute to avoid getting blocked/banned unsigned long lastTime = 0; // Set timer to 10 minutes (600000) //unsigned long timerDelay = 600000; // Timer set to 10 seconds (10000) unsigned long timerDelay = 10000; 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 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading."); // Random seed is a number used to initialize a pseudorandom number generator randomSeed(analogRead(33)); } void loop() { //Send an HTTP POST request every 10 seconds 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); // Specify content-type header http.addHeader("Content-Type", "application/x-www-form-urlencoded"); // Data to send with HTTP POST String httpRequestData = "api_key=" + apiKey + "&field1=" + String(random(40)); // 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"); // JSON data to send with HTTP POST String httpRequestData = "{\"api_key\":\"" + apiKey + "\",\"field1\":\"" + String(random(40)) + "\"}"; // Send HTTP POST request int httpResponseCode = http.POST(httpRequestData);*/ Serial.print("HTTP Response code: "); Serial.println(httpResponseCode); // Free resources http.end(); } else { Serial.println("WiFi Disconnected"); } lastTime = millis(); } }
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";
Modify the apiKey variable to include your ThingSpeak API key.
String apiKey = "REPLACE_WITH_YOUR_API_KEY";
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 POST request.
In the loop() is where you make the HTTP POST request with URL encoded data every 10 seconds with random data:
// Specify content-type header http.addHeader("Content-Type", "application/x-www-form-urlencoded"); // Data to send with HTTP POST String httpRequestData = "api_key=" + apiKey + "&field1=" + String(random(40)); // Send HTTP POST request int httpResponseCode = http.POST(httpRequestData);
For example, the ESP32 makes a URL encoded request to publish a new value (30) to field1.
POST /update HTTP/1.1 Host: api.thingspeak.com api_key=api&field1=30 Content-Type: application/x-www-form-urlencoded
Or you can uncomment these next lines to make a request with JSON data (instead of URL-encoded request):
// If you need an HTTP request with a content type: application/json, use the following: http.addHeader("Content-Type", "application/json"); // JSON data to send with HTTP POST String httpRequestData = "{\"api_key\":\"" + apiKey + "\",\"field1\":\"" + String(random(40)) + "\"}"; // Send HTTP POST request int httpResponseCode = http.POST(httpRequestData);
Here’s a sample HTTP POST request with JSON data:
POST /update HTTP/1.1
Host: api.thingspeak.com
{api_key: "api", field1: 30}
Content-Type: application/jsonThen, the following lines print the server response code.
Serial.print("HTTP Response code: "); Serial.println(httpResponseCode);
In the Arduino IDE serial monitor, you should see an HTTP response code of 200 (this means that the request has succeeded).

Your ThingSpeak Dashboard should be receiving new random readings every 10 seconds.

For a final application, you might need to increase the timer or check the API call limits per hour/minute to avoid getting blocked/banned.
In this example you’ll learn how to trigger a web API to send email notifications. As an example, we’ll use the IFTTT.com API. IFTTT has has a free plan with lots of useful automations.

IFTTT stands for “If This Than That”, and it is a free web-based service to create chains of simple conditional statements called applets.

This means you can trigger an event when something happens. In this example, the applet sends three random values to your email when the ESP32 makes a request. You can replace those random values with useful sensor readings.
If you don’t have an IFTTT account, go the IFTTT website: ifttt.com and enter your email to create an account and get started. Creating an account on IFTTT is free!
Next, you need to create a new applet. Follow the next steps to create a new
applet:
1. Open the left menu and click the “Create” button.

2. Click on the “this” word. Search for the “Webhooks” service and select the Webhooks icon.

3. Choose the “Receive a web request” trigger and give a name to the event. In this case, I’ve typed “test_event”. Then, click the “Create trigger” button.
4. Click the “that” word to proceed. Now, define what happens when the event you’ve defined is triggered. Search for the “Email” service and select it.

5. Then, select Send me an email. You can leave the default options.
6. Press the “Create action” button to create your Applet. Then, click on Continue, and finally, Finish.
Before proceeding with the project, it’s important to test your Applet first. Follow the next steps to test it:
1. Search for Webhooks service or open this link: https://ifttt.com/maker_webhooks
2. Click the “Documentation” button.

A page showing your unique API key will show up.

Save your API key because you’ll need it later.
3. Fill the “To trigger an Event with 3 JSON values” section with the event name created previously, in our case test_event. Add some random values to the value1, value2, and value 3 fields. Then, click the “Test it” button.

4. The event should be successfully triggered, and you’ll get a green message saying “Event has been triggered”.
5. Go to your Email account. You should have a new email in your inbox from the IFTTT service with the values you’ve defined in the previous step.
If you’ve received an email with the data entered in the test request, it means your Applet is working as expected. Now, we need to program the ESP32 to send an HTTP POST request to the IFTTT service with the sensor readings.
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/esp32-http-post-ifttt-thingspeak-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. */ #include <WiFi.h> #include <HTTPClient.h> const char* ssid = "REPLACE_WITH_YOUR_SSID"; const char* password = "REPLACE_WITH_YOUR_PASSWORD"; // Domain Name with full URL Path for HTTP POST Request // REPLACE WITH YOUR EVENT NAME AND API KEY - open the documentation: https://ifttt.com/maker_webhooks const char* serverName = "http://maker.ifttt.com/trigger/REPLACE_WITH_YOUR_EVENT/with/key/REPLACE_WITH_YOUR_API_KEY"; // Example: //const char* serverName = "http://maker.ifttt.com/trigger/test_event/with/key/nAZjOphL3d-ZO4N3k64-1A7gTlNSrxMJdmqy3tC"; // THE DEFAULT TIMER IS SET TO 10 SECONDS FOR TESTING PURPOSES // For a final application, check the API call limits per hour/minute to avoid getting blocked/banned unsigned long lastTime = 0; // Set timer to 10 minutes (600000) //unsigned long timerDelay = 600000; // Timer set to 10 seconds (10000) unsigned long timerDelay = 10000; 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 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading."); // Random seed is a number used to initialize a pseudorandom number generator randomSeed(analogRead(33)); } void loop() { //Send an HTTP POST request every 10 seconds 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); // Specify content-type header http.addHeader("Content-Type", "application/x-www-form-urlencoded"); // Data to send with HTTP POST String httpRequestData = "value1=" + String(random(40)) + "&value2=" + String(random(40))+ "&value3=" + String(random(40)); // 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"); // JSON data to send with HTTP POST String httpRequestData = "{\"value1\":\"" + String(random(40)) + "\",\"value2\":\"" + String(random(40)) + "\",\"value3\":\"" + String(random(40)) + "\"}"; // Send HTTP POST request int httpResponseCode = http.POST(httpRequestData); */ Serial.print("HTTP Response code: "); Serial.println(httpResponseCode); // Free resources http.end(); } else { Serial.println("WiFi Disconnected"); } lastTime = millis(); } }
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";
Insert your event name and API key in the following line:
const char* serverName = "http://maker.ifttt.com/trigger/REPLACE_WITH_YOUR_EVENT/with/key/REPLACE_WITH_YOUR_API_KEY";
Example URL:
const char* serverName = "http://maker.ifttt.com/trigger/test_event/with/key/nAZjOphL3d-ZO4N3k64-1A7gTlNSrxMJdmqy3t";
In the loop() is where you make the HTTP POST request every 10 seconds with sample data:
// Specify content-type header http.addHeader("Content-Type", "application/x-www-form-urlencoded"); // Data to send with HTTP POST String httpRequestData = "value1=" + String(random(40)) + "&value2=" + String(random(40))+ "&value3=" + String(random(40)); // Send HTTP POST request int httpResponseCode = http.POST(httpRequestData);
The ESP32 makes a new URL encoded request to publish some random values in the value1, value2 and value3 fields. For example:
POST /trigger/test_event/with/key/nAZjOphL3d-ZO4N3k64-1A7gTlNSrxMJdmqy3tC HTTP/1.1 Host: maker.ifttt.com value1=15&value2=11&value3=30 Content-Type: application/x-www-form-urlencoded
Alternatively, you can uncomment these next lines to make a request with JSON data:
// If you need an HTTP request with a content type: application/json, use the following: http.addHeader("Content-Type", "application/json"); // JSON data to send with HTTP POST String httpRequestData = "{\"value1\":\"" + String(random(40)) + "\",\"value2\":\"" + String(random(40)) + "\",\"value3\":\"" + String(random(40)) + "\"}"; // Send HTTP POST request int httpResponseCode = http.POST(httpRequestData);
Here’s an example of HTTP POST request with a JSON data object.
POST /trigger/test_event/with/key/nAZjOphL3d-ZO4N3k64-1A7gTlNSrxMJdmqy3tC HTTP/1.1
Host: maker.ifttt.com
{value1: 15, value2: 11, value3: 30}
Content-Type: application/jsonThen, the following lines of code print the HTTP response from the server.
Serial.print("HTTP Response code: "); Serial.println(httpResponseCode);
After uploading the code, open the Serial Monitor and you’ll see a message printing the HTTP response code 200 indicating that the request has succeeded.

Go to your email account, and you should get a new email from IFTTT with three random values. In this case: 38, 20 and 13.

For demonstration purposes, we’re publishing new data every 10 seconds. However, for a long term project you should increase the timer or check the API call limits per hour/minute to avoid getting blocked/banned.
Copyright ©2025. All Rights Reserved Emblab THE RAVE INNOVATION