Skip to main content
  • 289 Product updates

Adjustments to API rate limiting

Hey everyone 🔮 We made some changes to our rate limiting mechanism to make it easier for apps to understand their limits and prevent abuse of our API. TLDR: Each individual query now has a complexity limit of 5M Most apps/users won’t notice a difference (but let us know if you do). How our rate limits work: a recap GraphQL rate limits are based on how much work you makes our servers do, measured in a unit called complexity. Each account and app has a specific complexity allowance that resets every minute. Trial accounts have a budget of 1M complexity every minute, while paid and developer accounts have a budget of 10M. New error messages When you run out of your complexity budget in a given minute, your app will now see a new error message that tells you how much budget you have left and when the limit resets: "message": "Complexity budget exhausted, query cost 1100010 budget remaining 999819 out of 1000000 reset in 19 seconds" Rate limit per query - 5M complexity We are enforcing a new limit of 5M complexity for each individual query. This is still quite a high limit, and you should be able to comfortably write queries that are under this limit using pagination and other best practices (more on that below). What should I do to prepare for this? We believe that very few users will be affected by these changes. However, you can ensure you don’t hit these limits by making your queries as efficient as possible. Follow these simple rules: Don’t ask for more than what you need. Every field in your query contributes to its cost, so only return the data that your app needs to do its job. Paginate, paginate, paginate. As far as possible, paginate through the returned data using the page and limit parameters. If you don’t add a limit or pagination to your query, we’ll assume you’re trying to return 1000 data points (which could blow up your query’s complexity). Reduce deeply nested fields. Each level of nesting in your query increases its complexity by 10x. Therefore, minimize the complexity of your query by ensuring you are returning the majority of your data in the first or second level of nesting. Here’s an example: # Inefficient (cost: 1011020) query { boards (ids:162169280) { groups { id items { id } } } } # Efficient (cost: 1220) query { boards (ids:162169280) { items (limit:100) { id group { id } } } } Have a question, comment, or feedback? Create a new thread from this topic by clicking the link icon 🔗 at the bottom of the post, and hitting “New Topic”:

Uploading a file to monday.com with variables - example in NodeJS

Hey there, awesome developers! 🎩 Ever wanted to upload a file to our API using variables without using our SDK? You’re in the right place! Today, I wanted to share a code example you can use as a reference point to making File upload calls to monday.com, including variables. This can make it easier to make the actual API call, instead of using hard-coded values in the call itself. This also helps make escaping JSON easier. You can find the code example here with comments: Code example - uploading files with variables using Node In general, you can take the logic of the code example above, and apply it the programming language you are using. You will be sending a request that consists of 4 parts: Query: The actual API query you’d like to make. In this case, either upload a File to the Files column, or to the Updates section. Variables: Your GraphQL variables, where you can store either the Update ID to be used, or the Item ID and the File column ID to be referenced in the mutation. This is useful as it allows you to avoid an additional layer of escaping JSON; Map: This is the part of the request where you include the name of your variables.file request part. For example: var map = {“image”:”variables.file”} This allows us to use variables in the call, and to also include a different name for the file we upload, if necessary. Variables.file (has to match the Map name) This is where you are passing the actual file to be uploaded. To sum up, you will be making a multipart/form-data request here, which is somewhat different from making the usual “application/json” requests for Queries and Mutations. You can find some more examples of multipart/form-data requests and GraphQL below: Some more general info on using multipart/form-data with GraphQL multipart/form-data general info This code example is based on another example that Dipro made earlier, constructing the request using boundaries and creating a stream of the File to upload before making the API call: Uploading a file to monday.com without variables I hope this helps you make more efficient API calls when uploading files to monday.com 🙂 -Alex

Windows Quickstart Integration Troubleshooting

