Guide

Send Email to a Notion Database (CLI)

Teams run intake in Notion — sales leads, bug reports, candidate pipelines — and the source is often email. The usual bridge is a paid automation that charges per record. The Nylas CLI gives you the email as JSON; the Notion API creates a database page per message with the properties mapped. This guide builds an email-to-Notion pipeline you control, mapping subject, sender, and date to Notion properties, and running it on a schedule for free.

Written by Nick Barraclough Product Manager

VerifiedCLI 3.1.16 · Gmail, Outlook · last tested June 8, 2026

Command references used in this guide: nylas email search, nylas email list, and nylas email read.

How do you send email to a Notion database?

You send email to Notion by pulling the messages as JSON and creating one page per message in a Notion database. The CLI returns structured messages with nylas email search --json, and a single POST to the Notion API /v1/pages endpoint creates a page with your mapped properties. The page-creation contract is documented in the Notion API reference.

Two setup steps come first: create an internal integration to get a token, and share the target database with it so the integration can write. Notion's permission model is share-based, so a database the integration can't see returns a 404 — connecting it is a one-time click. After that, each message maps cleanly to a page.

# Pull the messages you want to file into Notion
nylas email search "subject:bug report newer_than:1d" --json --limit 50 > items.json

How do you map a message to Notion properties?

Map each message to a Notion properties object, where the database's title property holds the subject and your other columns hold the sender, date, or status. Notion types each property — title, rich_text, email, date — so the request must wrap values in the matching shape. The subject goes under the title property as a title array; the sender fits an email property directly.

Build the properties object with jq so the mapping is explicit and null-safe. A message with no subject would otherwise create a blank-titled page, so fall back to a placeholder. Keep the property names exactly matching your database schema, since Notion rejects unknown property keys rather than ignoring them.

DB_ID="your-database-id"
jq -c '.[]' items.json | while read -r msg; do
  subject=$(echo "$msg" | jq -r '.subject // "(no subject)"')
  sender=$(echo "$msg"  | jq -r '.from[0].email // ""')
  curl -s -X POST https://api.notion.com/v1/pages \
    -H "Authorization: Bearer $NOTION_TOKEN" \
    -H "Notion-Version: 2022-06-28" \
    -H "Content-Type: application/json" \
    -d "{\"parent\":{\"database_id\":\"$DB_ID\"},
         \"properties\":{
           \"Name\":{\"title\":[{\"text\":{\"content\":\"$subject\"}}]},
           \"Sender\":{\"email\":\"$sender\"}}}"
done

How do you keep the database in sync?

Keep it in sync by running the pipeline on a schedule and de-duplicating on a stable field. Store each message's ID in a Notion property and query before creating, or scope the search to newer_than:1d and run daily so you only ever process the last day's mail. A daily cron that files new bug reports keeps the database current without re-importing the whole inbox.

For near-real-time intake, drive the same create step from a webhook instead of a poll — when a new message arrives, file it immediately. The mapping code is identical; only the trigger changes. The Notion token is separate from the mailbox grant the CLI manages, so rotate them independently.

Next steps