API returns "400 The plain HTTP request was sent to HTTPS port"

Hi all,

I am trying to get the price of Bitcoin from the Coinbase API and display it on a small OLED screen.

The code below returns an error message 400 telling me that "The plain HTTP request was sent to HTTPS port".
Problem is, I am using (or at least I think I am using) https to make the request.

// Initialize the OLED display using SPI
//D5 -> CLK
//D7 -> MOSI (DOUT)
//D3 -> RES
//D1 -> DC
//D8 -> CS


// Libraries
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
#include <Wire.h>
#include <SPI.h>
#include "SSD1306Spi.h"

// Create display
SSD1306Spi        display(D3, D1, D8);

// WiFi settings
const char* ssid     = "SSID";
const char* password = "PASSWORD";

// API server
const char* host = "api.coinbase.com";

void setup() {

  // Serial
  Serial.begin(115200);
  delay(10);

   // Initialize display
  display.init();
  display.flipScreenVertically();
  display.clear();
  display.display();

  // We start by connecting to a WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {

  // Connect to API
  Serial.print("connecting to ");
  Serial.println(host);
  
  // Use WiFiClient class to create TCP connections, port 80 for http and port 443 for https
  WiFiClient client;
  const int httpPort = 80;
  const int httpsPort = 443;
  if (!client.connect(host, httpsPort)) {
    Serial.println("connection failed");
    return;
  }
  
  // We now create a URI for the request
  String url = "/v2/prices/spot?currency=USD";
  
  Serial.print("Requesting URL: ");
  Serial.println(url);
  
  // This will send the request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" + 
               "Connection: close\r\n\r\n");
  delay(100);
  
  // Read all the lines of the reply from server and print them to Serial
  String answer;
  while(client.available()){
    String line = client.readStringUntil('\r');
    answer += line;
  }

  client.stop();
  Serial.println();
  Serial.println("closing connection");

  // Process answer
  Serial.println();
  Serial.println("Answer: ");
  Serial.println(answer);

  // Convert to JSON
  String jsonAnswer;
  int jsonIndex;

  for (int i = 0; i < answer.length(); i++) {
    if (answer[i] == '{') {
      jsonIndex = i;
      break;
    }
  }

  // Get JSON data
  jsonAnswer = answer.substring(jsonIndex);
  Serial.println();
  Serial.println("JSON answer: ");
  Serial.println(jsonAnswer);
  jsonAnswer.trim();

  // Get rate as float.
  int rateIndex = jsonAnswer.indexOf("rate_float");
  String priceString = jsonAnswer.substring(rateIndex + 51, rateIndex + 56);
  priceString.trim();
  float price = priceString.toFloat();

  // Print price
  Serial.println();
  Serial.println("Bitcoin price: ");
  Serial.println(price);

  // Display on OLED
  display.clear();
  display.setFont(ArialMT_Plain_24);
  display.drawString(22, 11, priceString);
  display.display();

  // Wait 10 seconds
  delay(10000);
}

The code was initially taken from Marco Schwartz's project here, (where the price is taken by Coindesk API) and works perfectly, but after altering it to collect the price data from Coinbase instead, I receive the error message about the HTTP request.

I am using a Wemos D1 Mini with an OLED SPI SSD1306.

I have a feeling this is a simple thing to fix but I can't figure it out.

Any ideas what I'm doing wrong?

WiFiClient does not do HTTPS, use WiFiClientSecure instead.

1 Like

Thank you very much oqibidipo, that worked great!