✨✨Hi everyone! We know that some of our users use Windows computers, so we decided it would be a good idea to release an official troubleshooting guide for our Quickstart guides on these machines. Taking the example of our Quickstart Integration recipe, follow each of the steps until you get to step 4. Instead of copy-pasting the given command in your command line prompt: Download the project from our GitHub library following these steps: Download the Quickstart code from this GitHub repo. Navigate to the directory where you downloaded the code Install the dependencies with npm install Run the development environment with npm run start Following these steps, you may run into the following error messages: Kill-port is not recognized: 'kill-port' is not recognized as an internal or external command, operable program or batch file. If you run into this error message, this means that the kill-port command isn’t available on your machine. To correct this, simply install the kill-port ability with the following command and you should be good to go: npm install --save kill-port. Learn more in this community post. Nodemon is not recognized: 'nodemon' is not recognized as an internal or external command, operable program or batch file. If you run into this error message, this means that, like the kill-port command, the nodemon command hasn’t been installed on your machine yet. You can correct this by running the following command, which should install nodemon globally on your machine: npm install -g nodemon. If you see an error message along the lines of: Node Sass does not yet support your current environment: Windows 64-bit with Unsupported runtime (88) you may just need to update your node version by first installing NVM, then run nvm install 10.16.3 to install this version of Node. Lastly, run nvm use 10.16.3 before running the npx command. Learn more in this community post. After resolving these errors, run the same command `npm run start` to start your server. Paste the outputted URL in the URL box from step 4 here: I hope this helps! Feel free to let us know if you run into any other errors when installing. -Helen

Complexity Field Weights

✨✨Hi everyone! We thought it would be a good idea to post the complexity weights for each kind of field: Scalar fields (string, etc) = 1 Objects (items, boards, etc) = 10 Mutations = 30,000 items_by_column_values query = 100,000 File uploads = 100,000 Limiting and specifying IDs At this time, IDs are considered before the limit argument. In case you have added 4 Board IDs to your query, but are using a limit of 3 boards, your complexity rate will be based on the number of IDs you are using, and not the limit. Complexity limit per query Currently, there is a 5,000,000 complexity rate limit per query. This means that if you do a single query to the API and the complexity is over 5,000,000, it will be considered as exceeding complexity and the API call will fail. We suggest using limits within your query, as well as specifying IDs, in ordr to reduce complexity in such cases. Complexity Rate refresh rate An important thing to keep in mind (and a question we often get) is that complexity rates are set for each minute, and not for each query. This means that, though the complexity of your query may not be very high, if you’re calling said query many times, this could also lead to a complexity limit error. To combat this, you can either implement pagination, limit the amount of data you’re querying/mutating, or reduce the nesting of your API call. For more info about complexity and rate limits, check out this section of our API documentation: https://monday.com/developers/v2#rate-limits-section. -Helen

Announcement: Uploading files to monday.com has just become easier :)

New feature alert! 🎩 I’m excited to announce that uploading files to monday.com has just become a bit simpler using our API, and even easier when using our SDK. Now, when making direct calls to our API, you can upload files in a more GraphQL-like way. With your query you can now include query variables alongside files! This is compared to before when you’d need to use inline variables in the query. Now, the following request to our API is possible: const query = mutation add_file($update_id:Int!, $file: File!) { add_file_to_update(update_id: $update_id, file: $file) { id } } ; const variables = { update_id: yourUpdateId, file: yourFile }; Here’s an example in Postman as well if you’d like to try this out: Send the request as form-data; Send a POST request to the special File endpoint: https://api.monday.com/v2/file Use the File type for the file; You can use Text inputs for other Keys, and Auto for content-type; In “variables”, you can include your Update ID, or Item + File column IDs. To add the File as a variable, you will need to add another Key to map the variable to another key. In the Map key, you declare the name of the variable, for example, “image”, and then set it as the variable.file. And you should get a result as follows: Always make sure to send your File upload requests with variables to the https://api.monday,com/v2/file Endpoint. Here’s a cURL example as well: curl --location --request POST 'https://api.monday.com/v2/file' \\ --header 'Authorization: yourSuperSecretApiKey' \\ --header 'Cookie: __cfduid=d0359804269ad2a2a33bc1bbbe9d6f18d1612880009' \\ --form 'query="mutation add_file($file: File!, $update_id: Int!) {add_file_to_update(update_id: $update_id, file: $file) {id}}"' \\ --form 'variables="{\\"update_id\\":920768626}"' \\ --form 'map="{\\"image\\":\\"variables.file\\"}"' \\ --form 'image=@"/Users/alexsavchuk/Downloads/300px-All_Right_Then,_Keep_Your_Secrets.jpg"' What about the SDK, you might ask? This has now become easier too 🙂 Developers using our SDK to make requests from View apps that are using seamless auth will now also enjoy seamless file uploads! monday.com will now translate any query into a multipart request IF it detects the request contains files. This means that if you’re adding files as variables, it will just work with zero extra code on your side 🙂 If you are making a direct call from the server-side using the monday.api method, the translation will not work. Instead, we recommend constructing your own HTTP request using a library of your choice.

