user77843: I'm successfully sending a GET request (in the setup function, to load certificates,) but my POST request fails with a bunch of AT errors. I suspect this has to do with the way I'm formatting the POST. Any ideas would be appreciated.
Code follows:
// MKRGSM - Version: 1.5.0
#include <MKRGSM.h>
#include <ArduinoJson.h>
#include <Arduino_MKRGPS.h>

const char PINNUMBER[]     = "";
// APN data

const char GPRS_APN[]      = SECRET_GPRS_APN;

const char GPRS_LOGIN[]    = "";

const char GPRS_PASSWORD[] = "";

DynamicJsonDocument doc(1024);

// initialize the library instance

GSMSSLClient client;

GPRS gprs;

GSM gsmAccess(true);

// Specify IP address or hostname

char server[] = "webhook.site";
char path[] = "/ce480c43-95a8-4f1e-b996-bc02f6d1adaa";
int port = 443; 

void setup() {

  // initialize serial communications and wait for port to open:

  Serial.begin(9600);

  while (!Serial) {

    ; // wait for serial port to connect. Needed for native USB port only

  }

  // If you are using the MKR GPS as shield, change the next line to pass

  // the GPS_MODE_SHIELD parameter to the GPS.begin(...)
  delay(200);


  if (!GPS.begin()) {

    Serial.println("Failed to initialize GPS!");

    while (1);

  }
  Serial.println("Starting Arduino GSM ping.");
  // connection state
  bool connected = false;

  // After starting the modem with GSM.begin()
  // attach the shield to the GPRS network with the APN, login and password
  while (!connected)
  {
    if ((gsmAccess.begin(PINNUMBER) == GSM_READY) &&
        (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD) == GPRS_READY))
    {
      connected = true;
    } 
    else 
    {
      Serial.println("Not connected");
      delay(1000);
    }
  }

  Serial.println("connecting...");

  // if you get a connection, report back via serial:
  // Use this to load Root Certs the first time
  if (client.connect(server, port)) 
  // Use this to not load Root Certs anymore as done last time and stored in modem's flash
//  if (client.connect(server, port, false)) 
  {
        Serial.println("connected");

    // Make a HTTP request:

    client.print("GET ");

    client.print(path);

    client.println(" HTTP/1.1");

    client.print("Host: ");

    client.println(server);

    client.println("Connection: close");

    client.println();
  } 
  else 
  {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
}

void loop() {

  ...GPS stuff happens here

  // print GPS values

  Serial.println();

  Serial.print("Location: ");

  Serial.print(latitude, 7);

  Serial.print(", ");

  Serial.println(longitude, 7);

  Serial.print("Altitude: ");

  Serial.print(altitude);

  Serial.println("m");

  Serial.print("Number of satellites: ");

  Serial.println(satellites);

  doc["latitude"] = latitude;
  doc["longitude"] = longitude;
  doc["altitude"] = altitude;
  
  String location;
  serializeJson(doc, location);
  Serial.print("Location string: ");
  Serial.println(location);

  Serial.println();
  
  Serial.println("Starting Arduino web client.");

  // connection state
  
  if (client.available()) {
    Serial.println("Sending location");
    client.print("POST ");
    client.print(path);
    client.println(" HTTP/1.1");
    delay(5);
    client.println("Content-Type: application/json;");
    delay(5);
    client.print("Content-Length: ");
    client.println(location.length());
    client.print("Host: ");
    client.println(server);
    delay(5);
    client.println("Connection: close");
    delay(5);
    client.println();
    delay(5);
    client.println(location);
    Serial.print("Successfully sent location");

    if (!client.available() && !client.connected()) {
  
      Serial.println();
  
      Serial.println("disconnecting.");
  
      client.stop();
    }
  } else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
  
}

Here's what the output looks like:

Location: 32.1208382, 35.2468376 Altitude: 640.40m Number of
satellites: 5 Location string:
{"latitude":32.12084,"longitude":35.24684,"altitude":640.4}
Starting Arduino web client. Sending location
AT+USOWR=0,13,"504F53542068747470733A2F2F"
ERROR
AT+USOWR=0,37,"2F63653438306334332D393561382D346631652D623939362D626330326636643161646161"
ERROR AT+USOWR=0,9,"20485454502F312E31"
ERROR AT+USOWR=0,2,"0D0A"
ERROR
AT+USOWR=0,31,"436F6E74656E742D547970653A206170706C69636174696F6E2F6A736F6E3B"
ERROR AT+USOWR=0,2,"0D0A"
ERROR AT+USOWR=0,16,"436F6E74656E742D4C656E6774683A20"
ERROR AT+USOWR=0,2,"3539"
ERROR AT+USOWR=0,2,"0D0A"
ERROR AT+USOWR=0,6,"486F73743A20"
ERROR AT+USOWR=0,12,"776562686F6F6B2E73697465"
ERROR AT+USOWR=0,2,"0D0A"
ERROR AT+USOWR=0,17,"436F6E6E656374696F6E3A20636C6F7365"
ERROR AT+USOWR=0,2,"0D0A"
ERROR AT+USOWR=0,2,"0D0A"
ERROR
AT+USOWR=0,59,"7B226C61746974756465223A33322E31323038342C226C6F6E676974756465223A33352E32343638342C22616C746974756465223A3634302E347D"
ERROR AT+USOWR=0,2,"0D0A"
ERROR

