npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mondaydotcomorg/api

v14.3.1

Published

monday.com API client

Readme

monday.com API SDK

A JavaScript/TypeScript client for monday.com's GraphQL platform API. It works in Node.js and in the browser, and uses graphql-request under the hood.

The package has two clients:

  • ApiClient: for everything that has an API token, such as scripts, servers and integrations.
  • SeamlessApiClient: for the client side of an app deployed on monday.com. It needs no token, because it asks monday.com to make the call on behalf of the logged-in user.

Installation

npm install @mondaydotcomorg/api

ApiClient

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

const client = new ApiClient({ token: '<API-TOKEN>' });

const { boards } = await client.request<{ boards: { name: string }[] }>(
  `query { boards(ids: 123) { name } }`,
);

request() resolves with the data of the GraphQL response, and rejects if the response has errors (see Handling errors).

The constructor also takes apiVersion (defaults to the version matching your package release), endpoint, and requestConfig, which is passed on to graphql-request.

Operations

For common tasks you don't have to write GraphQL yourself. The client ships with ready-made operations:

const me = await client.operations.getMeOp();

// Change a text column
await client.operations.changeColumnValueOp({
  boardId: 'your_board_id',
  itemId: 'your_item_id',
  columnId: 'text',
  value: JSON.stringify('Hello, world!'),
});

// Change a status column
await client.operations.changeColumnValueOp({
  boardId: 'your_board_id',
  itemId: 'your_item_id',
  columnId: 'project_status',
  value: JSON.stringify({ label: 'Done' }),
});

Types

The package exports the types of the whole API, for example Board and User:

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

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

These types match the API version that was current when the package was released.

A type like Board describes every field, not just the ones in your query, so your editor will suggest fields the response doesn't have:

All fields are suggested, whatever the query asks for

To get types that match each query exactly, use @mondaydotcomorg/setup-api. It generates them from your own queries. The same tool is bundled in @mondaycom/apps-cli for monday app developers (see the monday apps SDK).

Request options

The third argument of request() sets options for that call only:

await client.request(query, variables, {
  versionOverride: '2025-10', // use another API version for this call
  timeoutMs: 20_000, // up to 60 seconds
  headers: { 'X-Custom-Header': 'value' },
  idempotencyKey: '<UNIQUE-KEY>',
});

An idempotency key makes a mutation safe to retry. It is sent as the Idempotency-Key header, so reuse the same key when you retry the same operation. See the idempotency docs.

Handling errors

When the response contains GraphQL errors, request() throws a ClientError:

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

try {
  await client.request(query, variables);
} catch (error) {
  if (error instanceof ClientError) {
    console.error(error.response.errors);
  } else {
    throw error;
  }
}

If you'd rather keep the partial data that did come back, set an errorPolicy on the client:

const client = new ApiClient({ token: '<API-TOKEN>', requestConfig: { errorPolicy: 'all' } });
  • none (default): throw on any GraphQL error.
  • ignore: ignore the errors and resolve with the data.
  • all: resolve with both data and errors. The errors are only visible through rawRequest().

rawRequest

rawRequest() returns the full response (data, errors, extensions, headers and status) instead of just the data:

const res = await client.rawRequest<{ boards: Board[] }>(query, variables);

console.log(res.data.boards);
console.log(res.errors);

It takes the same options as request().

File uploads

Pass a File or Blob in the variables and the client sends a multipart request for you. This relies on the File, Blob and fetch that come with Node.js.

const file = new File([Buffer.from('Hello World!')], 'test.txt', { type: 'text/plain' });

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: 'your_item_id', columnId: 'files' },
);

SeamlessApiClient

Use it in the browser code of an app deployed on monday.com. It sends the request to the monday.com page around your app, which makes the call as the current user, so there is no token to manage. It only works inside an app view on monday.com.

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

const client = new SeamlessApiClient();

const res = await client.request<{ data: { data: { boards: { id: string; name: string }[] } } }>(
  `query { boards(ids: 123) { id name } }`,
);
const boards = res.data.data.boards;

The constructor takes an API version and client settings: new SeamlessApiClient('2025-10', { errorPolicy: 'all' }). Without a version it uses the one matching your package release.

Response shape

Unlike ApiClient, request() doesn't return just the GraphQL data. It resolves with the whole reply from monday.com, so the fields you asked for are at res.data.data:

{
  data: {
    data,        // the fields you queried
    extensions,
  },
  headers,       // a Headers object with the response headers, if there are any (see below)
}

The type parameter of request<T>() describes this whole object.

Request options

await client.request(query, variables, {
  versionOverride: '2025-10',
  timeoutMs: 30_000, // default 60 seconds
  headers: { 'X-Custom-Header': 'value' },
  idempotencyKey: '<UNIQUE-KEY>',
  errorPolicy: 'all',
});

As with ApiClient, idempotencyKey is sent as the Idempotency-Key header and wins over one passed in headers.

Handling errors

When the response contains GraphQL errors, request() rejects with a SeamlessApiClientError:

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

try {
  await client.request(query, variables);
} catch (error) {
  if (error instanceof SeamlessApiClientError) {
    console.error(error.response.errors);
    console.error(error.response.extensions?.request_id); // quote this when reporting a problem
  }
}

error.response has:

  • errors: the GraphQL errors. The message of the error itself is always 'Graphql validation errors', so look at errors[0].message for the actual reason.
  • data: the fields that did resolve, if any.
  • extensions: extra response details, such as request_id.
  • headers: the response headers, if any.

Failures that aren't GraphQL errors (for example a missing query) also reject with a SeamlessApiClientError, but with response.errors undefined. A timeout rejects with a plain Error.

errorPolicy

Like in ApiClient, you can resolve the partial data instead of rejecting. Set the policy on the client, or for one call with the errorPolicy request option, which wins over the client setting.

const client = new SeamlessApiClient(undefined, { errorPolicy: 'all' });

// `me` works, `next_items_page` fails because the cursor is invalid
const res = await client.request('query { me { id } next_items_page(cursor: "invalid") { cursor } }');

res.data.data.me.id; // the field that resolved
res.data.errors; // the error of the field that failed
  • none (default): reject with SeamlessApiClientError.
  • ignore: resolve with data and extensions, and drop errors.
  • all: resolve with data, errors and extensions.

The policy only applies to replies that contain GraphQL errors. Timeouts and other failures always reject. If no partial data came back, res.data.data is undefined.

Response headers

Response headers, such as rate limit info, are on res.headers and error.response.headers as a standard Headers object, so lookups are case-insensitive:

res.headers?.get('RateLimit');

headers is undefined when there are none.

Using an AI assistant

If an LLM helps you write code with this SDK, the rules in the llm-context package make it more likely to get it right. See the LLM Context docs.