Troubleshooting Tips & Tricks for issues with the API

Hello awesome dev community! It’s Alex from monday.com’s developer success team again. If you ever find yourself stuck with an API call that just doesn’t seem to be working, this is the right place to be. Today, I wanted to share some general guidelines on how you could troubleshoot an API call to monday.com, and the basic steps to take in order to isolate the behavior further. We’ll go through the following steps together: Troubleshooting an API call on the API playground; Troubleshooting an API call made as an HTTP request; Limitations you should keep in mind Where to get additional help, if all else fails How do I troubleshoot API calls? This guide goes through a few different ways you can troubleshoot your API calls. These are basic steps you can take into account if something doesn’t seem to be working. You can use this guide to figure out the best next course of action. Part 1: The API call does not work in the Developer Playground As a user of monday.com, you have access to a testing environment to play with the API without needing to build their own environment. You can access it by going to the Developers section, found in “My Profile”: You can then choose the Developer Playground in the top menu to enter your account’s API test environment: Here, you can test queries, as well as mutations to see what data each query returns without having to package it in an HTTP request. If your query works in the testing environment, then we know the issue is probably with how you’re sending data to the server. Feel free to scroll right ahead to part 2 🙂 Part 1a: Argument X on field Y has an invalid value. This error means that the server expects a certain type of value (such as a number or text string) but is receiving a different type. Check the data you are trying to pass for that field, and what the server expects (via our documentation). Here’s an example: Since we are sending an integer to a text column, which normally expects Strings, we get an innvalid value error. If we send the same value (3) formatted as a JSON string, that will work: Part 1b: Field X does not exist on Type Y You might be trying to change a value that doesn’t exist, or make a query that doesn’t exist. For example here’s a query that doesn’t work just yet, since the “subitem” argument for board_kind doesn’t exist: Please check the spelling of the fields in the query. Part 1c: Parse Error on X This means there’s an issue with the commas and brackets of the query. Make sure the brackets are balanced and there are commas between the fields of each query 🙂 For example, there is an extra right curly bracket in the query below: Part 1d: 500 Internal Server Error This is a generic error that could be caused by a number of issues with your query – it’s basically a catch-all error for all the other issues that can crop up. If you get an Internal Server Error, check the following: Do you happen to have extra commas or brackets in the query? Is there a chance you are trying to get a board that doesn’t exist? Could it be that your API call is attempting to get an item that doesn’t exist? Or perhaps there’s a chance your API call is querying for a column that doesn’t exist? Part 2: It works in the testing environment, but not in my application 😦 If the query works in the testing environment but is failing in your custom application, there are a few quick troubleshooting steps we can do to ensure you are sending the correct information. Part 2a: Is the query exactly the same as in the testing environment? Sometimes, things can go wrong by accident in the weirdest of places. Sometimes, the query is just not copypasted fully. If you are creating your query through code that dynamically populates a query in your application, it might make sense to first test the exact query you are planning to use in the testing environment. If this works, then we know the issue is in how your data is being sliced-and-diced to generate your final API call. Part 2b: Are you sending the request to the right place? All API requests are sent to our server as an HTTP request. HTTP requests are the basic protocol used for almost all, if not all interactions on the modern internet. Requests to our API must be POST requests (signifying they want to change data). This applies to both queries and mutations. Note: although GET works for some queries, POST is still the best-practice method for this. Sent to https://api.monday.com/v2 for queries and mutations, or the File endpoint if you are trying to upload a file - api.monday.com/v2/file Part 2c: Are you passing the correct headers? HTTP requests are made of two chunks of data – headers and a body. The header contains metadata about the request itself; it tells the server “Heads up! This is the kind of data I’m sending you.” The body is where the actual content of the request is. There are two headers, in particular, that are required to be sent with any API request. One is the “Authorization” header, which supplies the API key, and the other is “Content-Type”, which tells the server the format of the data in the body. Please make sure you are passing the following in as headers: { “Content-Type” : “application/json”, “Authorization” : “mySuperSecretAPIKey” } Part 2d: Is the request body formatted correctly? You will need to make sure you are passing the query correctly. In the Body of your HTTP request, you will need to declare that what you are sending is a “query”, and this applies to both queries (getting data) and mutations (changing data). You will just declare further that the query you are sending is a mutation later down the line. An example of a query to search your board’s items for column values in Postman: In case you are sending a mutation, that has to be included in the body of the API call: Part 2e: I’m still getting an error. Now what? If you’ve followed the above instructions and are still getting an error, there might be a problem with how your query is structured. You can check out the Errors section of our API documentation - perhaps that can help figure out what is going astray. Part 3: Things to be aware of: Part 3a: Unsupported column types: If your API call takes over a minute to process, you will be faced with a timeout. In those cases, try and see if you can reformat the call to be more lightweight - getting the same data in multiple calls via pagination, for example. Another thing to check is making sure that the user that generated your API token has access to the board you are attempting to query. If you receive an empty object as a response from a “boards” query, most likely there is something astray with the access permissions. Some column types are not supported by our API, or are supported to a limited extent. Here is a list that can help you as a reference point: Columns you cannot read or update via the API Progress tracking Auto number column Columns that you can read using a workaround Item ID column – you cannot get the data in the column, but you can check the ID of the item via the API; Last updated column – you can get the time an item was edited via the activity log queries; Creation log column – you can check the creation date of the item via the API; Formula column - you can read the formula configuration (using settings_str), and then calculate the formula values in your application code. Columns without write support TIME TRACKING:. You cannot edit the data, or start/stop the timer. Part 3b: Items_by_column_values limitations: You can not query for null values just yet; It is not possible to query multiple columns at the same time; It is not possible to query for multiple values (for example, array of user IDs to search for in a People column); The items_by_column_values query does not support every single column type. Generally, if a column can contain multiple values (dropdown, people, tags), it cannot be filtered. To populate the Numbers column with a “0” value, you might need to format your column values as a String, and not as an integer. You can also take a look at the Errors section in our documentation to find more info on the errors our API might throw, as well as some general steps you can take to troubleshoot. Part 3c: List dimension mismatch on variable $theboardid and argument ids (Int! / [Int]) At the time, the board IDs field will expect an array/list of Ids. If you are sending a single ID, you’ll need to declare your variable as an array. Here are 2 examples that can illustrate the point a little further: This is an example of a query that won’t work: query ($boardId:Int) { boards (ids:$boardId) { items(ids:162169283) { column_values(ids:"time_tracking") { value } } } } This query will work instead! Notice how the board ID variable is declared as an array of integers with [Int]: query ($boardId:[Int]) { boards (ids:$boardId) { items(ids:162169283) { column_values(ids:"time_tracking") { value } } } } Part 4: Getting additional help If the above steps haven’t solved the issue, please feel free to reach out to us in the community or by using our appsupport@monday.com inbox - we’d be happy to help!

