UnityWebRequest.Post to send a task to ClickUp's API, encoding JSON improperly

So I’m writing a program in Unity that sends tasks to a ClickUp list. I’ve been able to send the request through Postman for testing properly, but whenever I try to send that request through Unity I get an error with the Json encoding:

{"err":"Unexpected token % in JSON at position 0","ECODE":"JSON_001"}

The code for the method is as follows. It’s just a very basic tester method, so I know it’s a little messy as is, but once I’m able to actually send the requests properly I want I’ll re-write it with the full functionality.

private void SendDemoTask()
    {
        string jsonString = "{\"name\": \"Unity send from postman\",\"description\": \"Sent on May 24 2022\"}";

        UnityWebRequest demoTaskRequest =
            UnityWebRequest.Post($"https://api.clickup.com/api/v2/list/{listID}/task",jsonString);
        demoTaskRequest.SetRequestHeader("Authorization",accessToken);
        demoTaskRequest.SetRequestHeader("Content-Type","application/json");

        var operation = demoTaskRequest.SendWebRequest();

        // Wait for request to return
        while (!operation.isDone)
        {
            CheckWebRequestStatus("Task creation failed.", demoTaskRequest);
        }
       
        Debug.Log(demoTaskRequest.result);
        Debug.Log(demoTaskRequest.downloadHandler.text);
    }

It seems to be an issue with the JSON encoding. Unfortunately the POST method doesn’t have an argument to take a byte array. The PUT method does, but ClickUp’s API won’t accept the same types of requests through Put.

Is there a way for me to send this request that will correct the encoding issue? Or is the problem somewhere else?

Apologies if any part of this isn’t clear. I’m fairly new to using UnityWebRequest and a total noob to webdev in general.

Thank you for any help you all can offer, I very much appreciate it!

1 Like

Not exactly an answer to the error you get, but I have been able before to send a byte array through a POST call like this:

string requestURL = "https://a20artour.studev.groept.be/addTour.php";

Tour tour = new Tour
{
    name = tourName,
    description = tourDescription,
};

// convert object to JSON
string jsonBody = JsonUtility.ToJson(tour);

// convert JSON to raw bytes
byte[] rawBody = Encoding.UTF8.GetBytes(jsonBody);

UnityWebRequest request = new UnityWebRequest(requestURL, "POST");
request.uploadHandler = new UploadHandlerRaw(rawBody);
request.downloadHandler = new DownloadHandlerBuffer();
request.SetRequestHeader("Authorization", "Basic " + GetAuthenticationKey());
request.SetRequestHeader("Content-Type", "application/json");

yield return request.SendWebRequest();

if (request.isNetworkError || request.isHttpError)
{
  // error
    // request.error
    // request.responseCode
}

else
{
    // successful
    // request.downloadHandler.text
}

edit: Note that the ‘Tour’ class in this example is marked with [Serializable], this is required for the conversion to JSON. Not sure what is going wrong with your own code, but I guess making a class for the messages you send doesn’t hurt? Could be as simple as a “MyMessage” class with just a “message” string field or something.

5 Likes

This worked, thank you so much!

2 Likes

This, or similar questions, has been asked countless of times now :slight_smile:

Yes, the static UnityWebRequest.Post method unintuitively expects URLEncoded form data, nothing else. So this method specifically applies url encoding to the string and also uses application/x-www-form-urlencoded as content type. This can be seen here. In most recent versions they actually marked “Post” as obsolete, so they may plan to remove it as the current behaviour is misleading.

So yes, if you want to post raw text / string data you have to manually use a raw upload handler and set the content type yourself.

2 Likes