I found this interesting when writing an interface to the OctoPrint API and it seems a bit unexpected to me. I honestly spent a long time troubleshooting this but finally found a good work-around. I don't know enough about the receiving code in OctoPrint to find out where these calls are landing.
I'll first introduce the code then describe what I was seeing. The code is in nodejs, btw.
/**
* Send the specified command to the indicated printer.
*
* @param {Number} - The printer ordinal from the global array
* @param {String} - The API endpoint
* @param {object} - The JSON printer command to send
*/
function sendToPrinter(iPrinterOrdinal, endPoint, objPrinterCommand, callback) {
var response = "";
var objPrinter = globalArrayPrinterProfiles[iPrinterOrdinal];
var apiKey = objPrinter.apiKey;
var url = "http://" + objPrinter.hostName + endPoint;
//console.log(objPrinterCommand);
$$.ajaxSetup({ headers: { 'X-Api-Key': apiKey }});
$$.ajax({
url: url,
method: 'POST',
contentType: 'application/json',
data: JSON.stringify(objPrinterCommand),
success: function(response){
if (typeof callback === "function") {
callback('Status 204');
}
},
error: function(xhr, status){
if (typeof callback === "function") {
callback(JSON.stringify(status));
}
}
});
};
A typical call to this function then would be:
var objPrinterCommand = { "command": "home", "axes": ["x","y","z"] };
sendToPrinter(printerOrdinal, endPoint, objPrinterCommand, function(data){
//console.log('Home command sent to printer: ' + data);
});
The work-around was to call JSON.stringify() to convert the command from json to a string before sending it on to your API. If you don't do this, the printer always returns a 400 status code.
The docs indicate that it wants application/json
as the Content-Type and that is being set of course. The API just doesn't like the data if it's not in a string format in the BODY. I've tried using a variety of Node modules for the http call but it seems to be the same, regardless.
I note this in case others are trying to exercise the API to control the printer.