READ THIS FIRST - Useful threads and development resources

Follow this section! It’s a place for the monday dev success team to put feature announcements, helpful examples, and tips. Here is a list of threads that might be helpful for folks designing and building monday apps. This document is a work in progress, and we’ll keep adding to it as y’all share your tips and tricks. Getting started with the basics Here’s some basic documentation to get you started building with the monday apps framework. Intro to monday apps Quickstart guides Code examples API Documentation API webinar Code examples in different languages Here are some code samples for building with specific technologies. Python: Python API integration help Python Code Example: Importing existing Zendesk tickets using the API Python Quickstart Tutorial Moncli - Monday.com client for Python - Third-party library Python library for v2 api on github - Third-party library cURL: cURL Examples for API v2 Uploading a file with cURL NodeJS: Node.js mutation example using Axios Node.js Change multiple column values Accessing and returning data from monday API v2 with Node.js Challenge with node Webhook PHP: POST request using PHP How to validate a Monday.com Webhook in PHP A Basic PHP Webhook Example C#: How to use add_file_to_column in VB.NET (API Call) Basic C# API v2 Example How monday.com works – the nitty gritty Here are some threads that answer common FAQs that developers have. How to upload a file via the API Where to find board, item, and column IDs Differences between client, account, and user IDs Error types thrown How to publish a build Common pitfalls and errors Here’s a list of common errors that developers often run into: Full list of errors GraphQL parsing errors: “-” parsing error Escaping quotations CORS policies File uploads sessionToken usage Unauthorized user Subitem querying limitations Dynamic mapping troubleshooting PowerApps and GraphQL

