JavaScript SDK

A comprehensive guide to the monday.com JavaScript/TypeScript SDK for interacting with the GraphQL API.

The monday.com JavaScript SDK (@mondaydotcomorg/api) provides a typed, ergonomic way to interact with the monday.com GraphQL API from Node.js or browser environments. It wraps graphql-request and ships with pre-built operations, full TypeScript types generated from the API schema, and automatic API versioning.

A companion package (@mondaydotcomorg/setup-api) scaffolds a GraphQL codegen pipeline so you can write custom queries with full type safety.

PackagePurposeLatest version
@mondaydotcomorg/apiAPI client, types, pre-built operations14.0.0
@mondaydotcomorg/setup-apiGraphQL codegen scaffolding CLI2.1.1

Installation

npm install @mondaydotcomorg/api

The package works in both Node.js (v18+) and browser environments.

Dependencies

The SDK depends on graphql, graphql-request, graphql-tag, and zod. These are installed automatically.


ApiClient

ApiClient is the main entry point. It requires an API token and optionally accepts an API version and request configuration.

Creating a client

import { ApiClient } from '@mondaydotcomorg/api';

const client = new ApiClient({
  token: '<YOUR_API_TOKEN>',
});

Constructor options

OptionTypeRequiredDefaultDescription
tokenstringYesYour monday.com API token (personal or OAuth). Sent as the Authorization header.
apiVersionstringNo'2026-01' (current at SDK release)API version in yyyy-mm format. Valid months: 01, 04, 07, 10. Also accepts 'dev'.
endpointstringNo'https://api.monday.com/v2'Override the API endpoint URL.
requestConfigRequestConfigNo{}Passed to the underlying graphql-request client. Includes errorPolicy, headers, fetch, requestMiddleware, etc.
const client = new ApiClient({
  token: '<YOUR_API_TOKEN>',
  apiVersion: '2025-10',
  requestConfig: {
    errorPolicy: 'all',
  },
});
📘

API version validation

The constructor throws an error if apiVersion doesn't match the format yyyy-mm with month 01, 04, 07, or 10 (or 'dev'). For example, '2025-03' is rejected.


Freestyle queries

Use client.request() to execute any GraphQL query or mutation.

Basic query

const result = await client.request(`
  query {
    boards(ids: [12345]) {
      id
      name
      columns { id title type }
    }
  }
`);

console.log(result.boards);

With variables

const result = await client.request(
  `query ($ids: [ID!]!) {
    boards(ids: $ids) {
      id
      name
      items_page(limit: 5) {
        items { id name }
      }
    }
  }`,
  { ids: ["12345", "67890"] }
);

With TypeScript generics

You can pass a type parameter to request() to type the response:

import { Board } from '@mondaydotcomorg/api';

const { boards } = await client.request<{ boards: Board[] }>(
  `query { boards(ids: [12345]) { id name } }`
);
👍

Pro tip

The SDK exports all GraphQL types from the monday.com schema (e.g., Board, Item, Column, User, Group, ColumnType, etc.). Import them directly for type-safe responses.

Request options

The third parameter to request() accepts:

OptionTypeDescription
versionOverridestringOverride the API version for this single request. Same validation rules as the constructor.
timeoutMsnumberRequest timeout in milliseconds (max 60,000). The request aborts if the API doesn't respond in time.
const result = await client.request(
  `query { me { id name } }`,
  undefined,
  { versionOverride: '2025-10', timeoutMs: 10000 }
);

Raw requests

Use client.rawRequest() when you need the full response structure including data, errors, and extensions:

const response = await client.rawRequest(`query { me { id name } }`);

console.log(response.data);       // { me: { id: '...', name: '...' } }
console.log(response.extensions);  // API metadata (complexity, etc.)
console.log(response.errors);      // Any GraphQL errors (if errorPolicy allows)

rawRequest() accepts the same parameters as request() (query, variables, options).


Pre-built operations

The SDK includes pre-built operations accessible via client.operations. These are typed GraphQL documents with dedicated methods — no need to write the query yourself.

Available operations

