# How to Integrate Retool with Monday.com

- Tool: Retool
- Difficulty: Intermediate
- Time required: 25 minutes
- Last updated: April 2026

## TL;DR

Connect Retool to Monday.com using Retool's GraphQL Resource type pointed at Monday's GraphQL API endpoint. Authenticate with a Monday.com API token, write GraphQL queries to fetch boards, items, and updates, then build cross-board reporting dashboards that Monday's native views cannot provide for operations teams.

## Build Monday.com Operations Dashboards in Retool

Monday.com's native views are powerful for day-to-day project management, but they fall short for operations teams that need cross-board visibility, custom aggregations, or data combined with external sources. Retool solves this by connecting directly to Monday's GraphQL API, letting you query any board, item, or column value and display the results in fully customizable tables, charts, and forms.

Monday.com uses GraphQL as its only API protocol — there is no REST alternative. This makes Retool's native GraphQL Resource type the right tool: it introspects the Monday schema automatically, provides type-aware autocomplete in the query editor, and handles pagination through cursor-based variables. You can query multiple boards in a single request, filter items by column values, and build dashboards that aggregate status counts, owner workloads, or due date distributions across an entire organization.

Common Retool apps built on Monday.com include: executive dashboards showing project health across all boards, team workload panels displaying item counts per assignee, escalation tools that surface overdue items filtered by priority, and write-back panels that update item statuses or add updates directly from Retool without requiring users to navigate Monday.

## Before you start

- A Monday.com account with API access (available on all paid plans and the free trial)
- A Retool account with permission to create new Resources
- A Monday.com personal API token (generated from your profile settings)
- At least one Monday.com board with items you want to display in Retool
- Basic familiarity with GraphQL query syntax (variables, nested fields)

## Step-by-step guide

### 1. Generate your Monday.com API token

Before creating a Retool Resource, you need a Monday.com personal API token. Log into Monday.com and click on your avatar in the bottom-left corner, then select 'Developers' from the menu. This opens the Developer Center. Click 'My Access Tokens' in the left sidebar, then click 'Show' next to the API v2 Token field. Copy this token — it is a long alphanumeric string starting with 'eyJhbGciOiJIUzI1NiJ9' or similar. This token authenticates all API calls and has the same permissions as your Monday.com account. Treat it like a password: store it in Retool's configuration variables, not in query code directly. Note that Monday.com also supports OAuth for team-level credentials, but personal access tokens are simpler for internal Retool tools where a single service account can own the integration.

**Expected result:** You have a Monday.com API token copied to your clipboard, ready to configure in Retool.

### 2. Create a GraphQL Resource in Retool

In your Retool workspace, navigate to the Resources tab in the top navigation and click 'Create New' → 'Resource'. Scroll through the list or search for 'GraphQL' — Retool has a dedicated GraphQL resource type, distinct from the generic REST API resource. Select it. In the configuration panel, set the Base URL to 'https://api.monday.com/v2'. This is Monday's single GraphQL endpoint — all queries and mutations go to this same URL. Under 'Headers', click 'Add header' and add two headers: the first with key 'Authorization' and value 'Bearer YOUR_TOKEN_HERE' (replace with the token from Step 1), and the second with key 'Content-Type' and value 'application/json'. Optionally, add an 'API-Version' header with value '2024-01' to pin to a specific Monday.com API version and avoid unexpected breaking changes. Name the resource 'Monday.com GraphQL' or similar. Click 'Test connection' — Retool will send a test introspection query. If successful, you will see a green checkmark. Click 'Create resource' to save.

```
{
  "Base URL": "https://api.monday.com/v2",
  "Headers": {
    "Authorization": "Bearer {{ retoolContext.configVars.MONDAY_API_TOKEN }}",
    "Content-Type": "application/json",
    "API-Version": "2024-01"
  }
}
```

**Expected result:** A new GraphQL Resource named 'Monday.com GraphQL' appears in your Resources list with a successful test connection.

### 3. Query boards and items with GraphQL

