Guide

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 Director of Product Management

VerifiedCLI 3.1.17 · Gmail, Outlook · last tested June 9, 2026

Command references used in this guide: nylas email search, nylas email list, and nylas 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. Below, the CLI pulls the latest leads into a file so the next step has clean JSON to read.

# 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.

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 documents the full create_item input.

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.

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.

# 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