MethodTypeDescription
getMeOp()QueryReturns the authenticated user's id, name, and email.
getBoardItemsOp({ ids })QueryReturns items (with column values) for the specified board IDs.
getBoardGroupsOp({ ids })QueryReturns groups (with id and title) for the specified board IDs.
createItemOp({ boardId, groupId, itemName })MutationCreates a new item in the specified board and group.
changeSimpleColumnValueOp({ boardId, itemId, columnId, value })MutationSets a column's value using a simple string.
changeColumnValueOp({ boardId, itemId, columnId, value })MutationSets a column's value using a JSON value.
changeMultipleColumnValuesOp({ boardId, itemId, columnValues })MutationSets multiple column values at once using a JSON string.

Examples

Get the current user

const { me } = await client.operations.getMeOp();
console.log(me.name, me.email);

Get board items

const { boards } = await client.operations.getBoardItemsOp({
  ids: ["12345"],
});

for (const board of boards) {
  for (const item of board.items_page.items) {
    console.log(item.id, item.name);
    for (const col of item.column_values) {
      console.log(`  ${col.id} (${col.type}): ${col.value}`);
    }
  }
}

Create an item

const { create_item } = await client.operations.createItemOp({
  boardId: "12345",
  groupId: "topics",
  itemName: "New task from SDK",
});

console.log("Created item:", create_item.id);

Change a single column value

// Simple string value (for text columns)
await client.operations.changeSimpleColumnValueOp({
  boardId: "12345",
  itemId: "67890",
  columnId: "text_column",
  value: "Hello from SDK!",
});

// JSON value (for structured columns like status, date, etc.)
await client.operations.changeColumnValueOp({
  boardId: "12345",
  itemId: "67890",
  columnId: "status_column",
  value: JSON.stringify({ label: "Done" }),
});

Change multiple column values at once

await client.operations.changeMultipleColumnValuesOp({
  boardId: "12345",
  itemId: "67890",
  columnValues: JSON.stringify({
    text_column: "Updated text",
    status_column: { label: "Working on it" },
    date_column: { date: "2026-04-01" },
  }),
});
📘

Column value formats

The value parameter for changeColumnValueOp and changeMultipleColumnValuesOp must be a JSON-stringified value. Each column type expects a specific JSON structure — refer to the column values documentation for details.


File uploads

The SDK supports file uploads through the standard GraphQL add_file_to_column mutation. Pass a Node.js File or Blob object in your variables, and the client automatically switches to a multipart request.

import { ApiClient } from '@mondaydotcomorg/api';
import { readFileSync } from 'fs';

const client = new ApiClient({ token: '<YOUR_API_TOKEN>' });

const file = new File(
  [readFileSync('./report.pdf')],
  'report.pdf',
  { type: 'application/pdf' }
);

const result = await client.request(
  `mutation ($file: File!, $itemId: ID!, $columnId: String!) {
    add_file_to_column(file: $file, item_id: $itemId, column_id: $columnId) {
      id
      name
      url
    }
  }`,
  {
    file,
    itemId: '67890',
    columnId: 'files',
  }
);

console.log(result.add_file_to_column);
⚠️

Important

File uploads use Node's built-in File and Blob (available in Node 18+). The SDK's file upload middleware detects these objects and converts the request to multipart/form-data automatically.


Error handling

ClientError

When a GraphQL request fails, the SDK throws a ClientError (re-exported from graphql-request):

import { ApiClient, ClientError } from '@mondaydotcomorg/api';

const client = new ApiClient({ token: '<YOUR_API_TOKEN>' });

try {
  await client.request(`query { invalid_field }`);
} catch (error) {
  if (error instanceof ClientError) {
    console.error('GraphQL errors:', error.response.errors);
    // [{ message: 'Cannot query field "invalid_field" on type "Query".', locations: [...] }]
  } else {
    console.error('Network or other error:', error);
  }
}

Error policies

By default, the client throws on any GraphQL error. You can change this with errorPolicy in the constructor:

PolicyBehavior
'none' (default)Throws on any error.
'ignore'Resolves the promise, ignoring errors entirely.
'all'Returns both data and errors. Use with rawRequest() to access partial data alongside errors.
const client = new ApiClient({
  token: '<YOUR_API_TOKEN>',
  requestConfig: { errorPolicy: 'all' },
});

