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

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

ESP8266 NodeMCU HTTP POST with Arduino IDE IFTTT ThingSpeak

Recommended: ESP8266 NodeMCU 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 ESP8266 (client) submits an HTTP request to a Server (for example: ThingSpeak or IFTTT.com);
  • 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 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 ESP8266 NodeMCU using Arduino IDE, so make sure you have the ESP8266 add-on installed.

Other Web Services or APIs

In this guide, you’ll learn how to setup your ESP8266 NodeMCU 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. ESP8266 HTTP POST Data (ThingSpeak)

In this example, the ESP8266 makes an HTTP POST request to send a new value to ThingSpeak.

HTTP POST ThingSpeak ESP8266 NodeMCU

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:

  1. Go to ThingSpeak.com and create a free account.
  2. Then, open the Channels tab.
  3. Create a New Channel.
ESP32 ESP8266 NodeMCU ThingSpeak Create New Channel
  1. Open your newly created channel and select the API Keys tab to copy your Write API Key.
ESP32 ESP8266 NodeMCU ThingSpeak View API Key Write Copy

Code ESP8266 HTTP POST ThingSpeak

Copy the next sketch to your Arduino IDE:

/*
  Rui Santos
  Complete project details at Complete project details at https://RandomNerdTutorials.com/esp8266-nodemcu-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.
  
  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";

// Domain Name with full URL Path for HTTP POST Request
const char* serverName = "http://api.thingspeak.com/update";
// Service API Key
String apiKey = "7HQJM49R8JAPR";

// 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(0));
}

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();
  }
}

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 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 ESP8266 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).

ESP32 ESP8266 NodeMCU HTTP POST Arduino IDE Serial Monitor Response

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

ESP32 ESP8266 NodeMCU HTTP GET and HTTP POST with Arduino IDE ThingSpeak Chart

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.

Note: for an easier way to send sensor readings to ThingSpeak using your ESP8266, we recommend the following tutorial:

2. ESP8266 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.

HTTP POST IFTTT ESP8266 NodeMCU

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.

IFTTT.com logo png

This means you can trigger an event when something happens. In this example, the applet sends three random values to your email when the ESP8266 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.

ifttt discover create new applet

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

Select webhooks services IFTTT.com

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. You can leave the default options.

select email service ifttt

5. Press the “Finish” button to create your Applet.

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.

webhooks documentation ifttt

A page showing your unique API key will show up.

IFTTT API key

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.

IFTTT Trigger an Event with 3 JSON values

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 ESP8266 to send an HTTP POST request to the IFTTT service with the sensor readings.

Code ESP8266 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/esp8266-nodemcu-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.
  
  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";

// 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(0));
}

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();
  }
}

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 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 ESP8266 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.

ESP32 ESP8266 NodeMCU HTTP POST Arduino IDE Serial Monitor Response

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.

ESP32 ESP8266 NodeMCU HTTP POST Arduino IDE IFTTT Response

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 ESP8266 with web services using HTTP POST requests. You can also make HTTP GET requests with the ESP8266.

If you’re using an ESP32 board, read:

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 »

Recommended Resources

Build a Home Automation System from Scratch » With Raspberry Pi, ESP8266, Arduino, and Node-RED.

Home Automation using ESP8266 eBook and video course » Build IoT and home automation projects.

Arduino Step-by-Step Projects » Build 25 Arduino projects with our course, even with no prior experience!

What to Read Next…


Enjoyed this project? Stay updated by subscribing our newsletter!

7 thoughts on “ESP8266 NodeMCU HTTP POST with Arduino IDE (ThingSpeak and IFTTT.com)”

  1. Hi Rui – great tutorial as always – Thanks!

    I have a suggestion. Many ESP8266/ESP32 tutorials require authentication credentials. I hate to place them directly in the sketches, because:
    1) I might share a sketch sometime and would have the risk of forgetting to remove the credentials.
    2) My credentials might change, thereby requiring that I update all my sketch source code rather than simply recompile.

    I suggest that your tutorials use the precedent of creating a file in the Arduino library called myLogin.h (or something like that) to contain the ssid, password, API key, or any other confidential information. Then, in each sketch requiring credentials include the following line:

    #include <MyLogin.h> // Needed to keep login credentials out of the source code

    I have used the same approach to consolidate things commonly used by numerous of my applications into a single easy to manage location. Nothing confidential in this case, but easier to maintain and prevent mistakes/overlooking yet another place that needed to be updated.

    Reply
  2. Thanks for introducing me to ThingSpeak. I got your example to work great but I am having problems when I (try to) assign my 8266 with a dedicated IP address. My intent is to have several 8266s which send dht (temp, humidity) readings to an aggregator 8266 which then uploads to ThingSpeak. I’ve actually got it all working BUT when I set up a dedicated IP address like this.

    IPAddress ip(192, 168, 10, 148);
    IPAddress gateway(192, 168, 10, 1);
    IPAddress subnet(255, 255, 255, 0);

    and WiFi.config(ip,gateway,subnet); in the setup prior to Wifi.begin(ssid,pw);

    Then it fails with an HTTP Response code of -1.

    Why does ThingSpeak care what my ip address is. Actually my guess is that it doesn’t but why doesn’t this work?

    Thanks.

    Reply
  3. Hi Rui – Hi Sara

    I have a tricky one for you (or could it be basic !)
    I run a Async Web server on an ESP8266 with several sensors
    Asynchroniously I want, on a particular event (internal trigger level or web button),
    to send a request to an other ESP,
    i.e. While I am in server mode I want to send a client request !!!!
    I fiddled with a flag to trigger a sequence in the loop … Mummm!
    some time it works ….
    some time it crash the ESP !!!!
    Any clue ?

    Thanks anyway for your slick tutorials
    RGS
    Fred

    Reply
  4. Can this example be applied to Binance Crypto Exchange? I want to make a dashboard for the prices of coin and various other features, send new order and other but they must be signed with an Akey and Skey. If possible post example. Thanks a lot.

    Reply
  5. I have implemented your solution for sending http post request to my custom webhook point in my website (not ThingSpeak or IFTTT). But it is showing response code 301. From postman.co or reqbin.com the post request can be sent successfully to my server.

    I want to send information of two variables ( ph and temperature) in the body (content type: application/json). My webhook receiving URL is: https://iot.insightsautomata.com/wp-json/gf/v2/workflow/webhooks/4/#############################

    (######################### is the api key which should be included in the URL). Should I need to send same api key in the body also?

    Please let me know if the following code is correct for sending data in body:
    http.addHeader(“Content-Type”, “application/json”);
    // JSON data to send with HTTP POST
    String httpRequestData = “{\”ph\”:\”” + String(random(40)) + “\”,\”temperature\”:\”” + String(random(40)) }”;
    // Send HTTP POST request
    int httpResponseCode = http.POST(httpRequestData);

    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.