Guide: Sending an API call via Zapier to get Integration column values!

Hey everyone, Alex here from the Developer Success team! I hope your projects are running smoothly ✨ Ever wanted to make a custom API call inside Zapier? Well, I wanted to share a quick guide with you today that explores the 2 following topics: How to run a custom API query to monday.com using Zapier; How to use that query to get Integration column data (using SalesForce integration column); As you might be aware, currently, our Zapier integration doesn’t allow you to get integration column values. You might be thinking “the What? Column value?” and I’d love to shed a bit more light on this. So… what is the integration column? The Integration Column is a column type that is added for some of the native integrations that monday.com offers, usually for those that are able to sync future changs from the target platform. For example: This column stores information about the object from your Target platform that was created as part of an integration. This helps the platforms communicate to the correct points of data quickly, as there is a match of a monday.com Item to the ID from the other platform. In the screenshot above, it stores data about the Trello card that led to an item being created on your board. Pretty neat! Got it! So how do we get those neat values then? There is a way to get the Integration column data, and you can use the Custom Request and Formatter Modules to get the values you are looking for 🙂 So let’s get started! How to make an API call on Zapier? First, we’ll need to figure out how to make an APi query to monday.com by using Zapier. We can use the Custom Request module for this. You’ll need to make sure it is set up the following way: POST as the method; https://api.monday.com/v2 as the URL; Headers should include: Authorization: [Paste in your API key here]; Content-Type: application/json; The Data field is where you’ll insert your API request: Here is the query that I’ve used in the Data field. You’ll need to make sure your Integration column ID matches the column ID on the platform {“query”:“{boards (ids:BoardId){items (ids:ItemId) {name column_values(ids:"salesforce_object") { value text}}}}”} If you have a previous step in Zapier that relates to monday.com, you can also use the Board and Item ID values from that step. In my screenshot example, the first Zap would trigger when an update on monday.com board is posted, and I could then use those IDs to query that specific item’s integration column. Making those values usable - How to apply Formatter to the output. The result is a JSON string, and we’ll need to take an extra step here to get the SalesForce object ID that we can work with. We can get the value we are looking for by using Zapier Formatter. Now, choose the Formatter Module, then the Text Action: In the next step, we’re going to want to Split text. This will allow us to use the overall output of the API request to get meaningful chunks of data: The input should reflect the data returned by the API Query from earlier: As your Separator, use quotes: Then, use All (as Separate Fields) as the separation option: The final output should provide you with the following set of items: You’ll then be able to use those items in your Zap’s next steps: Good luck! I hope this helps you if you’re just starting out with Zapier, or already a heavy user and looking to expand on the options we currently provide.