const response = await client.rawRequest(`query { ... }`);
console.log(response.data);    // partial data (if any)
console.log(response.errors);  // error details

SeamlessApiClient

SeamlessApiClient is designed for client-side code running inside a monday.com app (e.g., a board view or item view iframe). It communicates with the monday.com API through the platform's internal postMessage bridge — no API token is needed.

import { SeamlessApiClient, Board } from '@mondaydotcomorg/api';

const client = new SeamlessApiClient();

const { boards } = await client.request<{ boards: Board[] }>(
  `query { boards(ids: [12345]) { id name } }`
);

SeamlessApiClient constructor

OptionTypeDefaultDescription
apiVersionstringCurrent version at SDK releaseAPI version to use for requests.

SeamlessApiClient.request()

ParameterTypeRequiredDescription
querystringYesGraphQL query or mutation string.
variablesRecord<string, any>NoQuery variables.
versionstringNoPer-request API version override.
timeoutnumberNo (default 60000)Request timeout in ms.

Error handling

Errors from SeamlessApiClient are instances of SeamlessApiClientError:

import { SeamlessApiClient, SeamlessApiClientError } from '@mondaydotcomorg/api';

const client = new SeamlessApiClient();

try {
  await client.request(`query { boards { id } }`);
} catch (error) {
  if (error instanceof SeamlessApiClientError) {
    console.error(error.message);
    console.error(error.response.errors);
  }
}
⚠️

Browser only

SeamlessApiClient uses window.postMessage and only works inside a monday.com app iframe. For server-side code or standalone scripts, use ApiClient with a token.


API versioning

The monday.com API uses quarterly versioning. The SDK automatically sends the API-Version header with every request.

Version format

Versions follow yyyy-mm where month is one of 01, 04, 07, 10 (released quarterly). The special value 'dev' targets the development/preview version.

Version lifecycle

StageDescription
currentThe current stable version.
release_candidateNext version, available for preview.
maintenancePrevious version, still supported.
deprecatedNo longer supported; will eventually stop working.
devUnstable preview of upcoming changes.

Controlling the version

// Set at client creation (applies to all requests including operations)
const client = new ApiClient({
  token: '<YOUR_API_TOKEN>',
  apiVersion: '2025-10',
});

// Override per-request
const result = await client.request(
  `query { me { id } }`,
  undefined,
  { versionOverride: '2026-01' }
);

Exported constants

import { DEFAULT_VERSION, MONDAY_API_ENDPOINT, AvailableVersions } from '@mondaydotcomorg/api';

console.log(DEFAULT_VERSION);        // '2026-01'
console.log(MONDAY_API_ENDPOINT);    // 'https://api.monday.com/v2'
console.log(AvailableVersions);      // { CURRENT_VERSION: '2026-01', CURRENT: 'current', ... }

TypeScript types

The SDK exports all types from the monday.com GraphQL schema. These are generated from the API schema that was current when the package was published.

Commonly used types

TypeDescription
BoardA monday.com board with all fields.
ItemAn item (row) on a board.
ColumnA column definition on a board.
ColumnValueBase interface for column values. Union type with specific value types like TextValue, StatusValue, DateValue, etc.
ColumnTypeEnum of all column types (text, status, date, people, etc.).
GroupA group of items on a board.
UserA monday.com user.
WorkspaceA workspace.
AccountAccount-level information.
AssetAn uploaded file.
UpdateAn update (comment) on an item.
TagA tag.
TeamA team.
FolderA folder in a workspace.
DocA monday doc.
AppSubscriptionApp monetization subscription details.

Enum types

The SDK also exports useful enums:

EnumValues (examples)
BoardKindpublic, private, share
ColumnTypetext, status, date, numbers, people, timeline, etc.
BoardObjectTypeboard, sub_items_board, document
BoardSubscriberKindowner, subscriber
WorkspaceKindopen, closed
Stateactive, archived, deleted, all
FirstDayOfTheWeeksunday, monday

Usage example

import { Board, Item, ColumnType, BoardKind } from '@mondaydotcomorg/api';

const processItem = (item: Item) => {
  for (const col of item.column_values) {
    if (col.type === ColumnType.Status) {
      console.log(`Status column ${col.id}:`, col.value);
    }
  }
};

