
ESP32 http request example
Struggling to send HTTP GET and POST requests from your Arduino? This post gives a clear, copy-pastable solution that walks you through making GET and POST calls step by step, with annotated code you can drop straight into your ESP32 project.
This guide is written for Arduino hobbyists who want something easy to use and quick to customize. You will get compact, memorable helper functions and examples for adding headers, sending JSON payloads, and setting a secure SSL certificate. The result is reliable, easy-to-remember code that you can tweak for different APIs or sensors in minutes.
Using the ESPx library
This project makes use of the espx
library.
The espx
library for Arduino defines a set of abstractions that make the ESP32 features easily accessible with
few lines of code. Some of the features are:
- WiFi connection (
wifix
) - HTTP client (
httpx
) - JSON generator (
jsonx
) - Camera manipulation (
camx
)
Installation
Install the latest version of espx
from the Arduino Library Manager.
The code examples on this page have been tested with version 1.0.4
: if you get weird
errors about missing variables or method, double check that you have the correct version.
If the error persists, please open an issue on GitHub.
The ugly way of doing HTTP GET requests
HTTPClient http;
http.begin(HOST_NAME + PATH_NAME + "?" + queryString);
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
int httpCode = http.GET();
// httpCode will be negative on error
if (httpCode > 0) {
// file found at server
if (httpCode == HTTP_CODE_OK) {
String payload = http.getString();
Serial.println(payload);
} else {
// HTTP header has been send and Server response header has been handled
Serial.printf("[HTTP] GET... code: %d\n", httpCode);
}
} else {
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
HTTPClient http;
http.begin(HOST_NAME + PATH_NAME + "?" + queryString);
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
int httpCode = http.GET();
// httpCode will be negative on error
if (httpCode > 0) {
// file found at server
if (httpCode == HTTP_CODE_OK) {
String payload = http.getString();
Serial.println(payload);
} else {
// HTTP header has been send and Server response header has been handled
Serial.printf("[HTTP] GET... code: %d\n", httpCode);
}
} else {
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
The ESPx way of doing HTTP GET requests
The library exposes an httpx
global object that is the entrypoint for all HTTP-related tasks. To fire a request, you'll call httpx.run()
with a given number of parameters. You can configure:
- the SSL certificate (if any)
- timeouts
- headers
- body
The following block of code showcases most of them into a single GET request.
// GET request
// skips SSL cert verification
// timeout after 5 seconds
// "Accept: text/plain" header
auto response = httpx.run(
"https://icanhazdadjoke.com/",
// configurations go first
httpx.Insecure(),
httpx.RequestTimeout("5s"),
// then headers
httpx.Header("Accept", "text/plain"),
// Body() MUST be the last
// first argument is the method (GET, POST, PUT, DELETE)
httpx.Body("GET")
);
// GET request
// skips SSL cert verification
// timeout after 5 seconds
// "Accept: text/plain" header
auto response = httpx.run(
"https://icanhazdadjoke.com/",
// configurations go first
httpx.Insecure(),
httpx.RequestTimeout("5s"),
// then headers
httpx.Header("Accept", "text/plain"),
// Body() MUST be the last
// first argument is the method (GET, POST, PUT, DELETE)
httpx.Body("GET")
);
This will return a Response
object that can be used to:
- test if the request was successful (response code != 400 and 500)
- access the response body
if (!response) {
// request failed
Serial.print("Request failed with reason: ");
Serial.println(response.failure());
}
else {
// request was ok
Serial.printf("Response [%d]\n", response.code);
Serial.println(response.text());
}
if (!response) {
// request failed
Serial.print("Request failed with reason: ");
Serial.println(response.failure());
}
else {
// request was ok
Serial.printf("Response [%d]\n", response.code);
Serial.println(response.text());
}
ESPx HTTP GET request complete example
/**
* Do GET requests with httpx
*/
#include <espx.h>
#include <espx/wifix.h>
#include <espx/httpx.h>
void setup() {
delay(1000);
Serial.begin(115200);
Serial.println("Httpx example: GET request");
// connect to WiFi
wifix("SSID", "PASSWORD").raise();
}
void loop() {
// GET request
// skips SSL cert verification
// timeout after 5 seconds
// "Accept: text/plain" header
auto response = httpx.run(
"https://icanhazdadjoke.com/",
// configurations go first
httpx.Insecure(),
httpx.RequestTimeout("5s"),
// then headers
httpx.Header("Accept", "text/plain"),
// Body() MUST be the last
httpx.Body("GET")
);
if (!response) {
// request failed
Serial.print("Request failed with reason: ");
Serial.println(response.failure());
}
else {
// request was ok
Serial.printf("Response [%d]\n", response.code);
Serial.println(response.text());
}
// end connection
httpx.end();
delay(5000);
}
/**
* Do GET requests with httpx
*/
#include <espx.h>
#include <espx/wifix.h>
#include <espx/httpx.h>
void setup() {
delay(1000);
Serial.begin(115200);
Serial.println("Httpx example: GET request");
// connect to WiFi
wifix("SSID", "PASSWORD").raise();
}
void loop() {
// GET request
// skips SSL cert verification
// timeout after 5 seconds
// "Accept: text/plain" header
auto response = httpx.run(
"https://icanhazdadjoke.com/",
// configurations go first
httpx.Insecure(),
httpx.RequestTimeout("5s"),
// then headers
httpx.Header("Accept", "text/plain"),
// Body() MUST be the last
httpx.Body("GET")
);
if (!response) {
// request failed
Serial.print("Request failed with reason: ");
Serial.println(response.failure());
}
else {
// request was ok
Serial.printf("Response [%d]\n", response.code);
Serial.println(response.text());
}
// end connection
httpx.end();
delay(5000);
}
HTTP POST requests
To make a POST request, you do the exact same thing as earlier, but this time you may provide a body. The request body can either be:
- a
String
(for text content) - a
uint8_t*
(for binary content)
Also, you usually have to specify the Content-Type
of the body.
// POST request
// skips SSL cert verification
// timeout after 5 seconds
// Accept json header
// Content Type json header
// send dummy JSON body
auto response = httpx.run(
"https://httpbin.org/post",
// configurations go first
httpx.Insecure(),
httpx.RequestTimeout("5s"),
// then headers
httpx.Header("Accept", "application/json"),
httpx.Header("Content-Type", "application/json"),
// Body() MUST be the last
httpx.Body("POST", "[1, 2, 3]")
);
// POST request
// skips SSL cert verification
// timeout after 5 seconds
// Accept json header
// Content Type json header
// send dummy JSON body
auto response = httpx.run(
"https://httpbin.org/post",
// configurations go first
httpx.Insecure(),
httpx.RequestTimeout("5s"),
// then headers
httpx.Header("Accept", "application/json"),
httpx.Header("Content-Type", "application/json"),
// Body() MUST be the last
httpx.Body("POST", "[1, 2, 3]")
);
To send a binary content, replace
httpx.Body("POST", "[1, 2, 3]")
httpx.Body("POST", "[1, 2, 3]")
with
uint8_t *body = {...data...};
httpx.Body("POST", body, sizeof(body))
uint8_t *body = {...data...};
httpx.Body("POST", body, sizeof(body))
ESPx HTTP POST request to Telegram example
The following sketch leverages the httpx
object to send a text message to a Telegram bot using the Telegram API. The request part is very similar to the POST
example above, but the sketch adds a couple more details:
promptString
helper to get user inputwifix
to connect to WiFi (see Connect ESP32 to WiFi for more details)jsonx
to construct a JSON stringhttpx.Cert
to set the SSL certificate for a secure connection (as opposed tohttpx.Insecure
)
/**
* Send text to Telegram bot with httpx
*/
#include <espx.h>
#include <espx/wifix.h>
#include <espx/httpx.h>
#include <espx/jsonx.h>
static const char TELEGRAM_CERT[] PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
ReYNnyicsbkqWletNw+vHX/bvZ8=
-----END CERTIFICATE-----
)EOF";
String botToken;
void setup() {
delay(1000);
Serial.begin(115200);
Serial.println("Httpx example: send text to Telegram bot");
// connect to WiFi
wifix("SSID", "PASSWORD").raise();
// get bot token once
botToken = promptString("Enter bot token: ");
}
void loop() {
const String recipient = promptString("Enter recipient id");
const String message = promptString("Enter message");
// use jsonx to construct payload
StringIO payload;
Jsonx jsonx(payload);
jsonx.rootObject({
jsonx.scalar("chat_id", recipient.c_str()),
jsonx.scalar("text", message.c_str())
});
Serial.print("Payload: ");
Serial.println(payload.value());
// POST request
// SSL cert verification
// timeout after 5 seconds
// Accept json header
// Content Type json header
auto response = httpx.run(
String("https://api.telegram.org/bot") + botToken + "/sendMessage",
// configurations go first
httpx.Cert(TELEGRAM_CERT),
httpx.RequestTimeout("5s"),
// then headers
httpx.Header("Accept", "application/json"),
httpx.Header("Content-Type", "application/json"),
// Body() MUST be the last
httpx.Body("POST", payload.c_str())
);
if (!response) {
// request failed
Serial.print("Request failed with reason: ");
Serial.println(response.failure());
}
else {
// request was ok
Serial.printf("Response [%d]\n", response.code);
Serial.println(response.text());
}
// end connection
httpx.end();
delay(5000);
}
/**
* Send text to Telegram bot with httpx
*/
#include <espx.h>
#include <espx/wifix.h>
#include <espx/httpx.h>
#include <espx/jsonx.h>
static const char TELEGRAM_CERT[] PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
ReYNnyicsbkqWletNw+vHX/bvZ8=
-----END CERTIFICATE-----
)EOF";
String botToken;
void setup() {
delay(1000);
Serial.begin(115200);
Serial.println("Httpx example: send text to Telegram bot");
// connect to WiFi
wifix("SSID", "PASSWORD").raise();
// get bot token once
botToken = promptString("Enter bot token: ");
}
void loop() {
const String recipient = promptString("Enter recipient id");
const String message = promptString("Enter message");
// use jsonx to construct payload
StringIO payload;
Jsonx jsonx(payload);
jsonx.rootObject({
jsonx.scalar("chat_id", recipient.c_str()),
jsonx.scalar("text", message.c_str())
});
Serial.print("Payload: ");
Serial.println(payload.value());
// POST request
// SSL cert verification
// timeout after 5 seconds
// Accept json header
// Content Type json header
auto response = httpx.run(
String("https://api.telegram.org/bot") + botToken + "/sendMessage",
// configurations go first
httpx.Cert(TELEGRAM_CERT),
httpx.RequestTimeout("5s"),
// then headers
httpx.Header("Accept", "application/json"),
httpx.Header("Content-Type", "application/json"),
// Body() MUST be the last
httpx.Body("POST", payload.c_str())
);
if (!response) {
// request failed
Serial.print("Request failed with reason: ");
Serial.println(response.failure());
}
else {
// request was ok
Serial.printf("Response [%d]\n", response.code);
Serial.println(response.text());
}
// end connection
httpx.end();
delay(5000);
}