I could send the data as parameters in the GET query, but that's ugly.

user77843: The problem was that GSM gsmAccess; needed to be GSM gsmAccess(true). Unfortunately, while that solves the immediate problem, which is that the client was not initializing, there are other issues which deserve a separate question.

user4143: Your HTTP request is badly formatted.  You have:
POST https://webhook.site/ce480c43-95a8-4f1e-b996-bc02f6d1adaa HTTP/1.1
Content-Type: application/json

Instead the protocol is implied by the port you are connecting to, and the domain name does not go in the path on the server component - it has its own header.
Your request should look more like:
POST /ce480c43-95a8-4f1e-b996-bc02f6d1adaa HTTP/1.1
Host: webhook.site
Content-Type: application/json
Content-Length: [x]
Connection: close

[location]

Where [x] is location.length() and [location] is the content of the location string.

77843: <p>I'm successfully sending a GET request (in the setup function, to load certificates,) but my POST request fails with a bunch of AT errors. I suspect this has to do with the way I'm formatting the POST. Any ideas would be appreciated.</p>
<p>Code follows:</p>
<pre><code>// MKRGSM - Version: 1.5.0
#include &lt;MKRGSM.h&gt;
#include &lt;ArduinoJson.h&gt;
#include &lt;Arduino_MKRGPS.h&gt;

const char PINNUMBER[]     = &quot;&quot;;
// APN data

const char GPRS_APN[]      = SECRET_GPRS_APN;

const char GPRS_LOGIN[]    = &quot;&quot;;

const char GPRS_PASSWORD[] = &quot;&quot;;

DynamicJsonDocument doc(1024);

// initialize the library instance

GSMSSLClient client;

GPRS gprs;

GSM gsmAccess(true);

// Specify IP address or hostname

char server[] = &quot;webhook.site&quot;;
char path[] = &quot;/ce480c43-95a8-4f1e-b996-bc02f6d1adaa&quot;;
int port = 443; 

void setup() {

  // initialize serial communications and wait for port to open:

  Serial.begin(9600);

  while (!Serial) {

    ; // wait for serial port to connect. Needed for native USB port only

  }

  // If you are using the MKR GPS as shield, change the next line to pass

  // the GPS_MODE_SHIELD parameter to the GPS.begin(...)
  delay(200);


  if (!GPS.begin()) {

    Serial.println(&quot;Failed to initialize GPS!&quot;);

    while (1);

  }
  Serial.println(&quot;Starting Arduino GSM ping.&quot;);
  // connection state
  bool connected = false;

  // After starting the modem with GSM.begin()
  // attach the shield to the GPRS network with the APN, login and password
  while (!connected)
  {
    if ((gsmAccess.begin(PINNUMBER) == GSM_READY) &amp;&amp;
        (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD) == GPRS_READY))
    {
      connected = true;
    } 
    else 
    {
      Serial.println(&quot;Not connected&quot;);
      delay(1000);
    }
  }

  Serial.println(&quot;connecting...&quot;);

  // if you get a connection, report back via serial:
  // Use this to load Root Certs the first time
  if (client.connect(server, port)) 
  // Use this to not load Root Certs anymore as done last time and stored in modem's flash
//  if (client.connect(server, port, false)) 
  {
        Serial.println(&quot;connected&quot;);

    // Make a HTTP request:

    client.print(&quot;GET &quot;);

    client.print(path);

    client.println(&quot; HTTP/1.1&quot;);

    client.print(&quot;Host: &quot;);

    client.println(server);

    client.println(&quot;Connection: close&quot;);

    client.println();
  } 
  else 
  {
    // if you didn't get a connection to the server:
    Serial.println(&quot;connection failed&quot;);
  }
}

