I’ve been having some fun recently automating a database with Monday.com for a client. I had never used Monday.com, but they were using it and wanted to integrate information from my system into it. So I needed to develop a synchronization mechanism to for the standard CRUD operations (Create, Read, Update, Delete).
Now, the work I’ve been doing is actually part of a Web Application, so programmed in PHP, but I thought to myself that given the work I did on using the Outlook Graph REST API as well as the Google REST API, that what I had achieve in PHP I could translate over to VBA for use in any application of my choosing.
A couple hours later, I had a fully functional Access database capable of querying Monday.com, looking up information, creating entries, updating entries & deleting entries.
oAuth and Tokens
Now, I not going to over all the REST API stuff here. For that I’d refer you to my previous articles/videos:

So, in this article, I’m assuming you have authenticated properly and have a token to work with.
To get your authorization code
https://auth.monday.com/oauth2/authorize
To get your token
https://auth.monday.com/oauth2/token
You can consult the official oAuth documentation for all the details at:
Also note the oAuth implementation of Monday.com appears to be very basic, no means to check a token (besides just using it), no means to renew or invalidate a token. So basically, it implies that once you generate a token it is valid indefinitely. Thus, performing this task manually once or using the token provided in the Easy way (see below) may be the best option and offer you the possibility to completely bypass the need for any oAuth integration whatsoever.
VBA Integration of Monday.com
Querying Monday.com
The first thing to understand with interacting with Monday.com is that everything is done via a query. So you need to create a query, send it to Monday.com and then check the response that is sent back to you.
Luckily for use, once again Monday.com has somewhat helped us with our task of developing our query(ies) by providing us an interface for creating/testing them. They call it the ‘API Playground’ (Developers->API Playground). There you have a query editor to try variations, run, adjust, … Once you have it functional you can then bring it into VBA!
The API Playground permits multiple queries to be created and stored in separate tabs which is really convenient!
The VBA Procedure
Here is a simple procedure framework for working with the Monday.com REST API via VBA.
Public Sub HTTP_SendRequest_Monday()
On Error GoTo Error_Handler
Dim oHTTP As MSXML2.XMLHTTP60
Dim sHTTPRequest As String
Dim sMondayQuery As String
Const sToken = "PutYourMonday.comTokenHere"
'Initialize our variables
lHTTP_Status = 0
sHTTP_StatusText = ""
sHTTP_ResponseText = ""
'Define the Monday.com REST API query
sMondayQuery = "query { me { name } }"
'Finalize the actual REST API request string
sHTTPRequest = "{""query"": """
sHTTPRequest = sHTTPRequest & sMondayQuery
sHTTPRequest = sHTTPRequest & """}"
'Make the request and get a response back
Set oHTTP = New MSXML2.XMLHTTP60
With oHTTP
Call .Open("POST", "https://api.monday.com/v2")
Call .setRequestHeader("Content-Type", "application/json")
Call .setRequestHeader("Authorization", sToken)
Call .send(sHTTPRequest)
lHTTP_Status = .Status
sHTTP_StatusText = .StatusText
sHTTP_ResponseText = .responseText
Debug.Print "URL: " & "https://api.monday.com/v2"
Debug.Print "Request: " & sHTTPRequest
Debug.Print "Status: " & lHTTP_Status & " | " & sHTTP_StatusText
Debug.Print "Response: " & sHTTP_ResponseText
End With
Error_Handler_Exit:
On Error Resume Next
Set oHTTP = Nothing
Exit Sub
Error_Handler:
MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
"Error Source: HTTP_SendRequest_Monday" & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Description: " & Err.Description & _
Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
, vbOKOnly + vbCritical, "An Error has Occurred!"
Resume Error_Handler_Exit
End Sub
Running this will then output something like:
URL: https://api.monday.com/v2
Request: {"query": "query { me { name } }"}
Status: 200 | OK
Response: {"data":{"me":{"name":"Daniel"}}}
Normally you are only truly after the sHTTP_ResponseText values, but for illustrative and learning purposes I made the procedure return other information as well.
More Queries You Say
As I mentioned above, everything is query based, so once you have the basic procedure, the only thing you really need to do is switch the query being sent to Monday.com, the rest of the procedure stays unchanged! With that in mind, here are some examples of queries to help you understand and get going.
Identify the Current User
As shown above, we can easily identify the current user with a query like:
sMondayQuery = "query { me { name } }"
but, if you wish, you can also retrieve other information about the current user by simply adding the column(s) of data you wish to retrieve, such as:
sMondayQuery = "{ me { id name birthday } }"
List the Boards
To list all the boards, we could do something like:
sMondayQuery = "query ListAllBoard { boards { id name board_kind } }"
Get a Boards Details
Another useful thing, to be able to work with a board (perform CRUD operations on the items within a board) is to analyze a board and its columns. To do this, we can use a query like:
sMondayQuery = "query ListContactBoardColumns{ boards(ids: [YourBoardId]) { name columns { title id type } } }"
This will permit you to identify the ids of the various columns which is critical to being able to work with them!
List the Board Groups
On a board, we can make groups to better view groupings of data, so break the information down, if we wish to extract a list of these groups and their id (to be able to interact with them further) we can do something like:
sMondayQuery = "query ListBoardGroups{ boards(ids: [YourBoardId]) { groups { id title } } }"
Retrieving an Entry’s Details
So say you have a Contacts board with a listing of contacts. Say you wanted to get a listing of the entries, you could do:
sMondayQuery = "query ListContactsDetailed { boards(ids: [YourBoardId]) { items_page { items { id name } } } }"
or to get more details on each entry, you could do (adjusting for your column names of course):
sMondayQuery = "query ListContactsDetailed { boards(ids: [YourBoardId]) { items_page { items { id name column_values { id column { title } type value text } } } } }"
This will provide you a breakdown of current contacts on the specified board
If, instead of wanting to get a listing of all the entries you wanted to look up a specific entry, say search by First and Last name, you could do something like:
sMondayQuery = "query GetSpecificContactDetailsByName{ items_page_by_column_values( board_id: YourBoardId columns: [{column_id: \""text_mkpeqqsr\"", column_values: [\""Erik\""]}, {column_id: \""text_mkperft3\"", column_values: [\""Higgins\""]}] ) { cursor items { id name } } }"
Where text_mkpeqqsr is the id of my First Name column and text_mkperft3 is the id of my Last Name column.
Enumerate the Entries by Board Group
If instead of just getting a breakdown of the entries of a board, as shown above, we wanted to get a breakdown by group(ing), then we could do something like:
sMondayQuery = "query ListClientsByBoardGroup{ boards(ids: YourBoardId ) { groups{ id title items_page{ items{ id name } } } } }"
Or if you want to only get the breakdown of a specific board then you’d do:
sMondayQuery = "query ListClientsByBoardForASpecificGroup{ boards(ids: YourBoardId ) { groups(ids: \""YourGroupId\""){ \tid title position items_page{ items{ id name } } } } }"
and you could get a breakdown for multiple specific group by simply modifying the above slightly to:
sMondayQuery = "query ListClientsByBoardForASpecificGroups{ boards(ids: YourBoardId ) { groups(ids: [\""YourGroupId1\"", \""YourGroupId2\""]){ \tid title position items_page{ items{ id name } } } } }"
and adding as many Group Ids as you need to the ‘groups(ids:’ section.
Creating a New Entry In a Board
Creating an entry is relatively simple as well, once you know the query syntax.
sMondayQuery = "mutation { create_item(board_id: YourBoardId, item_name: \""John Doe\"", column_values: \""{\\\""text\\\"": \\\""AYZ Inc\\\"", \\\""text_mkpeqqsr\\\"": \\\""John\\\"", \\\""text_mkperft3\\\"": \\\""Doe\\\""}\"" ) { id } }"
This will create an entry labeled ‘John Doe’ with a First Name of ‘John’ and a Last Name of ‘Doe’.
Modifying an Existing Entry
To modify an entry we would look up the record to determine the id and then bind to that id to perform the update by doing:
sMondayQuery = "mutation UpdateContactEmail { change_simple_column_value( board_id: YourBoardId item_id: YourContactId column_id: \""email\"" value: \""j.doe@somewhere.com j.doe@somehwere.com\"" ) { id } }"
Deleting an Entry on a Board
Deletion is very straightforward and you only need the id of the entry to delete. The basic syntax would be:
sMondayQuery = "mutation DeleteContact{ delete_item(item_id: YourContactId) { id } }"
Some Final Thoughts
I must say that Monday.com seems to have made initial access to automate things as simple as possible by providing a token directly via your account, bypassing the need of coding any oAuth processes into your project. That said, be very careful how you code/store such a confidential piece of information!
I must also applaud them for the API Playground. This is where I spent the bulk of my time learning things! Once I got thing functional there, migrating to PHP, or VBA, was relatively simple.
Syntax. Well this is one thing that sometimes took a bit to figure out, or look up online. I had issues with their documentation (but that could be just me as it was new to me) and often found it easier to perform and online search to locate a discussion … from which I could learn things, or through trial and error in the API Playground.
PHP/VBA Syntax. Well, if you reviewed the VBA procedure you probably noticed that we set a header to “application/json” indicating that our request must be a JSON string. This is why we have to send strings like \\\”” … I will hopefully do another post on this in the coming days and show you what I did to convert the API Playground query into the required JSON formatted string (as always we have a couple options on this front).
I also found the fact that I could create a free developer’s account which took me 30 seconds to get up and running a huge bonus!
I should also mention, one thing I’d recommend is that whenever you create an entry in Monday.com capture its id in your application as this will avoid any need to look it up again to be able to work with it (update/delete). You’ll simply use the stored id and run your command!
All and all, this was a fun couple of hours and I already have a VBA and a PHP version up and running.
I hope this enables a few of you to have fun working with Monday.com!
Page History
| Date | Summary of Changes |
|---|---|
| 2025-03-31 | Initial Release |
