Guide

Track Event RSVPs from the Terminal

Send a calendar invite, read who accepted or declined straight from the event JSON, then email the people who never replied. This guide closes the whole RSVP loop from the CLI — invite, count responses, chase non-responders — with no spreadsheet and no manual follow-up.

Written by Prem Keshari Senior SRE

Reviewed by Qasim Muhammad

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

How do I send calendar invites from the terminal?

You send invites by creating one event and listing every guest with a repeated --participant flag on nylas calendar events create. Each address gets a real calendar invitation it can accept or decline, and every reply lands back on the same event — the source of truth for RSVP tracking.

The command below books a 60-minute event and invites four guests in a single call. The CLI prints the new event ID on success; capture it, since every later step reads or updates that one ID. A 30-person invite is the same command with 30 --participant lines, not 30 separate sends.

nylas calendar events create \
  --title "Q3 Planning Offsite" \
  --start "2026-07-10 09:00" --end "2026-07-10 10:00" \
  --location "Boardroom A" \
  --participant alice@example.com \
  --participant bob@example.com \
  --participant carol@example.com \
  --participant dave@example.com

How do I read who accepted or declined?

Each guest's reply lives in the participants array on the event. Run nylas calendar events show --json and read the status field on each entry. Nylas normalizes every provider to four values, so Google and Outlook replies read identically.

The four statuses are yes, no, maybe, and noreply — though events rsvp only writes yes, no, or maybe; noreply is the default state until a guest responds. Piping through jq turns one API call into a clean attendee-by-attendee table you can scan in a second.

# One row per guest: email and current RSVP
nylas calendar events show "$EVENT_ID" --json \
  | jq -r '.participants[] | "\(.email)\t\(.status)"'

# alice@example.com   yes
# bob@example.com     no
# carol@example.com   noreply
# dave@example.com    maybe

How do I count the responses at a glance?

A headcount answers the only question an organizer asks before catering or booking a room: how many are coming? Group the same participants array by status with one jq expression and you get accepted, declined, tentative, and silent totals.

The query below tallies all four buckets from a single events show call, so a 30-guest event resolves in one request instead of polling each attendee. Run it on a schedule and you have a live RSVP dashboard with zero stored state — the event itself is the database.

nylas calendar events show "$EVENT_ID" --json \
  | jq -r '.participants | group_by(.status)[]
      | "\(.[0].status): \(length)"'

# yes: 1
# no: 1
# maybe: 1
# noreply: 1

How do I chase the people who never replied?

Non-responders are the guests whose status is still noreply. Filter the event's participant list for that value, then loop the addresses into nylas email send. Adding --track-opens tells you who at least saw the nudge.

The snippet emails only the silent guests, so the four people who already answered never get a reminder. Each send is a single OAuth-backed call with no SMTP setup, and the open-tracking pixel records a read within seconds of delivery. Swap --yes out while testing to preview each message before it leaves.

nylas calendar events show "$EVENT_ID" --json \
  | jq -r '.participants[] | select(.status == "noreply") | .email' \
  | while read -r guest; do
      nylas email send --to "$guest" \
        --subject "Quick RSVP for the Q3 Planning Offsite?" \
        --body "We have not heard from you yet. Can you accept or decline the calendar invite?" \
        --track-opens --track-label rsvp-chase --yes
    done

How do I run the whole RSVP loop as one script?

The closed loop chains three reads and one send: pull the event, print the counts, find the silent guests, and email each one. The script below does exactly that and exits early when everyone has answered, so a fully-replied 30-person event sends zero chase emails and finishes in under a second.

Schedule it once a day with cron and the follow-up runs itself until the last noreply clears. Because the event JSON holds the live status, the script is stateless — rerunning it is always safe and never double-pings a guest who replied between runs.

#!/usr/bin/env bash
set -euo pipefail
EVENT_ID="$1"

EVENT=$(nylas calendar events show "$EVENT_ID" --json)

echo "RSVP counts:"
echo "$EVENT" | jq -r '.participants | group_by(.status)[]
  | "  \(.[0].status): \(length)"'

PENDING=$(echo "$EVENT" | jq -r '.participants[]
  | select(.status == "noreply") | .email')

[ -z "$PENDING" ] && { echo "everyone has responded"; exit 0; }

echo "$PENDING" | while read -r guest; do
  nylas email send --to "$guest" \
    --subject "Quick RSVP?" \
    --body "Please accept or decline the calendar invite when you get a moment." \
    --track-opens --track-label rsvp-chase --yes
done

Next steps