GraphQL codegen setup (@mondaydotcomorg/setup-api)

For projects that need custom queries with full type safety, use the companion setup package to scaffold a GraphQL codegen pipeline.

Running the setup

Run this command in your project's root directory:

npx @mondaydotcomorg/setup-api
⚠️

Bash-only

This CLI requires a bash-like environment (macOS Terminal, Linux shell, Git Bash on Windows). It is not compatible with Windows Command Prompt (cmd).

What the setup creates

File/folderPurpose
codegen.ymlConfiguration for GraphQL Code Generator.
graphql.config.ymlConfiguration for the GraphQL IDE extension. Provides autocomplete and validation in your editor.
src/queries.graphql.tsStarter file where you write your GraphQL queries and mutations. Comes with example query and mutation.
fetch-schema.shScript that downloads the latest monday.com API schema.
npm scripts in package.jsonfetch:schema, codegen, and fetch:generate.

Installed dev dependencies

The setup installs these packages:

  • @graphql-codegen/cli
  • @graphql-codegen/typescript
  • @graphql-codegen/typescript-operations

Workflow

After running the setup:

1. Write your queries

Edit src/queries.graphql.ts to define your GraphQL operations:

import gql from 'graphql-tag';

export const getBoards = gql`
  query GetBoards($ids: [ID!]) {
    boards(ids: $ids) {
      id
      name
      columns { id title type }
      groups { id title }
    }
  }
`;

export const createItem = gql`
  mutation CreateItem($boardId: ID!, $groupId: String!, $itemName: String!) {
    create_item(board_id: $boardId, group_id: $groupId, item_name: $itemName) {
      id
      name
    }
  }
`;

2. Fetch the schema and generate types

npm run fetch:generate

This downloads the latest monday.com API schema and generates TypeScript types in src/generated/graphql.ts.

3. Use the generated types

import { ApiClient } from '@mondaydotcomorg/api';
import { GetBoardsQuery, GetBoardsQueryVariables } from './generated/graphql';
import { getBoards } from './queries.graphql';

const client = new ApiClient({ token: '<YOUR_API_TOKEN>' });

const variables: GetBoardsQueryVariables = { ids: ["12345"] };
const data = await client.request<GetBoardsQuery>(getBoards, variables);

// data.boards is fully typed based on your query's selected fields

Regenerating types after query changes

Whenever you modify your queries:

npm run codegen

To also re-fetch the schema (e.g., after a new API version):

npm run fetch:generate

IDE support

For the best experience, install the GraphQL extension for your editor. The graphql.config.yml created by the setup enables autocomplete, validation, and hover docs for your queries.

VS Code: Install the GraphQL: Language Feature Support and GraphQL: Syntax Highlighting extensions.

JetBrains IDEs: Install the GraphQL plugin from Preferences > Plugins > Marketplace.


Full examples

Querying boards and items

import { ApiClient, Board, ColumnType } from '@mondaydotcomorg/api';

const client = new ApiClient({ token: '<YOUR_API_TOKEN>' });

// Get board structure
const { boards } = await client.request<{ boards: Board[] }>(`
  query {
    boards(ids: [12345]) {
      id
      name
      columns { id title type }
      groups { id title }
    }
  }
`);

// Get items with column values
const { boards: boardsWithItems } = await client.operations.getBoardItemsOp({
  ids: ["12345"],
});

for (const item of boardsWithItems[0].items_page.items) {
  console.log(`Item: ${item.name}`);
  for (const col of item.column_values) {
    console.log(`  ${col.id}: ${col.value}`);
  }
}

Creating items and updating columns

import { ApiClient } from '@mondaydotcomorg/api';

const client = new ApiClient({ token: '<YOUR_API_TOKEN>' });

// Create an item
const { create_item } = await client.operations.createItemOp({
  boardId: "12345",
  groupId: "topics",
  itemName: "New feature request",
});

// Update multiple columns on the new item
await client.operations.changeMultipleColumnValuesOp({
  boardId: "12345",
  itemId: create_item.id,
  columnValues: JSON.stringify({
    status: { label: "Working on it" },
    text: "Description of the feature",
    date: { date: "2026-04-15" },
    person: { personsAndTeams: [{ id: 12345678, kind: "person" }] },
  }),
});