Introducing: Simple Column Values for API

Hey everyone! 🚀 You can now use strings when sending data to a particular column instead of formatting it as a JSON. This is particularly useful when updating simple columns such as text or status columns. You can find all the documentation for this on our developer page. Using a status column as an example, you would now be able to use either "Done" or "0" as your value for updating the status. If you still prefer to send it as a JSON string, those mutations remain unchanged: "{\\"label\\":\\"Done\\"}" One additional thing to note is you can mix these! This means your query can use both simple values and JSON values. Here’s how it would look when used in a change column value mutation: mutation { change_simple_column_value (board_id: xxxxxx, item_id: xxxxx, column_id: "status", value: "Done") { id } } And the create item mutation: mutation { create_item(board_id: xxxxxx, item_name: "My Item", column_values: "{\\"status\\": \\"Done\\" }") { id } } You will mainly be using this new feature in 2 scenarios - when updating the value of an item using the change_column_value mutation, or when creating a new item by using the create_item mutation and setting its values on creation. The following columns currently support being updated with a simple column value: Date column Dropdown column Email column Link column Long text column Number column People column Phone column Status column Text column If you try and send a simple string to a column which does not currently support it, the server will reply with a message explaining the problem: “error_message”: “column type CountryColumn is not supporting changing the column value with simple column value, please check our API documentation for the correct data structure for this column. https://monday.com/developers/v2#column-values-section”, Hope this is useful for everyone! If you have any questions let us know below. -Daniel

Feature Release Updates!

Hey app builders! We release great new functionality to the app framework and I wanted to share with you about it so you can start building some more amazing stuff! Item View: This new capability of the monday Apps Framework gives the ability to create new item views, which will be placed next to “Updates”, “Info Boxes” and “Activity Log” tab: User can add new item views with help of “Add view” button. This button will appear if there is at least one item view in the account, and in the future will appear for all users. Once an item view was added it will be added to all of the items in the board. Building an Item view is the same as building board views and dashboard widget but it gets a different context of a specific Item view: // Item view context { "boardId" : 12345, "itemId" : 123456 } You can learn about how to build your item view here: https://monday.com/developers/apps/quickstart-view Workspace Template: Workspace Templates allows you to create a template out of a workspace in your account. After installing your app, users can add the template from the template center to their account: You can add all of your app feature to the template and they will be duplicated as part of the template. It’s a great way to package all of your app features to a monday workflow to make it easier to start using your app features and to show best practices on how to set it up. All of the settings of the views, configuration of the integration recipes will be duplicated as well. It can have a pretty extend configuration, which includes the solution “on boarding” experience after user uses it from the template store. You can configure which workspace will become a template, which board and view of this workspace user will be landed after the duplication process, and even the view mode for it (vertical split or fullscreen). You can also add all of the information that will appear in the template center so users can easily understand when and how to use this template. Item Mapping: This is an enhancement to our integration recipes. Item mapping allow you to sync external fields of an external entity to a monday item and all of it’s columns. For example sync a lead in salesforce with a monday item. You can allow the user that is adding your integration recipe to the board, to map the field that he cares about to the his columns. That way you can create one recipe that each user can use differently and adjust it to his boards and data. For example map the fields form a zendesk ticket to an item: And after adding this recipe the user can map the field: In order to use item mapping you need to create a new field type - dynamic mapping. When you will add this field to a recipe sentence, it will show the user the mapping screen between the fields. You need to provide the field definition url that will return a list of field that are supported in the external service and their primitive type in order to show the relevant options to the user that is configuring the integration. You can learn how to set it up here: https://monday.com/developers/apps/dynamic-mapping Good luck and looking to hear some feedback and questions!