Source: https://cli.nylas.com/guides/email-to-monday-items

# Create monday.com Items from Email

Sales leads, support tickets, and project requests arrive by email, but the work gets tracked on a monday.com board. The manual hop is copy-paste: read the email, open the board, retype the title into a new item. This guide closes the loop from the terminal — pull messages as JSON with the CLI, then POST a single GraphQL create_item mutation to the monday.com API with your board ID. No paid connector, no per-item fee.

Written by [Hazik](https://cli.nylas.com/authors/hazik) Director of Product Management

Updated June 9, 2026

> **TL;DR:** Pull messages with `nylas email search --json`, then create one item per message by POSTing a GraphQL `create_item` mutation to `https://api.monday.com/v2` with a `board_id`. The CLI handles the inbox across six providers; one mutation handles the write. The catch most people miss is where the `board_id` comes from — resolved below in two lines of GraphQL.

Command references used in this guide: [`nylas email search`](https://cli.nylas.com/docs/commands/email-search), [`nylas email list`](https://cli.nylas.com/docs/commands/email-list), and [`nylas email read`](https://cli.nylas.com/docs/commands/email-read).

## How do you create a monday.com item from an email?

You create a monday.com item from an email by pulling the message as JSON and sending one GraphQL `create_item` mutation. The Nylas CLI returns structured messages with `nylas email search --json`, and a single POST to `https://api.monday.com/v2` creates the item. monday.com has one GraphQL endpoint — every read and write goes through that one URL.

Two setup steps come first. Generate a personal API token in monday.com under your avatar, Developers, My Access Tokens, then export it as `MONDAY_TOKEN`. The API authenticates with the raw token in the `Authorization` header, per the [monday.com authentication docs](https://developer.monday.com/api-reference/reference/authentication). Below, the CLI pulls the latest leads into a file so the next step has clean JSON to read.

```bash
# Pull the email you want to file into a board, into a JSON file
nylas email search "new lead" --after 2026-06-08 --json --limit 50 > items.json
```

## Where does the monday.com board ID come from?

The `board_id` is a numeric identifier that scopes an item to one board, and `create_item` rejects the mutation without it. You can read it from the board URL, but the reliable path is a `boards` query against the same GraphQL endpoint. A workspace with 12 boards returns up to 25 nodes per page by default.

Query the endpoint once and cache the result. Match on the board name you recognize rather than the numeric ID, since the name is readable while the ID is not. monday.com returns the `id` as a string in the JSON even though it is numeric, so quote it when you reuse it. The command below pipes the response through `jq` to print name-to-ID pairs, following the [monday.com GraphQL introduction](https://developer.monday.com/api-reference/docs/introduction-to-graphql).

```bash
curl -s -X POST https://api.monday.com/v2 \
  -H "Authorization: $MONDAY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query":"{ boards(limit: 25) { id name } }"}' \
  | jq -r '.data.boards[] | "\(.name)\t\(.id)"'
```

## How do you map an email to a create_item mutation?

Map the email subject to the item name passed inside the `create_item` input alongside the `board_id`. The mutation returns the new item's `id`, so one round trip both creates and confirms. Extra fields like the sender email or a date go in `column_values` as a JSON string keyed by column ID.

Build the request with GraphQL variables instead of string-interpolating the email text, so a subject containing quotes or a backslash cannot break the query. The pattern below reads each message from the JSON, extracts the `subject` and sender with `jq`, and sends the same mutation per message. A blank subject falls back to a placeholder so no item is created untitled. The [monday.com items reference](https://developer.monday.com/api-reference/reference/items) documents the full `create_item` input.

```bash
BOARD_ID="1234567890"
MUTATION='mutation($b:ID!,$name:String!,$cols:JSON){ create_item(board_id:$b, item_name:$name, column_values:$cols){ id } }'

jq -c '.[]' items.json | while read -r msg; do
  name=$(echo "$msg"   | jq -r '.subject // "(no subject)"')
  sender=$(echo "$msg" | jq -r '.from[0].email // ""')
  cols=$(jq -nc --arg e "$sender" '{email_col:{email:$e, text:$e}}')
  jq -n --arg q "$MUTATION" --arg b "$BOARD_ID" --arg name "$name" --arg cols "$cols" \
    '{query:$q, variables:{b:$b, name:$name, cols:$cols}}' \
  | curl -s -X POST https://api.monday.com/v2 \
      -H "Authorization: $MONDAY_TOKEN" \
      -H "Content-Type: application/json" \
      --data @- \
  | jq -r '.data.create_item.id'
done
```

## How do you avoid creating the same item twice?

Keep a board from filling with duplicate items by recording each filed message and querying monday.com for that source ID before creating a new item. Pair that with an `--after` window so a daily run only sees the last 24 hours, and the stable Nylas message `id` becomes your dedupe key.

Keep a flat file of processed IDs and skip any message already in it. This survives reruns, partial failures, and an overlapping search window without creating a second board item. For a 50-message daily batch, the ledger check adds under 1 second. Append each ID only after `create_item` returns a non-null `id`, so a failed call retries on the next run.

```bash
touch filed.txt
jq -c '.[]' items.json | while read -r msg; do
  id=$(echo "$msg" | jq -r '.id')
  grep -qx "$id" filed.txt && continue   # already filed, skip
  # ... run the create_item mutation here ...
  echo "$id" >> filed.txt
done
```

## Why drive this from a webhook instead of a cron poll?

A webhook creates the item the moment the email arrives, while a cron poll waits for the next scheduled run. For a sales team, the gap between a daily poll and a webhook is up to 24 hours of delay before a lead lands on the board. The Nylas CLI exposes a `message.created` trigger that fires on each new message, and monday.com caps writes by a complexity budget of 5,000,000 points per minute.

Run a local webhook server with `nylas webhook server`, which opens a tunnel and prints events as they arrive. The same `create_item` mapping runs per event — only the trigger changes from a poll to a push. The monday.com token stays separate from the mailbox grant the CLI manages, so you rotate them independently. The command below subscribes to new-message events.

```bash
# Subscribe to new-message events, then map each to a create_item call
nylas webhook create --url https://your-app.example.com/hooks --triggers message.created
```

## Next steps

- [Fireflies vs Nylas Notetaker: Meeting Bots](https://cli.nylas.com/guides/fireflies-vs-nylas-notetaker) — Fireflies is a meeting-notes app with a GraphQL API for reading…
- [File Linear issues from email](https://cli.nylas.com/guides/email-to-linear-issues) — the same pattern against a GraphQL issueCreate mutation
- [Create Asana tasks from email](https://cli.nylas.com/guides/email-to-asana-tasks) — the same pattern into an Asana project
- [Open GitHub issues from email](https://cli.nylas.com/guides/email-to-github-issues) — file messages as repository issues
- [Send email to a Notion database](https://cli.nylas.com/guides/email-to-notion) — file messages as Notion pages
- [Extract email data with jq](https://cli.nylas.com/guides/extract-email-data-jq) — the JSON-shaping toolkit
- [Full command reference](https://cli.nylas.com/docs/commands) — every flag and subcommand documented
- [monday.com items API reference](https://developer.monday.com/api-reference/reference/items) — the full create_item input and column types
- [monday.com rate limits](https://developer.monday.com/api-reference/reference/rate-limits) — the complexity budget and per-minute caps
- [jq manual](https://jqlang.github.io/jq/manual/) — the JSON filter reference used throughout
- [RFC 5322](https://datatracker.ietf.org/doc/html/rfc5322) — the internet message format behind every email field
