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)
HTTP POST Request Method
The Hypertext Transfer Protocol (HTTP) works as a request-response protocol between a client and server. Here’s an example:
- The ESP32 (client) submits an HTTP request to a Server (for example: ThingSpeak or IFTTT.com);
- The server returns a response to the ESP32 (client);
- Finally, the response contains status information about the request and may also contain the requested content.
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 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.)
Prerequisites
Before proceeding with this tutorial, make sure you complete the following prerequisites.
Arduino IDE
We’ll program the ESP32 using Arduino IDE, so make sure you have the ESP32 add-on installed.
Other Web Services or APIs
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.
1. ESP32 HTTP POST Data (ThingSpeak)
In this example, the ESP32 makes an HTTP POST request to send a new value to ThingSpeak.
Using ThingSpeak API
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:
- Go to ThingSpeak.com and create a free account.
- Then, open the Channels tab.
- Create a New Channel.
- Open your newly created channel and select the API Keys tab to copy your Write API Key.
Code ESP32 HTTP POST ThingSpeak
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();
}
}
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 API Key
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.
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/json
Then, 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.
2. ESP32 HTTP POST (IFTTT.com)
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.
Using IFTTT.com Webhooks API
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.
Creating an IFTTT Account
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.
Testing Your Applet
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.
Code ESP32 HTTP POST Webhooks IFTTT.com
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();
}
}
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 IFTTT.com API Key
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";
HTTP POST Request
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/json
Then, the following lines of code print the HTTP response from the server.
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
HTTP POST Demonstration
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.
Wrapping Up
In this tutorial you’ve learned how to integrate your ESP32 with web services using HTTP POST requests. You can also make HTTP GET requests with the ESP32.
If you’re using an ESP8266 board, read:
You might also like reading:
- [Course] Learn ESP32 with Arduino IDE
- ESP32/ESP8266 Send Email Notification using PHP Script
- Visualize Your Sensor Readings from Anywhere in the World
- ESP32 Relay Module Web Server
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 ESP32, you might consider enrolling in our course “Learn ESP32 with Arduino IDE“. You can also access our free ESP32 resources here.
Thank you for reading.
When I POST single whole string it’s working ok….but when I create String using += Operator it’s not POST . Server returns 200 .
Does gmail work with IFTTT? I set everything up and test in IFTTT. It doesn’t complain but I never get an email.
Hi Steve.
Yes, it works.
Double-check that you have the right event name in the URL as well as the API key.
Did you go to the documentation tab and test the applet?
Regards,
Sara
Thanks for the response Sara. Yes I’ve double checked and tested using the documentation tab. (I assume it auto-populates with the correct API key.) I get the notification that the applet ran but the email never shows up. I’ve checked spam and filters and don’t see anything wrong with my gmail account but there must be if it works for others.
Hi
Thank you for your tutorials, it has taught me so much.
I have a project that uses asysnc web server libraries for posting sensor data and controlling relays. When I tried to add Thingspeak libraries to my project, it caused a massive amount of errors and it seems that the Thingspeak libraries and the Async libraries don’t like to be used together.
Do you know of a way to add Thingspeak functionality to an Async web server project?
Sorry, I see now that this example does not use the Thingspeak libraries and might solve my problem. I will give it a try.
Can the HTTPClient be used together with an Async Web Server?
Hello, Santos’s! What’s the difference between these publicly posted tutorials and the ESP32 Full ($39) course? Thank you!
Hi.
You can learn more about our course and what’s included here: https://randomnerdtutorials.com/learn-esp32-with-arduino-ide/
Besides the content you also get unlimited future updated, access to our private forum and facebook group.
If you have any doubts about the course content, send an email using our form: https://randomnerdtutorials.com/contact/
Regards,
Sara
I tried to load this ,I keep getting an error about HTTPClient ,noticed that it expected HttpClient so I changed that but still get error. No matching function, went to github and downloaded HttpClient master, installed it as a zip in include library but still issues.Help please
Hi.
What’s the issue that you get after installing the right library?
Regards,
Sara
No matching function for the call to HttpClient also didn’t accept the const char , had to change it to char .
/*
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>
char* ssid = “NETGEAR18”;
char* password = “crispybox986”;
// Domain Name with full URL Path for HTTP POST Request
const char* serverName = “http://api.thingspeak.com/update”;
// Service API Key
String apiKey = “161866”;
// 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.print(“ESP Board MAC Address: “);
// Serial.println(WiFi.macAddress());
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){
HttpClient http; //here is where I get the error of no matching function for call to HttpClient :: HttpClient
// Your Domain name with URL path or IP address with path
http.begin(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();
}
}
Hi. I just did the example with ThingSpeak and i am getting the following message “HTTP Response code: -1”. What does it mean and how can i fix it?
Make sure your URL is http not https. if you want to use https here is github link: https://github.com/Nmbwj/Esp-Project/tree/main/POST_Https ,to secure POST. There are also GET on the github. Please take look. Thanks to randomNerd we are able to increase our potential. Caution: to replace the APIKEY to your APIKEY, Wifi ssid and Wifi password.
YOU ARE GREAT .. I LEARNED A LOT … A LOT .. A LOT FROM YOU
That’s great!
Thank you.
Regards,
Sara