Guide
Export Email to CSV from the Terminal
Someone always asks for the email list 'as a spreadsheet.' CSV is the answer, and it's one command away once the data is clean JSON. The Nylas CLI returns messages as JSON; jq's @csv operator turns them into properly quoted rows that Excel and Google Sheets open without complaint. This guide builds a correct CSV export — headers, RFC 4180 quoting, and the fields people actually want — and shows how to handle commas, quotes, and newlines inside subjects safely.
Written by Prem Keshari Senior SRE
Command references used in this guide: nylas email list, nylas email search, and nylas email read.
How do you export email to CSV?
You export email to CSV by piping the CLI's JSON through jq's @csv operator, which formats an array of values as one correctly quoted CSV row. nylas email list --json gives you the messages; jq maps each to a row of the fields you want. The -r flag prints raw output so the file contains literal CSV, not JSON-escaped strings.
The reason to use @csv rather than joining with commas yourself is correctness. CSV is deceptively tricky — a subject containing a comma, a quote, or a newline breaks a naive join — and @csv implements the quoting rules from RFC 4180 so those cases just work. One operator replaces a pile of escaping code.
# Build a CSV with a header row, one message per line
{
echo 'date,from,subject'
nylas email list --json --limit 200 \
| jq -r '.[] | [ (.date|tostring), (.from[0].email // ""), (.subject // "") ] | @csv'
} > inbox.csvHow do you add headers and choose columns?
Add a header row by echoing it before the jq output, and choose columns by editing the array jq builds. The array's order is the column order, so [date, from, subject] produces those three columns in that sequence. Add a column — a thread ID, an unread flag, a recipient — by extending the array and the header to match.
Use null-safe fallbacks so every row has the same column count. A message missing a subject would otherwise emit a short row that misaligns the spreadsheet; // "" fills the gap with an empty cell. Keep the header and the array in lockstep — a mismatch between them is the most common cause of a CSV that looks shifted by one column.
# More columns: date, from, to, subject, unread
{
echo 'date,from,to,subject,unread'
nylas email search "newer_than:7d" --json --limit 500 \
| jq -r '.[] | [
(.date|tostring),
(.from[0].email // ""),
((.to // []) | map(.email) | join(";")),
(.subject // ""),
(.unread // false)
] | @csv'
} > week.csvHow do you make the CSV open cleanly in Excel?
For Excel, two details matter: encoding and how it interprets the date column. Write the file as UTF-8 and, if non-ASCII subjects show as garbled, prepend a UTF-8 byte-order mark so Excel detects the encoding. The epoch timestamps the CLI returns are numbers; convert them to a readable date in jq if you want Excel to treat the column as a date rather than a large integer.
Convert the timestamp with jq's strftime after todate or gmtime, producing an ISO date string Excel and Google Sheets both parse. Quote the whole pipeline once and reuse it as a script, so anyone on the team can regenerate the export by running one command. The result is a file that opens correctly on the first try, which is the entire point of getting the quoting right.
# Human-readable ISO dates instead of epoch seconds
nylas email list --json --limit 200 \
| jq -r '.[] | [
(.date | gmtime | strftime("%Y-%m-%d %H:%M")),
(.from[0].email // ""),
(.subject // "")
] | @csv' > inbox.csvNext steps
- Extract email data with jq — the full jq toolkit for email
- Log email to Google Sheets — a live sheet instead of a file
- Back up emails to JSON — keep the structured source too
- Organize emails by company — group before you export
- Load email into Postgres — query instead of exporting a flat file
- Full command reference — every flag and subcommand documented