Communications.makeWebRequest in CIQ simulator gives result -200

This code:

Communications.makeWebRequest(url, authParams, options, method(:onAuthResponse));

gives me -200 as result in the simulator and that means COMMUNICATIONS_ERR_NETWORK_FAILURE if I am correct.

SDK 8.2.3

Use device HTTPS Requirements is checked, Connection type is BLE  (Wifi disabled)

Is it possible to get internet access thru the simulator?

  • -200 is INVALID_HTTP_HEADER_FIELDS_IN_REQUEST

    There is something wrong with what you have in the makeWebRequest call

  • this is the option part:

        var options =
            {
                :method => Communications.HTTP_REQUEST_METHOD_POST,
                            :headers => { "Content-Type" => "application/json"
                  },
                :responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_JSON
            };    

    Another thing, if i DEBUG the authparams i get this in the debug console:
     {password=>mypassword, applicationId=>00000-ab09-00-0000-0019, accountName=>myusernane}

    according to the API it should be:
    {"accountName": "username","password": "password","applicationId": "appId"}

    In my C# code if I print the same authCode

    {"accountName": "myusername","password": "mypassword","applicationId": "00000-ab09-00-0000-0019"}


    It doesn't seem like the body is correctly formatted to json?

    I do this in my C# code and would like to do the same here:

    var loginData = new
    {
    accountName = username,
    password = password,
    applicationId = appId
    };

    var json = JsonConvert.SerializeObject(loginData);
    var content = new StringContent(json, Encoding.UTF8, "application/json");
    var response = await httpClient.PostAsync(url, content);



  • needed to change to 

     "Content-Type" => Communications.REQUEST_CONTENT_TYPE_JSON

    But the content is still not json

  • Another thing, if i DEBUG the authparams i get this in the debug console:
     {password=>mypassword, applicationId=>00000-ab09-00-0000-0019, accountName=>myusernane}
    It doesn't seem like the body is correctly formatted to json?

    That's because you're not printing params as json (since they're not json), you're printing them as a Monkey C dictionary data structure (since that's what they are). That's just the debug representation of a dictionary, which doesn't quote strings [*], and which uses "=>" for key/value pairs (the same as a Monkey C dictionary in source code)

    The CIQ API (makeWebRequest) should change the params to JSON, but you won't see that in your app.

    [*] It's not too different than printing/logging a string in any other language - it won't be automatically quoted either.

    js:

    let s = "foo"
    console.log(s); // prints: foo

    python:

    s = "foo"
    print(s) # prints: foo

    I could also give examples in C#, Java and other languages, but you get the idea.

    I do this in my C# code and would like to do the same here:

    var loginData = new
    {
    accountName = username,
    password = password,
    applicationId = appId
    };

    var json = JsonConvert.SerializeObject(loginData);
    var content = new StringContent(json, Encoding.UTF8, "application/json");
    var response = await httpClient.PostAsync(url, content);

    Yeah so the difference here is that in your C# code, your app encodes the data to be sent, and the API just passes it along.

    CIQ is much more restrictive - makeWebRequest wants a Monkey C dictionary as input, and will encode it for you (either as JSON or URL params)

  • But the content is still not json

    Could you test this with a local server that you control? Or you use a site like https://beeceptor.com/resources/http-echo/ 

  • Thanks for the clarification.
    The first problem seems to be that i used my own text instead of system parameter:

     var options =
            {
                :method => Communications.HTTP_REQUEST_METHOD_POST,
                          :headers => { "Content-Type" => Communications.REQUEST_CONTENT_TYPE_JSON      
                },
                :responseType =>   Communications.HTTP_RESPONSE_CONTENT_TYPE_JSON
            };    

    But now I get -400 error instead:

    The data I am getting back (from my C# application) :
    StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
    {
    Connection: keep-alive
    CF-RAY: 983949141fbc204f-BCN
    vary: Origin
    vary: Access-Control-Request-Method
    vary: Access-Control-Request-Headers
    x-trace-id: 61670ae3-fac8-4eea-87fc-ebc7a5afebdb
    x-content-type-options: nosniff
    x-xss-protection: 0
    pragma: no-cache
    strict-transport-security: max-age=15780000; includeSubDomains; preload
    x-frame-options: DENY
    cf-cache-status: DYNAMIC
    Cache-Control: no-store, must-revalidate, no-cache, max-age=0
    Date: Tue, 23 Sep 2025 10:16:14 GMT
    Server: cloudflare
    Content-Length: 38
    Content-Type: application/json
    Expires: 0
    }

    And its the data in System.Net.Http.StreamContent I am interested in  
  • update:

    The website requires raw JSON and that seems to me a problem for Communications.makeWebRequest.

    tried  this

    var jsonBody = "{"
            + "\"accountName\":\"" + myusername + "\","
            + "\"password\":\"" + password + "\","
            + "}";
             // Pass JSON as :body inside dictionary
             var parameters = { :body => jsonBody };

    but then it includes :body
    {symbol (8392369):"{\"accountName\":\"...\",\"password\":\"...\"}"}

    is it any other way to do a webrequest that I can use raw json?

  • > The website requires raw JSON and that seems to me a problem for Communications.makeWebRequest.

    Sorry, maybe I didn't communicate clearly?

    When you pass in a dictionary as the 2nd parameter to makeWebRequest and tell makeWebRequest to send JSON (using the Content-Type header), makeWebRequest automatically converts the dictionary to JSON.

    There's no need for you to encode the JSON yourself. In fact CIQ doesn't give you functions to decode/encode JSON, it's always done automatically for you. (Yes, this is kind of restricting in a way.)

    That's why I was trying to suggest testing it with a server that you control (or the test server linked above), so you can see what data the server is actually receiving.

    You keep saying the content is not JSON, but you're not telling us exactly what it is. Logging the params in your app as they are passed to makeWebRequest does not tell you what the content looks like to the server.

    Unless you control the server, it's not clear to me how you can be sure what the server is seeing and be confident in your statement that the server is not seeing JSON

    But now I get -400 error instead

    In CIQ / makeWebRequest, -400 is INVALID_HTTP_BODY_IN_NETWORK_RESPONSE.

    In your case, this means that the response from the server is not a JSON object.

    Note that CIQ requires a JSON object in the response when you use HTTP_RESPONSE_CONTENT_TYPE_JSON, and not one of the following JSON types, even though they are also valid json: array, string, number, null.

    Are you able to tell us what the response from the server is supposed to look like? (Like when you use your C# app?)

    Again the problem here is that makeWebRequest is very restrictive:

    - it expects the input to be in a certain format, based on the request content type, and in the case of JSON, you don't even get to look at the actual input that's sent to the server (you specify the input as a Monkey C dictionary, and you never see the JSON in your app)

    - it expects the output to be in a certain format, based on the response content type. Again, in the case of JSON, you never see the original JSON response, only the Monkey C dictionary that the API decodes for you. In the case that the original response is not a JSON object, you don't even get to see any kind of response at all

    So for example, if the server returns something like "Authentication Successful" or  ["Authentication Successful"], even though that's valid JSON, makeWebRequest would reject it because it wants a JSON object, like { result: "Authentication Successful" }

    You may be able to get around this if you specify HTTP_RESPONSE_CONTENT_TYPE_TEXT_PLAIN for the response type, but only if you also control the server and you can get the server to return "text/plain" in the actual response header. But of course if you could do that, you could also change the response to return a JSON object.

    If you don't control the server, I *think* your only option is to implement a wrapper server which returns a JSON object.

    EDIT: actually I did some testing, and if you specify HTTP_RESPONSE_CONTENT_TYPE_TEXT_PLAIN for the response type, then if the server returns application/json and status 200, makeWebRequest will succeed (but of course it will return the JSON as a stirng). In other words, it won't care about the mismatch between the specified response type and the actual response in this case. So in your case, for successful auth, it doesn't matter whether the server returns a content-type of text/plain or application/json (while returning a string in either case) - you can use HTTP_RESPONSE_CONTENT_TYPE_TEXT_PLAIN for both cases

  • HI You are correct,

    this old web API states that it must have JSON, BUT when correctly authenticated it returns HTTP_RESPONSE_CONTENT_TYPE_TEXT_PLAIN , when there is error in the AUTH it returns HTTP_RESPONSE_CONTENT_TYPE_JSON

  • Yeah so this highlights a problem with makeWebRequest's overly restrictive behaviour. 

    I think there are 2 ways to get around this:

    - Remove :responseType from the options dictionary

    - Change :responseType to HTTP_RESPONSE_CONTENT_TYPE_TEXT_PLAIN

    When the API returns text/plain (with 200 status), then you should get a String in the response callback.

    Unfortunately, no matter what you do, you cannot see the response data if the server returns an error, because makeWebRequest will pass null for the data to the response callback. This is really a shame, because it prevents you from displaying an error message based on the response data. You only have access to the server response code in this case. 

    Also, note that HTTP_RESPONSE_CONTENT_TYPE_TEXT_PLAIN is only available in CIQ 3 and higher, so I think neither option will work on the very old CIQ 2 devices (which are about 9-10 years old at this point).