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, so 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.
No more extensions
As of March 5th, customers can no longer request an extension. All customers must migrate to a new API version as we near the March 18th deadline.
General information
Rationale
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.
Migration steps
Application developers
Review the changes to the API and adjust your applications to use version 2023-10 or later.
A fully-migrated app will:
- Use the
API-Version
header in all API calls - Specify an API version of 2023-10 or later (2024-01, 2024-04, etc)
- Make API calls to the new version with no errors
Account admins
Review the applications that are using the API and ensure that you have a migration plan for each:
- Marketplace applications - It is the app developer's responsibility to update their apps. Most apps will likely not require any workflow changes from you
- Internally developed applications - Your developers 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.
Summary of changes
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 by querying thedisplay_value
field through the relevant implementation (i.e.,MirrorValue
,DependencyValue
, orBoardRelationValue
.
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, so bad API calls will now return more descriptive errors:
- 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
15 January 2024 (gradual release) – version 2023-07 is no longer supported, 2024-01 is API default
Common patterns & usage
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.
- Pagination – any queries that return more than 500 items
- Apps using the
items_by_column_values
query - Any query that retrieves the value of Mirror, Connect Boards, or Dependency columns
- Apps that return the whole board for in-app filtering and sorting
- Apps that query large amounts of board data for aggregation and other data manipulation
- Apps using strongly-typed languages
- Apps using the create_column mutation
Testing and development
Previewing version 2023-10
You can use 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) - Using the
setApiVersion('2024-01')
method in the Javascript SDK (instructions).
Getting help
If you have questions about the new version or the migration process, please let us know in our developer community:
- Sign up for an account at community.monday.com
- Navigate to the "monday apps & developers" section
- Post a new topic
Cursor 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");
}
Migrating the items_by_column_values
query
items_by_column_values
queryThe 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
}
}
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
}
}
}
}
}
}
}
Filtering and sorting with items_page
items_page
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
}
}
}
}
Returning the whole board for data aggregation
The items_page
object will return a maximum of 500 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
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.
Using the 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 about 2 months ago