Migration guide - 2023-10
A guide to help developers migrate to monday API version 2023-10
Version 2023-10 contains a number of changes to improve the scalability and reliability of the monday GraphQL API. Many of these changes are breaking, which means you'll need to migrate your applications to use a slightly different query structure when making your calls.
This guide is long; use the table of contents on the right to skip to the information you need.
General information
Why is your API changing?
We've migrated our platform to a new data infrastructure called mondayDB, to support the next level of scale in our platform. We know that our customers are using monday in larger and larger workflows, and we want to design our system to support them.
Not only will the new API be faster, but it also has a rich sorting and filtering layer. In the past applications would have to implement board filtering themselves, but now it's handled by the API.
What do I need to do?
Application developers
Review the changes to the API and migrate your apps to use the new API correctly. Read on to see some common application patterns and learn how they should be updated.
Account admins
Review the applications that are using the API and ensure that you have a migration plan for each:
- Marketplace applications - will be updated by the developer, most apps will likely not require any changes from you
- Internally developed applications - will need to rewrite some of the code to use our new APIs
- Zapier, Make, and other 3rd party connectors - may require updates, pending implementation by the integration developer
Users of 3rd party integration tools like Zapier and Make
Third-party integration providers like Make, Zapier, and Workato are currently updating their connectors. They will send you communication on what updates your workflows will need.
If you're making direct GraphQL queries with these tools, you will need to review your queries and update them.
What's changing?
Major changes: These are the changes that will affect most applications and API users.
- Queries that use
items
on the group- or board-level must nest them in theitems_page
object - Queries that use
items_by_column_values
must now useitems_page_by_column_values
- Deprecated:
text
field returns empty values for mirror, dependency and connect boards columns when using the genericcolumn_values
object. You should retrieve this data using thedisplay_value
field instead.
Minor changes: These are changes that will affect some applications.
- Required argument:
column_type
argument is now required when creating a column - Type changed:
type
field oncolumn
object is now ColumnType, not string - Type changed: All IDs now use the ID type, not Int
- Updated: fields on the
column_values
object have changed - Deprecated:
pos
field onboards
andcolumns
objects - Deprecated:
newest_first
argument onboards
object. Use theorder_by
argument instead.
Bug fixes: We fixed some bugs, resulting in new errors and breaking behaviour:
- Empty parentheses will now return an error
- String arguments that are not surrounded by quotation marks will return an error
Timeline
July 2023 – version 2023-10 is announced and available for preview
October 2023 – version 2023-10 becomes stable (no new changes), but 2023-07 will still be used by default
January 2024 – version 2023-07 is no longer supported
Common patterns that need to be migrated:
We've compiled a list of some common patterns used in monday apps and how to migrate each one. Click an option to skip to the relevant section.
- Queries that return lots of items and need to use pagination
- Applications using the
items_by_column_values
query - Any query that retrieves the value of Mirror, Connect Boards, or Dependency columns
- Applications that return the whole board for in-app filtering and sorting
- Applications that query large amounts of board data for aggregation and other data manipulation
Testing and development
Previewing version 2023-10
You can test the new version of the API in two ways:
- Using the version selection button in the API playground (instructions)
- Passing the following header in your HTTP requests:
API-Version: 2023-10
(instructions)
Getting help
If you have questions about the new version or the migration process, please let us know! You can submit feedback using this form or post questions in our developer community:
- Sign up for an account at community.monday.com
- Navigate to the "monday apps & developers" section
- Post a new topic
Case 1: Queries that use pagination
Offset pagination (old method)
In version 2023-07, you would return pages of items like this:
query {
boards (ids: 4579863192) {
items (page:1, limit:5) {
id
}
}
}
{
"data": {
"boards": [
{
"items": [
{
"id": "4579863854"
},
{
"id": "4579863873"
},
{
"id": "4579863895"
},
{
"id": "4579863910"
},
{
"id": "4579863934"
}
]
}
]
},
"account_id": 1111111
}
Cursor pagination (new method)
In 2023-10, you need to use the new items_page
object, which represents a filtered set of items retrieved from the monday database. You can return a cursor
value which points to the next page of results and can be used to paginate through large data sets. When there are no more results, the cursor will be null.
query {
boards (ids: 4579863192) {
items_page (limit: 5) {
cursor
items {
id
}
}
}
}
{
"data": {
"boards": [
{
"items_page": {
"cursor": "MSw0NTc5ODYzMTkyLFRWX2ljOWt2MVpnTjFjelRadUR3Vyw3LDV8MTIyMTY3OTk4OA",
"items": [
{
"id": "4579863854"
},
{
"id": "4579863873"
},
{
"id": "4579863895"
},
{
"id": "4579863910"
},
{
"id": "4579863934"
}
]
}
}
]
},
"account_id": 111111
}
Querying items_page
can have a high complexity cost since it must be nested within a boards
query. To save on complexity, you can use the next_items_page
object at the root of your query and pass the cursor
argument to return the next page.
query {
next_items_page (limit: 5, cursor:"MSw0NTc5ODYzMTkyLFRWX2ljOWt2MVpnTjFjelRadUR3Vyw3LDV8MTIyMTY3OTk4OA") {
cursor
items {
id
}
}
}
{
"data": {
"next_items_page": {
"cursor": null,
"items": [
{
"id": "9876543210"
}
]
}
},
"account_id": 1234567
}
Here is a Javascript implementation of pagination with the cursor object and next_items_page
:
import mondaySdk from "monday-sdk-js";
const monday = mondaySdk();
monday.setApiVersion('2023-10');
async function itemspageWithLimit() {
const currentBoardId = 3944151369;
const firstPage = await monday.api(
`query {
boards (ids: ${currentBoardId}) {
items_page (limit:1) {
cursor
items {
id
}
}
}
}`,
{ apiVersion: "2023-10" }
);
const firstPageItems = firstPage.data.boards[0].items_page.items;
var cursor = firstPage.data.boards[0].items_page.cursor;
while (cursor) {
// loop will stop when cursor is null
const nextPage = await monday.api(
`query {
next_items_page (limit:1, cursor: "${cursor}") {
cursor
items {
id
}
}
}`,
{ apiVersion: "2023-10" }
);
const thisPage = nextPage.data.next_items_page.items;
cursor = nextPage.data.next_items_page.cursor;
}
console.log("All items retrieved");
}
Case 2: Applications that use items_by_column_values
items_by_column_values
The previous API had an items_by_column_values
and items_by_multiple_column_values
query to return items that matched a specific column value.
In version 2023-10 you should use the new items_page_by_column_values
query(which takes the same data as items_by_column_values
). Here's an example that returns items whose status is "Done":
query {
items_page_by_column_values(
board_id:4892484081,
columns:[{column_id: "status", column_values: "Done"}]
) {
items {
id
}
}
}
query {
complexity {
query
}
items_by_column_values(board_id:4892484081, column_id:"status", column_value:"Done") {
id
}
}
Case 3: Applications reading the Connect Boards, Dependency, or Mirror column
In the past, you could only retrieve the ID of items that are linked in a Connect Boards or Dependency column. You would need to make another API call to look up the linked items by their ID.
text
field will return null, use display_value
to get stringified data
text
field will return null, use display_value
to get stringified dataIn 2023-10
, the text
field will return null for all Connect Boards, Dependency, and Mirror columns.
Use a frasgment and specify the display_value
instead:
query {
boards (ids:4892484081) {
items_page(limit:5) {
items {
id
column_values {
id
...on DependencyValue {
display_value
}
...on MirrorValue {
display_value
}
...on BoardRelationValue {
display_value
}
}
}
}
}
}
If you want to get really fancy, you can also use an alias to rename display_value
to "text", so you can parse the data the same way. This will not work if you use the text
field in another part of your query.
query {
items (ids:872058183) {
column_values {
...on BoardRelationValue {
text: display_value
}
}
}
}
{
"data": {
"items": [
{
"column_values": [
{
"id": "connect_boards",
"text": "Item 1, Item 2, Item 3"
}
]
}
]
},
"account_id": 1825528
}
Using linked_items
to retrieve rich item data
linked_items
to retrieve rich item dataNow you can use the linked_items
field to query the linked items in the same API call. Here is an example:
query {
boards (ids:4892484081) {
items_page(limit:5) {
items {
id
column_values {
...on DependencyValue {
Dependencies: linked_items {
name
id
}
}
}
}
}
}
}
query {
boards (ids:4892484081) {
items_page(limit:5) {
items {
id
column_values {
...on BoardRelationValue {
LinkedItems: linked_items {
name
id
}
}
}
}
}
}
}
If you're using the Mirror column, now you can use the MirrorValue
interface that exposes data on the linked items:
query {
complexity {
query
}
boards (ids:4892484081) {
items_page(limit:5) {
items {
id
column_values {
...on MirrorValue {
MirroredItems: mirrored_items {
linked_board_id
}
}
}
}
}
}
}
Case 4: Applications that return the whole board for filtering or sorting
The old API didn't have a robust filtering or sorting capabilities. As a workaround, many applications would retrieve the whole board's data and filter/sort inside their application code.
Now, items_page
exposes a rich filtering and sorting layer. You can ask monday to do the sorting for you, and just retrieve the relevant results.
If your application is currently retrieving the board to do its own filtering, you should instead using the filtering available in item_page
.
Filtering for a single column value
You can filter for items matching a specific value in a specific column, by adding a set of rules
to the query_params
argument. This query looks for items that have "Project Alpha" in the "text" column.
query {
boards (ids:4877868371) {
items_page (
query_params: {
rules: [
{
column_id: "text",
compare_value: ["Project Alpha"],
operator: any_of
},
],
operator: or
},
) {
items {
name
}
}
}
}
Filtering for text matches
You can filter for items that contain a specific substring, using the contains_text
operator. This returns all items that contain the string "Project" in the "text" column.
query {
boards (ids:4877868371) {
items_page (
query_params: {
rules: [
{
column_id: "text",
compare_value: ["Project"],
operator: contains_text
},
]
},
) {
items {
name
}
}
}
}
Filtering by date range
You can return items whose dates are between two values, using the between
operator:
query {
boards (ids:4877868371) {
items_page (
query_params: {
rules: [
{
column_id: "date4",
compare_value: ["2023-07-01", "2023-07-30"],
operator: between
}
]
}
) {
items {
name
}
}
}
}
Filtering for relative dates
You can filter for relative dates using keywords like "TODAY", "YESTERDAY", "ONE_MONTH_FROM_NOW" and more:
query {
boards (ids:4877868371) {
items_page (
query_params: {
rules: [
{
column_id: "date4",
compare_value: ["TODAY", "YESTERDAY"],
operator: any_of
}
]
}
) {
items {
name
}
}
}
}
Filtering for multiple static values
You can return items that match one or more static values by sending a list of items as the compare_value
:
query {
boards (ids:4877868371) {
items_page (
query_params: {
rules: [
{
column_id: "text",
compare_value: ["Vinod", "Susan"],
operator: any_of
}
]
}
) {
items {
name
}
}
}
}
Multiple filter rules
You can filter for multiple rules at a time. Notice each rule has an operator, and the query as a whole has one too:
query {
boards (ids:4877868371) {
items_page (
query_params: {
rules: [
{
column_id: "text",
compare_value: ["Vinod"],
operator: any_of
},
{
column_id: "date4",
compare_value: ["TODAY"],
operator: any_of
}
],
operator: or
},
) {
items {
name
}
}
}
}
Sorting by a single column
You can sort the item set by its column values, including with mutliple sort criteria (subsorts):
query {
boards (ids:4877868371) {
items_page(query_params: {
order_by: [
{column_id:"numbers_1", direction: asc}
]
}) {
items {
id
name
}
}
}
}
Sorting multiple columns (subsorts)
You can also sort by multiple columns. The sequence of the OrderBy
arguments will determine which sort is applied first.
query {
boards (ids:4877868371) {
items_page(query_params: {
order_by: [
{column_id:"status", direction: desc},
{column_id:"numbers", direction: asc}
]
}) {
items {
id
}
}
}
}
Case 5: Returning the whole board for data aggregation
The items_page
object will return a maximum of 100 items at a time. If you need to get all the data from a single board, you will need to use cursor-based pagination.
You can see some examples of using cursor pagination in section 1 of this guide: Cursor Pagination
Case 6: Apps written in any strongly-typed language - TypeScript, Python, Java, etc.
Version 2023-10 has some type changes to improve the consistency of our GraphQL API.
Specifically, we aligned our schema so all fields representing numerical IDs now use the ID
type. As a return value, it's expressed as a string. When used in an argument (input), it accepts either string or integer values.
If your app is strongly typed, your code may throw an error when this type changes because your application will expect an integer but receive a string.
To solve this, please review your API calls to check if you use any affected fields. Then, ensure your code accepts both integer and string values.
Note: Even though you could convert the strings to integers, we don't recommend it, as the structure of these IDs may change in the future.
Case 7: Apps using create_column
mutation
create_column
mutationThe create_column
mutation now takes a column_type
argument that specifies what kind of column is created.
In 2023-07, the column type argument was a string and inconsistent between query and mutations. For example, querying the checkbox column would return Checkbox
as its type, but you'd need to send boolean
as the column type to create it.
In 2023-10, we've aligned all the column types into consistent enum values.
Apps that used the string value in the past now need to use the enum value. We've compiled this table that lists every column and its corresponding string and enum values: Columns migration reference
Updated 5 days ago