void loop() {

  ...GPS stuff happens here

  // print GPS values

  Serial.println();

  Serial.print(&quot;Location: &quot;);

  Serial.print(latitude, 7);

  Serial.print(&quot;, &quot;);

  Serial.println(longitude, 7);

  Serial.print(&quot;Altitude: &quot;);

  Serial.print(altitude);

  Serial.println(&quot;m&quot;);

  Serial.print(&quot;Number of satellites: &quot;);

  Serial.println(satellites);

  doc[&quot;latitude&quot;] = latitude;
  doc[&quot;longitude&quot;] = longitude;
  doc[&quot;altitude&quot;] = altitude;
  
  String location;
  serializeJson(doc, location);
  Serial.print(&quot;Location string: &quot;);
  Serial.println(location);

  Serial.println();
  
  Serial.println(&quot;Starting Arduino web client.&quot;);

  // connection state
  
  if (client.available()) {
    Serial.println(&quot;Sending location&quot;);
    client.print(&quot;POST &quot;);
    client.print(path);
    client.println(&quot; HTTP/1.1&quot;);
    delay(5);
    client.println(&quot;Content-Type: application/json;&quot;);
    delay(5);
    client.print(&quot;Content-Length: &quot;);
    client.println(location.length());
    client.print(&quot;Host: &quot;);
    client.println(server);
    delay(5);
    client.println(&quot;Connection: close&quot;);
    delay(5);
    client.println();
    delay(5);
    client.println(location);
    Serial.print(&quot;Successfully sent location&quot;);

    if (!client.available() &amp;&amp; !client.connected()) {
  
      Serial.println();
  
      Serial.println(&quot;disconnecting.&quot;);
  
      client.stop();
    }
  } else {
    // if you didn't get a connection to the server:
    Serial.println(&quot;connection failed&quot;);
  }
  
}
</code></pre>
<p>Here's what the output looks like:</p>
<blockquote>
<p>Location: 32.1208382, 35.2468376 Altitude: 640.40m Number of
satellites: 5 Location string:
{&quot;latitude&quot;:32.12084,&quot;longitude&quot;:35.24684,&quot;altitude&quot;:640.4}</p>
<p>Starting Arduino web client. Sending location
AT+USOWR=0,13,&quot;504F53542068747470733A2F2F&quot;</p>
<p>ERROR
AT+USOWR=0,37,&quot;2F63653438306334332D393561382D346631652D623939362D626330326636643161646161&quot;</p>
<p>ERROR AT+USOWR=0,9,&quot;20485454502F312E31&quot;</p>
<p>ERROR AT+USOWR=0,2,&quot;0D0A&quot;</p>
<p>ERROR
AT+USOWR=0,31,&quot;436F6E74656E742D547970653A206170706C69636174696F6E2F6A736F6E3B&quot;</p>
<p>ERROR AT+USOWR=0,2,&quot;0D0A&quot;</p>
<p>ERROR AT+USOWR=0,16,&quot;436F6E74656E742D4C656E6774683A20&quot;</p>
<p>ERROR AT+USOWR=0,2,&quot;3539&quot;</p>
<p>ERROR AT+USOWR=0,2,&quot;0D0A&quot;</p>
<p>ERROR AT+USOWR=0,6,&quot;486F73743A20&quot;</p>
<p>ERROR AT+USOWR=0,12,&quot;776562686F6F6B2E73697465&quot;</p>
<p>ERROR AT+USOWR=0,2,&quot;0D0A&quot;</p>
<p>ERROR AT+USOWR=0,17,&quot;436F6E6E656374696F6E3A20636C6F7365&quot;</p>
<p>ERROR AT+USOWR=0,2,&quot;0D0A&quot;</p>
<p>ERROR AT+USOWR=0,2,&quot;0D0A&quot;</p>
<p>ERROR
AT+USOWR=0,59,&quot;7B226C61746974756465223A33322E31323038342C226C6F6E676974756465223A33352E32343638342C22616C746974756465223A3634302E347D&quot;</p>
<p>ERROR AT+USOWR=0,2,&quot;0D0A&quot;</p>
<p>ERROR</p>
</blockquote>
<p>I could send the data as parameters in the GET query, but that's ugly.</p>
 77843: <p>The problem was that <code>GSM gsmAccess;</code> needed to be <code>GSM gsmAccess(true)</code>. Unfortunately, while that solves the immediate problem, which is that the client was not initializing, there are other issues which deserve a separate question.</p>
 4143: <p>Your HTTP request is badly formatted.  You have:</p>
<pre><code>POST https://webhook.site/ce480c43-95a8-4f1e-b996-bc02f6d1adaa HTTP/1.1
Content-Type: application/json
</code></pre>
<p>Instead the protocol is implied by the port you are connecting to, and the domain name does <em>not</em> go in the path on the server component - it has its own header.</p>
<p>Your request should look more like:</p>
<pre><code>POST /ce480c43-95a8-4f1e-b996-bc02f6d1adaa HTTP/1.1
Host: webhook.site
Content-Type: application/json
Content-Length: [x]
Connection: close

[location]
</code></pre>
<p>Where <code>[x]</code> is <code>location.length()</code> and <code>[location]</code> is the content of the <code>location</code> string.</p>
