Here’s a basic snippet of C# that let’s you execute queries against the v2 API and return the response as JSON. For some this may be old hat, but it took me a good couple of hours of mucking about - so hopefully it can save someone else that time in the future!
For convenience I’ve created a little helper class to encapsulate the call and return;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Threading.Tasks;
namespace Monday.lib
{
public class MondayHelper
{
private const string MondayApiKey = "your-api-key-goes-here";
private const string MondayApiUrl = "https://api.monday.com/v2/";
/// <summary>
/// Get a JSON response from the Monday.com V2 API.
/// </summary>
/// <param name="query">GraphQL Query to apply to the Monday.com production instance for Grange.</param>
/// <returns>JSON response of query results.</returns>
/// <remarks>
/// Query must be in JSON,
/// e.g. = "{\"query\": \"{boards(ids: 1234) {id name}}\"}"
/// </remarks>
public async Task<string> QueryMondayApiV2(string query)
{
byte[] dataBytes = System.Text.Encoding.UTF8.GetBytes(query);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(MondayApiUrl);
request.ContentType = "application/json";
request.Method = "POST";
request.Headers.Add("Authorization", MondayApiKey);
using (Stream requestBody = request.GetRequestStream())
{
await requestBody.WriteAsync(dataBytes, 0, dataBytes.Length);
}
using (HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync())
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
return await reader.ReadToEndAsync();
}
}
}
You can then use the helper like so;
var helper = new Monday.lib.MondayHelper();
string json = await helper.QueryMondayApiV2("{\"query\": \"{boards(limit:1){id name}}\"}");
Which will give you the JSON response string to consume as you will.
Note: you don’t need any Nuget Packages or libraries. The only one I’ve used is Newtonsoft’s JSON just so I didn’t have to hand-serialise/deserialise the JSON going in and returning.
Given you’re attempting to retain an escaped string in JSON I’d suggest using it’s escape context rather than the C# style. Thus whilst in C# you use a repeated double quote for escape context in a literal string ("") - in JSON you manually escape a double quote with a preceding slash (\"). Combining the two will be necessary to get the result you need to achieve.
Thus rather than this; value:""""123456""""
Perhaps instead try something like this; value:\""123456\""
Since the end result you’re shooting for is (probably) this; value:\"123456\"
You’ll also need to do that for where you’re specifying numbers. Use \"" there as well.
I haven’t tried this myself but it should give you something to work off.
This works correctly in the Monday.com tooling for creating items, looks correct from a script standpoint - any thoughts on fixing this so I can pass column data in on creation? if I remove the “column_values” segment, the item gets created correctly using the helper class.
I can get this working without the “column values” portion, so the rest is formatted correctly - there’s something wrong with my column values formatting for Monday to understand it… any help would be greatly appreciated.
I figured this out - wanted to share here, in case another runs into this issue. My issue with the column values was the escape sequences for the quotes! Since this is a text string that’s meant to be embedded json, it gets a bit nasty. Here is my final query using the library that is working to add an item, as well as, insert column data in all the columns that I want to:
Thank you so much @SHaddy - can you imagine I have spent a day and a half going crazy with formatting the query string in various way and maybe your working version was the only one I haven’t tried. Can you share - how you managed to discover it - you get almost no response from the API why the request fails with bad response.
I even tried different ways with Json.net serializing object - in vain.
Thank you so much for sharing.
Yeah, unfortunately with how Graph is built, it can be prone to giving generic responses - I figured it out by literally trying a ton of different things and working on the formatted string. I kept trying different combinations and reducing the query to know what worked. Once I got a solid positive result, I added a single field update to my query and then the real fun began - trying different formatting for output.
Once I kept running into a single field update issue - I read some more on the API and noticed the data passed to the standard graph differentiated from the later parameters - this made me start trying different formatting to try and determine what could impact the result set. I ran the data through some json escape sequence builders and modifying from there. After many hours there, I finally came up with a combination that worked - once a single param was built, it was home free from there.
It really amazes me that the graph system does not have a standard json input option that general json objects can be passed to - it would make it incredibly more simple to interface with.
Hey @SHaddy, thanks for walking us through your approach!
In your last post you refer to a “Standard JSON input” to pass data in your API call. Could variables do the trick (they let you pass the arguments of your mutation as a JSON object), or do you mean standard JSON input for column values specifically?
Hello @SHaddy first so much thanks to your effort and help. I have been trying yesterday when I had time to get rid of this nasty string formatting but it seems that that is the only format monday api accepts, really the only one!
and especially generate the column_values json dynamically but what I have come up with
public static string CreateColumnValuesStrng(CampaignStatsusReportRow row)
{
string builder = string.Empty;
dynamic obj = new ExpandoObject();
foreach (var property in row.GetType().GetProperties())
{
switch (property.Name)
{
case "CampaignReference":
{
var columnname = @"\""" + property.Name+ @"\""";
var columnvalue = @"\""" + row.CampaignReference + @"\""";
((IDictionary<string, object>)obj)[columnname] =columnvalue;
break;
// more cases
}
}
}
var scriptSerializer = new JavaScriptSerializer();
return scriptSerializer.Serialize(obj);
}
Unfortunately JsonConvert.SerializeObject adds one slash and quote for escaping at the end and beginning of each key value and I cannot achieve the same string format required. If you can suggest a better way that mine junior developer struggling I would be so grateful.
I tried a lot of different work-arounds for inserting the proper escape sequences using available libraries. Unfortunately the built in json values essentially need to be double escaped due to the way Graph is built (not Monday’s fault - but graph should have built out a better way to pass in plain json vs their own proprietary format).
Now, I’m sure there’s a way to stack multiple escape json sequences in .NET, but this was a small side project for our marketing department, so I didn’t dig deeper. This is the solution I came up with: got the query working in plain format without passed in values, then replaced keywords in the query to finalize the query.
You could easily fill this out into a method by using an array of values stacked at different positions and loop through those dynamically. Below is a screenshot of my method I created that’s working for this project. Like I said, I kept it simple because we had a specific need for this project - I might dig further on the next time I use the Graph system:
The main thing I think should be noted is, the depth of the escapes on each column value. Also note, I tried various versions of this by inserting parameters into the query itself, but had trouble (because of the escape depth) getting the parameters inserted correctly. I ended up going the replace route, due to this.