Using codegen with the SDK

import { ApiClient, ClientError } from '@mondaydotcomorg/api';
import { GetBoardsQuery, GetBoardsQueryVariables, CreateItemMutation, CreateItemMutationVariables } from './generated/graphql';
import { getBoards, createItem } from './queries.graphql';

const client = new ApiClient({ token: '<YOUR_API_TOKEN>' });

// Typed query
const queryVars: GetBoardsQueryVariables = { ids: ["12345"] };
const boardData = await client.request<GetBoardsQuery>(getBoards, queryVars);

// Typed mutation
const mutationVars: CreateItemMutationVariables = {
  boardId: "12345",
  groupId: "topics",
  itemName: "Created with typed SDK!",
};
const itemData = await client.request<CreateItemMutation>(createItem, mutationVars);

Error handling pattern

import { ApiClient, ClientError } from '@mondaydotcomorg/api';

const client = new ApiClient({ token: '<YOUR_API_TOKEN>' });

async function safeRequest<T>(query: string, variables?: Record<string, any>): Promise<T | null> {
  try {
    return await client.request<T>(query, variables);
  } catch (error) {
    if (error instanceof ClientError) {
      const gqlErrors = error.response.errors;
      for (const err of gqlErrors) {
        if (err.message.includes('complexity')) {
          console.error('Complexity budget exceeded. Simplify your query.');
        } else if (err.message.includes('Rate limit')) {
          console.error('Rate limited. Implement backoff.');
        } else {
          console.error('GraphQL error:', err.message);
        }
      }
    } else {
      console.error('Unexpected error:', error);
    }
    return null;
  }
}

File upload

import { ApiClient } from '@mondaydotcomorg/api';
import { readFileSync } from 'fs';

const client = new ApiClient({ token: '<YOUR_API_TOKEN>' });

const fileBuffer = readFileSync('./document.pdf');
const file = new File([fileBuffer], 'document.pdf', { type: 'application/pdf' });

const result = await client.request(
  `mutation ($file: File!, $itemId: ID!, $columnId: String!) {
    add_file_to_column(file: $file, item_id: $itemId, column_id: $columnId) {
      id
      name
      url
    }
  }`,
  { file, itemId: "67890", columnId: "files" }
);

Quick reference

Exports summary

// Classes
import { ApiClient, SeamlessApiClient } from '@mondaydotcomorg/api';

// Error types
import { ClientError, SeamlessApiClientError } from '@mondaydotcomorg/api';

// Constants
import { DEFAULT_VERSION, MONDAY_API_ENDPOINT, AvailableVersions } from '@mondaydotcomorg/api';

// Types (examples — hundreds are available)
import { Board, Item, Column, ColumnValue, User, Group, Workspace, Asset, Update, Tag } from '@mondaydotcomorg/api';

// Enums (examples)
import { ColumnType, BoardKind, State, WorkspaceKind, BoardObjectType } from '@mondaydotcomorg/api';

ApiClient method reference

MethodSignatureDescription
request<T>()(query: string, variables?: Record<string, any>, options?: RequestOptions) => Promise<T>Execute a GraphQL query/mutation. Returns typed response data.
rawRequest<T>()(query: string, variables?: Record<string, any>, options?: RequestOptions) => Promise<GraphQLClientResponse<T>>Execute a query and return the full response with data, errors, and extensions.
operations.getMeOp()() => Promise<GetMeOpQuery>Get the authenticated user.
operations.getBoardItemsOp()({ ids: string[] }) => Promise<GetBoardItemsOpQuery>Get items for boards.
operations.getBoardGroupsOp()({ ids: string[] }) => Promise<GetBoardGroupsOpQuery>Get groups for boards.
operations.createItemOp()({ boardId, groupId, itemName }) => Promise<CreateItemOpMutation>Create an item.
operations.changeSimpleColumnValueOp()({ boardId, itemId, columnId, value: string }) => PromiseSet a column's simple string value.
operations.changeColumnValueOp()({ boardId, itemId, columnId, value: JSON }) => PromiseSet a column's JSON value.
operations.changeMultipleColumnValuesOp()({ boardId, itemId, columnValues: JSON }) => PromiseSet multiple column values.