Open or create a Retool app. In the Code panel, click 'New query' and select your 'Monday.com GraphQL' resource. Retool's GraphQL query editor loads and automatically introspects the Monday.com schema, so you will see the available types in a schema explorer on the right. Write a GraphQL query to fetch your boards and their items. The Monday.com API uses the 'boards' query type as the primary entry point — you specify board IDs in the 'ids' argument or omit them to fetch all accessible boards. Each board contains 'items_page' (paginated items) and each item contains 'column_values' for field data. Run the query to confirm it returns data. The response will be nested JSON that you will reshape in the next step using a transformer.

```
query GetBoardItems($boardId: ID!, $cursor: String) {
  boards(ids: [$boardId]) {
    id
    name
    items_page(limit: 50, cursor: $cursor) {
      cursor
      items {
        id
        name
        state
        created_at
        updated_at
        group {
          id
          title
        }
        column_values {
          id
          text
          value
          column {
            title
            type
          }
        }
      }
    }
  }
}
```

**Expected result:** The query runs and returns a JSON response with board data including item names, statuses, and column values. The response is nested under data.boards[0].items_page.items.

### 4. Transform the nested GraphQL response

Monday.com's GraphQL API returns deeply nested JSON — items contain a 'column_values' array where each element represents a board column. To use this data in a Retool Table or Chart, you need to flatten it into a simple array of objects. Open the query's Advanced tab and click 'Add transformer'. Write a JavaScript transformer that maps over the items array and converts column_values into named properties. This makes the data directly bindable to Retool Table columns. For status columns, the 'text' field contains the label. For date columns, parse the 'value' field which is a JSON string containing a 'date' key. For people columns, 'text' contains the assignee name. The transformer runs automatically whenever the query data changes, and the result replaces query.data throughout your app.

```
// Transformer: flatten Monday.com GraphQL response
const boards = data.boards || [];
if (boards.length === 0) return [];

const items = boards[0].items_page.items || [];

return items.map(item => {
  // Convert column_values array to an object keyed by column title
  const cols = {};
  (item.column_values || []).forEach(cv => {
    cols[cv.column.title] = cv.text || '';
  });

  return {
    id: item.id,
    name: item.name,
    state: item.state,
    group: item.group?.title || '',
    status: cols['Status'] || '',
    owner: cols['Person'] || cols['Owner'] || '',
    due_date: cols['Due Date'] || cols['Date'] || '',
    priority: cols['Priority'] || '',
    created_at: new Date(item.created_at).toLocaleDateString()
  };
});
```

**Expected result:** The transformer output is a clean, flat array of item objects. The Table component bound to {{ query1.data }} now displays columns for name, status, owner, due_date, and priority.

### 5. Build the dashboard UI with Tables and Charts

Now that your data is flowing, build the dashboard layout. Drag a Table component onto the canvas and set its 'Data source' to {{ getBoardItems.data }}. Enable column filtering so users can filter by status or owner. Add a Chart component above the table — set its type to 'Bar' and configure it to aggregate item counts by status. For the Chart data, create a new JavaScript query (no resource needed) that groups items by status field. Add a TextInput component at the top for board ID input so users can switch between boards without editing query variables — bind the GraphQL query's boardId variable to {{ boardIdInput.value }}. Add event handlers to automatically re-run the board query whenever boardIdInput changes. For the mutation flow (updating an item's status), add a Button and create a second GraphQL query that runs the change_column_value mutation on the selected table row.

```
// JavaScript query for Chart data: group items by status
const items = getBoardItems.data || [];
const counts = {};

items.forEach(item => {
  const status = item.status || 'No Status';
  counts[status] = (counts[status] || 0) + 1;
});

return Object.entries(counts).map(([status, count]) => ({
  status,
  count
}));
```

**Expected result:** The dashboard displays a bar chart of item status distribution and a filterable table of all board items. Selecting a row enables write-back actions via mutation queries.

### 6. Add write-back with GraphQL mutations

