Export Monday.com boards to Google Sheets with the GraphQL API, including the items query that was removed and the complexity budget that throttles large boards.
Monday.com's API is GraphQL only, which makes it different in shape from most integrations here. Two things catch people out: the top-level items query was removed in the 2023-10 version, so most tutorials online no longer work, and rate limiting is based on query complexity rather than request count, so a single greedy query can exhaust your budget.
The two-minute option: board export
Open a board, use the board menu, and choose Export board to Excel. Open the file in Sheets, or import it. The export reflects the board's current columns and any active filters, and is per board, so a multi-board report means repeating it.
Monday.com to Google Sheets for free (Apps Script + GraphQL)
Generate a personal API token from your profile menu → Developers → My access tokens, or from Admin for a workspace-level token. The board ID is the numeric value in the board URL.
The current query shape goes through the board: boards(ids: [123]) then items_page, which returns a cursor for the next page. Note that IDs must be passed as an array even when you only want one board.
function importMondayBoard() { const TOKEN = "YOUR_API_TOKEN"; const BOARD_ID = 1234567890; const headers = { Authorization: TOKEN, // no "Bearer" prefix "Content-Type": "application/json", "API-Version": "2024-01", // pin it; the default version moves }; // The top-level "items" query was removed in 2023-10. Items are reached // through the board via items_page, which paginates with a cursor. const query = ` query ($board: [ID!], $cursor: String) { boards(ids: $board) { name items_page(limit: 500, cursor: $cursor) { cursor items { id name group { title } column_values { id text } } } } }`; const rows = []; const columnIds = []; let cursor = null; do { const res = JSON.parse(UrlFetchApp.fetch("https://api.monday.com/v2", { method: "post", headers: headers, payload: JSON.stringify({ query: query, variables: { board: [String(BOARD_ID)], cursor: cursor }, }), muteHttpExceptions: true, }).getContentText()); // GraphQL returns HTTP 200 with an errors array on failure. if (res.errors) throw new Error(JSON.stringify(res.errors)); const page = res.data.boards[0].items_page; page.items.forEach((item) => { const byId = {}; item.column_values.forEach((c) => { if (columnIds.indexOf(c.id) === -1) columnIds.push(c.id); byId[c.id] = c.text; // text is the display string }); rows.push({ name: item.name, group: item.group.title, values: byId }); }); cursor = page.cursor; // null once the last page is reached } while (cursor); const header = ["Item", "Group", ...columnIds]; const table = rows.map((r) => [ r.name, r.group, ...columnIds.map((id) => r.values[id] || ""), ]); const ss = SpreadsheetApp.getActiveSpreadsheet(); const sheet = ss.getSheetByName("Monday") || ss.insertSheet("Monday"); sheet.clearContents(); sheet.getRange(1, 1, 1, header.length).setValues([header]); if (table.length) { sheet.getRange(2, 1, table.length, header.length).setValues(table); }}Two details. Like most GraphQL APIs, Monday returns HTTP 200 with an errors array when a query fails, so checking the status code alone treats failures as success. And column IDs are used as headers here rather than titles; requesting columns { id title } on the board lets you map them to readable names.
Limits: complexity budget per minute rather than a request count, so request only the columns you need. Apps Script's six-minute cap applies, and very wide boards may need splitting by group.
The Brooked method
Brooked builds the GraphQL query for you against the current API version, pages the cursor, maps column IDs to their titles, and parses typed columns such as status and people into readable values. Several boards can import into one spreadsheet on a single schedule.
Step 1: Install Brooked
Install Brooked from the Google Workspace Marketplace. Free tier includes 100 imports per month, no credit card required.
Step 2: Connect Monday.com
Choose Monday.com in Brooked and paste a personal API token from Developers → My access tokens. Pick the boards and columns you want and import.
Step 3: Schedule the refresh
Set the import to re-run daily or weekly so cross-board status reports rebuild themselves rather than being re-exported by hand.
Method comparison
| Method | Cost | Setup | Refresh | Two-way | Best for |
|---|---|---|---|---|---|
| Monday.com CSV export | Free | 2 min | Manual | No | A one-off export of a single board |
| Apps Script + GraphQL API | Free | 30 to 45 min | Time-driven trigger | DIY | Several boards, custom columns |
| Monday integrations | Paid plans, action limits apply | 5 to 10 min | On item change | Varies | Reacting to individual item events |
| Brooked | Free tier · Pro $29/user/mo | ~3 min | Scheduled (hourly, daily, weekly) | Yes | Scheduled reporting across boards |
Common use cases
- Portfolio status: combine several boards into one leadership table
- Overdue tracking: items past their date column, grouped by owner
- Capacity planning: item counts and effort per person across boards
- Client reporting: share a filtered sheet without granting board access
- Historical snapshots: schedule imports to build trend data Monday does not retain
Troubleshooting common issues
Related Articles
- How to Connect Clockify to Google Sheets
- How to Connect ClickUp to Google Sheets
- How to Connect Asana to Google Sheets
Frequently asked questions
Why does my Monday.com items query return an error?
The top-level items query was removed in API version 2023-10. Items are now fetched through their board using items_page, as boards(ids: [123]) { items_page(limit: 500) { cursor items { ... } } }. Most tutorials written before that change no longer work, and the error message does not make the cause obvious.
Do I need the API-Version header?
Yes, in practice. Monday.com versions its GraphQL API and without an explicit API-Version header your request is served by whichever version is currently the default, which changes over time. Pinning a version means your integration breaks on a date you choose rather than unexpectedly.
Can I export Monday.com to Google Sheets for free?
Yes. Any board exports to Excel from the board menu on all plans, which covers a one-off. The Apps Script method here uses a free personal API token and a free time-driven trigger. Note Monday's own integration recipes that push to Google Sheets are limited by plan and consume monthly action quotas.
How does Monday.com rate limiting work?
By query complexity rather than request count. Every query costs points based on how much data it could return, and you have a complexity budget per minute that varies by plan. Requesting many columns across many items on a wide board can exhaust it in a single query, so asking for fewer columns is more effective than adding delays.
Why are my column values empty or unreadable?
column_values returns a generic type where text gives a display string and value gives raw JSON. For most reporting the text field is what you want. Typed columns such as status, date and people carry richer data in value, which needs parsing as JSON, and some column types return null text entirely so the JSON is the only source.
Can I write back to Monday.com from Sheets?
Yes with mutations, and Brooked supports write-back for editable columns, so bulk status or date updates from a sheet are possible. Mirror, formula and auto-number columns are computed by Monday and reject writes; change the source column those derive from instead.
Connect Monday.com to Google Sheets today.
Free tier: 100 imports per month, no credit card required. Or see the full Monday.com integration details.
Install Brooked free →

