Learn how to read, create, update, and delete boards using the platform API
monday.com boards are where users input all of their data, making them a core component of the platform. The board's structure consists of items(rows), groups (groups of rows), and columns, and the board's data is stored in items and their respective updates sections.
Queries
Get boards
- Required scope:
boards:read - Returns an array containing metadata about one or a collection of boards
- Can be queried directly at the root or nested within another query (e.g.,
items)
query {
boards(
ids: [1234567890]
hierarchy_types: [classic, multi_level]
) {
name
state
permissions
items_page {
items {
id
name
}
}
}
}import { ApiClient } from "@mondaydotcomorg/api";
const mondayApiClient = new ApiClient({ token: myToken});
const query = `query { boards (ids: [1234567890]) { name state permissions items_page { items { id name }}}}`
const response = await mondayApiClient.request(query);Arguments
| Argument | Type | Description | Enum Values |
|---|---|---|---|
| board_kind | BoardKind | The type of board to return. | privatepublicshare |
| hierarchy_type | [BoardHierarchy!] | The board hierarchy type to filter by. If omitted, only classic boards will be returned unless specific board IDs are provided. | classicmulti_level |
| ids | [ID!] | The specific board IDs to return. | |
| limit | Int | The number of boards to return. The default is 25. | |
| order_by | BoardsOrderBy | The order in which to retrieve your boards. | created_at (desc.)used_at (desc.) |
| page | Int | The page number to return. Starts at 1. | |
| state | State | The state of the board to return. The default is active. | activeallarchived deleted |
| workspace_ids | [ID] | The specific workspace IDs that contain the boards to return. |
Fields
| Field | Type | Description | Enum Values |
|---|---|---|---|
| access_level | BoardAccessLevel! | The user's board permission level. | editview |
| activity_log | BoardActivityLogsPage | Returns a page of the board's activity log events. Only available in versions 2026-10 and later. | |
| activity_logs | [ActivityLogType] | The activity log events for the queried board(s). | |
| board_folder_id | ID | The unique identifier of the folder that contains the board(s). Returns null if the board is not in a folder. | |
| board_kind | BoardKind! | The board's type. | privatepublicshare |
| columns | [Column] | The board's visible columns. | |
| communication | JSON | The board's communication value (typically a meeting ID). | |
| creator | User! | The board's creator. | |
| description | String | The board's description. | |
| groups | [Group] | The board's visible groups. | |
| hierarchy_type | BoardHierarchy | The board's hierarchy type. | classicmulti_level |
| id | ID! | The board's unique identifier. | |
| item_terminology | String | The nickname for items on the board. Can be a predefined or custom value. | |
| items_count | Int | The number of items on the board. | |
| items_page | ItemsResponse! | The board's items. Can be used to retrieve all items on a board. | |
| name | String! | The board's name. | |
| object_type_unique_key | String | A unique identifier for the board's object type. May return null for boards without a specific object type classification. | |
| owner (DEPRECATED) | User! | The user who created the board. | |
| owners | [User]! | The board's owners. | |
| permissions | String! | The board's permissions. | assigneecollaboratorseveryoneowners |
| state | State! | The board's state. | activeallarchiveddeleted |
| subscribers | [User]! | The board's subscribers. | |
| tags | [Tag] | The board's tags. | |
| team_owners | [Team!] | The board's team owners. | |
| team_subscribers | [Team!] | The board's team subscribers. A value of -1 indicates that the "everyone at account" team is subscribed to this board. | |
| top_group | Group! | The group at the top of the board. | |
| type | BoardObjectType | The board's object type. | boardcustom_objectdocumentsub_items_board |
| updated_at | ISO8601DateTime | The last time the board was updated. | |
| updates | [Update] | The board's updates. | |
| url | String! | The board's URL. | |
| views | [BoardView] | The board's views. | |
| workspace | Workspace | The workspace that contains the board. Returns null for the Main workspace. | |
| workspace_id | ID | The unique identifier of the board's workspace. Returns null for the Main workspace. | |
| created_from_board_id | ID | The unique identifier of the source board this board was created from (e.g., when duplicated). Returns null if the board was not created from another board. Only available in versions 2026-04 and later. | |
| folder | Folder | The folder containing this board. Returns null if the board is not in a folder. Only available in versions 2026-04 and later. | |
| inferred_metadata | BoardInferredMetadata | Inferred metadata for the board (for example, custom terminology for items). Only available in versions 2026-07 and later. | |
| manual_metadata | BoardManualMetadata | Manually set metadata for the board (for example, markdown describing the board). Only available in versions 2026-07 and later. |
Get export job status
Only available in API versions
2026-10and later
- 🚧 Only available for Enterprise plans
- Required scope:
boards:read - Returns the current state of an async board export as
ExportJobStatusInfo, ornull - Use it to poll a
job_idreturned bycreate_board_export
query {
export_job_status(job_id: "a1b2c3d4-0000-0000-0000-000000000000") {
status
download_url
failure_reason
failure_message
}
}import { ApiClient } from "@mondaydotcomorg/api";
const mondayApiClient = new ApiClient({ token: myToken });
const query = `query ($job: ID!) { export_job_status (job_id: $job) { status download_url failure_reason failure_message }}`
const variables = {
job: "a1b2c3d4-0000-0000-0000-000000000000"
}
const response = await mondayApiClient.request(query, variables);Arguments
| Argument | Type | Description |
|---|---|---|
| job_id | ID! | The job_id returned by create_board_export. |
Polling
Poll until status is one of the terminal values — COMPLETED, FAILED, or CANCELLED:
COMPLETED— readdownload_url. It can still benullif you poll after the URL has expired, so check before using it.FAILED— readfailure_reason(andfailure_messagewhen present).RUNNING— wait and poll again.
Back off between polls rather than polling in a tight loop; every call counts against your rate limits. Large exports can take minutes, so set a timeout in your own client rather than polling indefinitely.
A
nullresult does not mean the job failed. This query returnsnullfor ajob_idthat does not exist and for one that belongs to a different account — the two are deliberately indistinguishable, so an ID that leaks cannot be used to probe for other accounts' exports. If you getnullfor an ID you just received, check that you are querying with the same account's token.
Mutations
Required scope: boards:write
Create board
Creates a new board. Returns Board.
The user who creates the board is automatically added as a board owner when creating a private or shareable board or if board_owners_ids is not provided.
This mutation has an additional rate limit of 40 mutations per minute.
mutation {
create_board(
board_name: "my board"
board_kind: public
item_nickname: { preset_type: "item" }
) {
id
}
}Arguments
| Argument | Type | Description | Enum Values |
|---|---|---|---|
| board_kind | BoardKind! | The type of board to create. | privatepublic share |
| board_name | String! | The new board's name. | |
| board_owner_ids | [ID!] | A list of the IDs of the users who will be board owners. | |
| board_owner_team_ids | [ID!] | A list of the IDs of the teams that will be board owners. | |
| board_subscriber_ids | [ID!] | A list of the IDs of the users who will subscribe to the board. | |
| board_subscriber_teams_ids | [ID!] | A list of the IDs of the teams that will subscribe to the board. | |
| description | String | The new board's description. | |
| empty | Boolean | Creates an empty board without any default items. | |
| folder_id | ID | The board's folder ID. | |
| item_nickname | ItemNicknameInput | The nickname configuration for items on the board. When provided, the configuration is applied to the new board's items. | |
| template_id | ID | The board's template ID.* | |
| workspace_id | ID | The board's workspace ID. | |
| prompt | String | An AI prompt to generate the board's structure and content (columns, groups, items). Only available in versions 2026-04 and later. | |
| use_mls_template | Boolean | When true, creates the board as a multi-level board using the MLS template. Only available in versions 2026-10 and later. | |
| use_dataset_template | Boolean | When true, creates the board from the dataset template. Only available in versions 2026-10 and later. |
*You can see your personal template IDs in the template preview screen by activating Developer Mode in monday.labs. For built-in templates, the template ID will be the board ID of the board created from the template.
Change board kind
Changes the privacy kind (public, private, or shareable) of a board. Returns ChangeBoardKindResult.
Only available in API versions
2026-10and later
mutation {
change_board_kind(
board_id: 1234567890
kind: PRIVATE
) {
id
board_kind
}
}import { ApiClient } from "@mondaydotcomorg/api";
const mondayApiClient = new ApiClient({ token: myToken });
const query = `mutation ($board: ID!, $kind: BoardKindInput!) { change_board_kind(board_id: $board, kind: $kind) { id board_kind }}`
const variables = {
board: 1234567890,
kind: "PRIVATE"
}
const response = await mondayApiClient.request(query, variables);Arguments
| Argument | Type | Description | Enum Values |
|---|---|---|---|
| board_id | ID! | The board's unique identifier. | |
| kind | BoardKindInput! | The board's new privacy kind. | PRIVATEPUBLICSHARE |
Fields
| Field | Type | Description | Enum Values |
|---|---|---|---|
| id | ID! | The board's unique identifier. | |
| board_kind | String! | The board's new privacy kind. |
Set board permission
Sets or updates a board's default role/permissions. Returns SetBoardPermissionResponse.
This mutation only works for board owners on an Enterprise plan.
mutation {
set_board_permission(
board_id: 1234567890
basic_role_name: viewer
) {
edit_permissions
failed_actions
}
}Arguments
| Argument | Type | Description | Enum values |
|---|---|---|---|
| basic_role_name | BoardBasicRoleName! | The role's name. | contributor (can edit content)editor (can edit content and structure)viewer (read-only) |
| board_id | ID! | The board's unique identifier. | |
| cross_product_collaborative | Boolean | When true, enables cross-product collaboration permissions for the board. Only available in versions 2026-07 and later. |
Update teams board role
Updates the board role for one or more teams that are already subscribed to the board. Returns UpdateTeamsBoardRoleResponse.
Only available in API versions
2026-10and later
Teams must already be subscribed to the board — this mutation changes a team's role, it doesn't grant board access. Use
add_teams_to_boardfirst to subscribe a team.
mutation {
update_teams_board_role(
board_id: 1234567890
team_ids: [11111111, 22222222]
role_name: editor
) {
successful_team_ids
failed_teams {
team_id
error
}
}
}import { ApiClient } from "@mondaydotcomorg/api";
const mondayApiClient = new ApiClient({ token: myToken });
const query = `mutation ($board: ID!, $teams: [ID!]!, $role: BoardBasicRoleName!) { update_teams_board_role(board_id: $board, team_ids: $teams, role_name: $role) { successful_team_ids failed_teams { team_id error } }}`
const variables = {
board: 1234567890,
teams: ["11111111", "22222222"],
role: "editor"
}
const response = await mondayApiClient.request(query, variables);Arguments
| Argument | Type | Description | Enum Values |
|---|---|---|---|
| board_id | ID! | The board's unique identifier. | |
| role_name | BoardBasicRoleName! | The role to assign to the teams. assigned_contributor and member are rejected — the former depends on assignee-column configuration only settable in the UI, and the latter is agent-user only. | contributor (can edit content)editor (can edit content and structure)viewer (read-only) |
| team_ids | [ID!]! | The IDs of the teams to update. Teams not already subscribed to the board are returned in failed_teams rather than being granted access. Limited to 50 teams per call. |
Fields
| Field | Type | Description | Enum Values |
|---|---|---|---|
| successful_team_ids | [ID!]! | The IDs of the teams whose board role was successfully updated. | |
| failed_teams | [FailedTeamBoardRoleUpdate!]! | The teams whose board role could not be updated, with the reason for each failure. |
Duplicate board
Duplicates a board with all of its items and groups to a specific workspace or folder. Returns Board.
An asynchronous duplication process may take some time to complete, so the query may initially return partial data.
This mutation has an additional rate limit of 40 mutations per minute.
mutation {
duplicate_board(
board_id: 1234567890
duplicate_type: duplicate_board_with_structure
) {
board {
id
}
}
}import { ApiClient } from "@mondaydotcomorg/api";
const mondayApiClient = new ApiClient({ token: myToken });
const query = `mutation ($board: ID!) { duplicate_board(board_id: $board, duplicate_type: duplicate_board_with_structure) { board { id }}}`
const variables = {
board: 9571351437
}
const response = await mondayApiClient.request(query, variables);Arguments
| Argument | Type | Description | Enum Values |
|---|---|---|---|
| board_id | ID! | The board's unique identifier. | |
| board_name | String | The board's name. If omitted, it will be automatically generated. | |
| duplicate_type | DuplicateBoardType! | The duplication type. | duplicate_board_with_pulses (duplicate structure and items)duplicate_board_with_pulses_and_updates (duplicate structure, items, and updates)duplicate_board_with_structure (duplicate structure) |
| folder_id | ID | The destination folder within the destination workspace. Required if you are duplicating to another workspace. If omitted, it will default to the original board's folder. | |
| keep_subscribers | Boolean | Whether to duplicate the subscribers to the new board. Defaults to false. | |
| workspace_id | ID | The destination workspace. If omitted, it will default to the original board's workspace. |
Update board
Updates a board. Returns a JSON object that confirms whether the update was successful and returns the updated board metadata.
mutation {
update_board(
board_id: 1234567890
board_attribute: description
new_value: "This is my new description"
)
}import { ApiClient } from "@mondaydotcomorg/api";
const mondayApiClient = new ApiClient({ token: myToken });
const query = `mutation ($desc: String!) { update_board (board_id: 1234567890, board_attribute: description, new_value: $desc)}`
const variables = {
desc: "This is my new description"
}
const response = await mondayApiClient.request(query, variables);Arguments
| Argument | Type | Description | Enum Values |
|---|---|---|---|
| board_attribute | BoardAttributes! | The board's attribute to update. | communicationdescriptionitem_nickname (version 2026-04 and later)name |
| board_id | ID! | The board's unique identifier. | |
| new_value | String! | The new attribute value. |
Update board hierarchy
Updates a board's position, workspace, or product. Returns UpdateBoardHierarchyResult.
mutation {
update_board_hierarchy(
board_id: 1234567890,
attributes: {
account_product_id: 54321
workspace_id: 12345
folder_id: 9876543210
position: {
object_id: "15",
object_type: Overview,
is_after: true
}
}
) {
success
}
}Arguments
| Argument | Type | Description |
|---|---|---|
| attributes | UpdateBoardHierarchyAttributesInput! | The board's attributes to update. |
| board_id | ID! | The board's unique identifier. |
Archive board
Archives a board. Returns Board.
mutation {
archive_board(
board_id: 1234567890
) {
id
}
}import { ApiClient } from "@mondaydotcomorg/api";
const mondayApiClient = new ApiClient({ token: myToken });
const query = `mutation ($board: ID!) { archive_board (board_id: $board) { id }}`
const variables = {
board: 1234567
}
const response = await mondayApiClient.request(query, variables);Arguments
| Argument | Type | Description |
|---|---|---|
| board_id | ID! | The board's unique identifier. |
Delete board
Deletes a board. Returns Board.
mutation {
delete_board(
board_id: 1234567890
) {
id
}
}import { ApiClient } from "@mondaydotcomorg/api";
const mondayApiClient = new ApiClient({ token: myToken });
const query = `mutation ($board: ID!) { delete_board (board_id: $board) { id }}`
const variables = {
board: 1234567
}
const response = await mondayApiClient.request(query, variables);Arguments
| Argument | Type | Description |
|---|---|---|
| board_id | ID! | The board's unique identifier. |
Create board export
Only available in API versions
2026-10and later
- 🚧 Only available for Enterprise plans
- Required scope:
boards:read(notboards:write— this mutation only reads board data) - Exports a board to a CSV file and returns
ExportResult - The exported file is always CSV
This mutation returns one of two different types, and your query must handle both.
Small boards usually finish immediately and return
ExportFilewith adownload_url. Larger ones returnExportAsyncJobwith ajob_idyou then poll.Which one you get is not part of the contract. It depends on board size and current server load, and the thresholds can be retuned without notice — so the same board can return
ExportFiletoday andExportAsyncJobtomorrow. A client that selects only one branch will break. Always select both.
mutation {
create_board_export(
board_id: 1234567890
export_options: { include_subitems: true, header_row: COLUMN_ID, columns_order: ["name", "status", "date4"] }
time_zone: "America/New_York"
) {
... on ExportFile {
download_url
expires_at
}
... on ExportAsyncJob {
job_id
}
}
}import { ApiClient } from "@mondaydotcomorg/api";
const mondayApiClient = new ApiClient({ token: myToken });
const query = `mutation ($board: ID!) { create_board_export (board_id: $board) { ... on ExportFile { download_url expires_at } ... on ExportAsyncJob { job_id }}}`
const variables = {
board: 1234567890
}
const response = await mondayApiClient.request(query, variables);
const result = response.create_board_export;
if (result.download_url) {
// Finished synchronously — download it now.
} else {
// Still running — poll export_job_status with result.job_id.
}Arguments
| Argument | Type | Description |
|---|---|---|
| board_id | ID! | The unique identifier of the board to export. |
| export_options | CreateBoardExportOptionsInput | Export configuration (subitems, header format, column order, and so on). Omit for defaults. |
| time_zone | String | IANA time zone used to format date and time values, for example America/New_York. Defaults to the time zone of the user whose token made the request, and to UTC if that user has none set. |
export_options.columns_orderselects columns as well as ordering them. Any column you do not list is left out of the export entirely — it is not appended at the end. To reorder a board without losing columns, list every column ID you want.The item name and subitems columns are the exception: they are always placed first, whether or not you list them.
Returns
ExportResult — a union of:
| Type | When | What to do |
|---|---|---|
ExportFile | The export finished in time | Download download_url before expires_at. |
ExportAsyncJob | The export is still running | Poll export_job_status with job_id until the status is terminal. |
Use __typename if you would rather branch explicitly than infer the branch from which fields came back:
mutation {
create_board_export(board_id: 1234567890) {
__typename
... on ExportFile { download_url }
... on ExportAsyncJob { job_id }
}
}Errors
The result has no error branch. Failures reach you one of two ways:
- As a GraphQL error, if the request is rejected before the export starts — for example an invalid
board_id, missing permissions, or an unsupported combination of export options. Accounts that are not on an Enterprise plan are rejected here with theFORBIDDEN_EXCEPTIONerror code. - As a
FAILEDstatus onexport_job_status, if an async export fails after starting. ReadExportFailureReasonto find out why.
Download URLs
download_url is a presigned URL and expires. Treat it as a secret — anyone who has it can download the file until it expires. It cannot be refreshed: once it expires, call create_board_export again to produce a new file.