A read-only dashboard is useful, but the real productivity gain comes from enabling status updates directly in Retool. Create a new query using the Monday.com GraphQL resource and write a change_column_value mutation. This mutation requires the board ID, item ID, column ID, and the new value formatted as a JSON string. The column ID for a status column is typically 'status' or a custom identifier visible in Monday's board settings under 'Customize columns'. Bind the mutation's item_id argument to {{ table1.selectedRow.id }}, the board_id to the same boardId variable used in the read query, and the value to a JSON string with the label index. Wire this mutation to a Button component's click event, and on success, trigger the read query to refresh the table. Add a Select component to let users choose the new status value from a dropdown bound to the mutation's value input.

```
mutation UpdateItemStatus($boardId: ID!, $itemId: ID!, $columnId: String!, $value: JSON!) {
  change_column_value(
    board_id: $boardId
    item_id: $itemId
    column_id: $columnId
    value: $value
  ) {
    id
    name
    column_values {
      id
      text
    }
  }
}
```

**Expected result:** Selecting a row in the table and clicking the 'Update Status' button runs the mutation and refreshes the table with the new status value — the change is immediately visible in Monday.com.

## Best practices

- Store Monday.com API tokens in Retool configuration variables marked as 'secret' — never reference them directly in query code where they could be exposed in app exports
- Use a dedicated Monday.com service account for your Retool integration rather than a personal user account, ensuring the token remains valid even when team members leave
- Pin the API version using the 'API-Version' header (e.g., '2024-01') to prevent unexpected breaking changes when Monday.com releases new API versions
- Request only the column IDs you need in column_values queries — fetching all columns on large boards significantly increases complexity costs and response times
- Implement cursor-based pagination for boards with more than 50 items — store the cursor value and pass it to subsequent queries rather than increasing the limit beyond 500
- Use Retool Workflows instead of in-app queries for batch operations like updating many items at once — Workflows support retry logic and run server-side without timeout concerns
- Build a board selector component (Select or TextInput) rather than hard-coding board IDs in queries, making the Retool app reusable across different Monday.com boards
- Add confirmation modals before running mutations that update or delete items — Monday.com mutations are immediately applied and cannot be undone from Retool

## Use cases

### Build a cross-board project health dashboard

Query multiple Monday.com boards simultaneously to display item status distributions, overdue counts, and owner workloads in a single Retool dashboard. Use Retool Charts to visualize status breakdowns and a Table to list all items filtered by priority or due date.

Prompt example:

```
Build a Retool dashboard that queries 3 Monday.com boards, shows a bar chart of item statuses per board, and lists all high-priority overdue items in a sortable table with a button to update their status to 'Blocked'.
```

### Create a team workload and capacity panel

Pull all items assigned to each team member across boards and display workload distribution. Build a Retool app where managers can reassign items, add updates, and see unassigned items that need owners — all without leaving the internal tool.

Prompt example:

```
Build a Retool app that shows a table of all Monday.com items grouped by assignee, with a count of open items per person, and a form to add an update to any selected item.
```

### Build an escalation and SLA tracking panel

Query items that have exceeded their expected completion date or have been in a specific status column for too long. Surface these in a Retool table with one-click actions to notify assignees or escalate to management by changing the item's priority column.

Prompt example:

```
Create a Retool escalation dashboard that lists all Monday.com items where the due date is in the past and status is not 'Done', sorted by days overdue, with a button that changes the item's priority column to 'Critical'.
```

## Troubleshooting

### Query returns '403 Forbidden' or 'User unauthorized' error

Cause: The API token in the Authorization header is invalid, expired, or missing the 'Bearer ' prefix. Monday.com tokens can also become invalid if the user's account is deactivated.

Solution: Regenerate the API token in Monday.com Developer Center → My Access Tokens. Ensure the Authorization header value starts with 'Bearer ' (with a space before the token). Confirm the token is stored in Retool's configuration variables and not hard-coded with extra whitespace.

### GraphQL query returns empty data array despite boards existing in Monday.com

