ESP32 http request example

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

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")
);

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

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

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]")
);

To send a binary content, replace

httpx.Body("POST", "[1, 2, 3]")

with

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 input
  • wifix to connect to WiFi (see Connect ESP32 to WiFi for more details)
  • jsonx to construct a JSON string
  • httpx.Cert to set the SSL certificate for a secure connection (as opposed to httpx.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);
}
Prev: ESP32 Multi - threading