Cause: The board IDs passed to the query do not match any boards accessible to the authenticated user, or the boards query argument format is incorrect. Monday.com board IDs are numeric integers, not strings, in most query contexts.

Solution: Run a discovery query first with no IDs argument to list all accessible boards: query { boards { id name } }. Copy the correct numeric ID from the response and use it in subsequent queries. Note that Monday.com's GraphQL treats board IDs as ID scalars — pass them as integers in the variables object, not as quoted strings.

```
// Discovery query to find your board IDs
query {
  boards(limit: 50) {
    id
    name
    board_kind
    state
  }
}
```

### Transformer returns undefined for column values that should have data

Cause: Column titles in Monday.com are case-sensitive and may differ from what you expect. The 'text' field for some column types (checkbox, formula) may be empty while the actual value is in the 'value' field as a JSON string.

Solution: Log the raw column_values array in the transformer to inspect actual column titles: console.log(item.column_values). Update the transformer to match the exact column title casing used in your board. For complex column types, parse the 'value' field with JSON.parse() after checking it is not null.

```
// Debug: list all column titles and values for first item
const items = data.boards?.[0]?.items_page?.items || [];
if (items.length === 0) return [];
return items[0].column_values.map(cv => ({
  column_title: cv.column.title,
  column_type: cv.column.type,
  text: cv.text,
  raw_value: cv.value
}));
```

### Mutation returns 'ComplexityBudgetExhausted' error

Cause: Monday.com's API enforces complexity budget limits per minute. Complex queries that retrieve many items with many column values, or rapid successive queries in a Retool app, can exhaust the budget (1,000,000 complexity per minute on standard plans).

Solution: Reduce query complexity by requesting fewer column_values fields — only fetch the specific column IDs you need rather than all column_values. Use pagination (the cursor-based items_page limit argument) to fetch items in smaller batches. Add a debounce or throttle setting to the Retool query's execution options to prevent rapid re-runs.

```
# Only fetch specific columns by their ID to reduce complexity
query GetBoardItemsLite($boardId: ID!) {
  boards(ids: [$boardId]) {
    id
    name
    items_page(limit: 25) {
      items {
        id
        name
        column_values(ids: ["status", "person", "date4"]) {
          id
          text
        }
      }
    }
  }
}
```

## Frequently asked questions

### Does Retool have a native Monday.com connector?

No, Retool does not have a dedicated Monday.com native connector. You connect using Retool's GraphQL Resource type, which supports Monday.com's GraphQL API natively. This approach works well because Retool's GraphQL editor introspects the Monday schema automatically, giving you autocomplete and type safety.

### Can I query multiple Monday.com boards in a single Retool query?

Yes. Monday.com's GraphQL API accepts an array of board IDs in the 'ids' argument. You can query multiple boards in one request: boards(ids: [1234567, 7654321]) { ... }. The response includes data for each board. Use a JavaScript transformer to merge and flatten the results into a single table.

### How do I handle Monday.com API rate limits in Retool?

Monday.com uses a complexity-based rate limit (1,000,000 units per minute on standard plans). To stay within limits, request only the column IDs you need, use pagination with small page sizes (25-50 items), and avoid running queries on every keystroke. Set Retool queries to run 'manually' or with a debounce rather than on every component change.

### Can I create new Monday.com items from Retool?

Yes, use the create_item GraphQL mutation. The mutation accepts a board_id, group_id, item_name, and column_values as a JSON string. Build a Retool Form component and wire its submit event to run the mutation with form field values as variables. After a successful creation, trigger the read query to refresh the table.

### Why do my Monday.com column values show as empty strings?

Some Monday.com column types (like formula columns, mirror columns, or empty date fields) return an empty 'text' field. The actual value is in the 'value' field as a JSON string. Parse it with JSON.parse(cv.value) in your transformer. Also check that column titles in your transformer match the exact case used in your Monday board settings.

---

Source: https://www.rapidevelopers.com/retool-integrations/monday-com
© RapidDev — https://www.rapidevelopers.com/retool-integrations/monday-com
