Source: https://cli.nylas.com/guides/auto-label-incoming-email-cli

# Auto-Organize Incoming Email by Rule

Auto label incoming email without touching your inbox. A message.created webhook fires on every new message, your script classifies it with deterministic rules, and the CLI flags and files it using nylas email mark and folder IDs from nylas email folders list.

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

Reviewed by [Qasim Muhammad](https://cli.nylas.com/authors/qasim-muhammad)

Updated June 9, 2026

> **TL;DR:** Register a `message.created` webhook, run each new message through deterministic rules, then sort it with `nylas email mark` and folder IDs from `nylas email folders list`. One rule order decides which match wins when a message hits two rules — the priority section explains how to make that deterministic.

## How do I auto-organize incoming email by rule?

Auto-organizing incoming email means a webhook fires the instant a message arrives, a script matches the message against a rule set, and the CLI flags or files it — no human opens the inbox. The Nylas CLI delivers the `message.created` trigger and the commands that act on each message. The average professional receives 121 emails per day, per the Radicati Group, so rule-based sorting removes a recurring manual task.

The pipeline has three stages: a `message.created` webhook for the event, a classifier that reads sender and subject fields, and the action commands. Rules are deterministic: the same sender domain always lands in the same folder, so the result is reproducible and auditable. Start by listing your folders to get the target IDs.

```bash
# List every folder/label and its ID, so rules can target real folders
nylas email folders list --json | \
  jq '.[] | {id: .id, name: .name}'
```

## How do I trigger a rule when a new message arrives?

You trigger a rule on arrival by registering a webhook for the `message.created` event. The `nylas webhook create` command points one HTTPS endpoint at the trigger; every new message then arrives as a POST within 1 to 2 seconds, carrying the message ID, sender, subject, and folder placement your classifier needs.

Each webhook POST is signed with HMAC-SHA256, so your endpoint can reject forged events before classifying. Run `nylas webhook triggers` to confirm the trigger name is exactly `message.created`. One webhook covers an entire mailbox, and Nylas retries failed deliveries, so a brief outage on your endpoint does not drop events.

```bash
# One webhook fires on every newly received message
nylas webhook create \
  --url https://your-server.example.com/incoming-mail \
  --triggers message.created \
  --description "auto-sort incoming mail"
```

## How do I classify a message and file it?

You classify a message by reading its sender and subject from the webhook payload, matching against your rule set, then calling the right action command. The CLI exposes `nylas email mark` for read and starred flags and `nylas email folders list` to resolve folder IDs. A single rule pass over one message runs in well under 1 second, so a mailbox taking 121 emails per day costs only a few seconds of total processing.

The handler below treats each rule as a sender-domain match mapped to an action. Receipts get starred, newsletters get marked read, and everything else stays untouched in the inbox. Mark commands take the message ID straight from the `message.created` payload, so no extra lookup is needed before acting.

```bash
#!/usr/bin/env bash
# Receives the webhook JSON on stdin; sorts one message by sender domain.
MSG=$(cat)
ID=$(echo "$MSG" | jq -r '.data.object.id')
FROM=$(echo "$MSG" | jq -r '.data.object.from[0].email')

case "$FROM" in
  *@receipts.stripe.com) nylas email mark starred "$ID" ;;
  *@news.* | *@email.*)  nylas email mark read "$ID" ;;
  *)                     : ;;  # leave in inbox, no action
esac
```

To file a message into a custom folder rather than flag it, resolve the folder ID once with `nylas email folders list`, then reassign the message's folder through the Nylas API. Gmail uses labels (one message can carry several at once) while Outlook uses single-parent folders, so the same rule produces a slightly different result per provider.

## Why does rule order matter for incoming mail?

Rule order matters because one message can match two rules at once — a receipt from a domain you also marked as a newsletter. Without a defined order, the outcome depends on which condition the loop hits first, and the result becomes non-deterministic. Evaluating rules in a fixed sequence and stopping at the first match makes every classification reproducible.

Order your rules most-specific first: an exact sender address before a domain wildcard, a domain before a catch-all. A rule set of 10 to 20 patterns covers most personal inboxes. The `case` statement above already does this — it tests the exact receipts domain before the broader `news.*` pattern and exits on the first hit. Gmail's own server-side filters evaluate every matching rule, which can apply two labels to one message; a first-match script avoids that ambiguity for the actions you care about.

```bash
# Verify a captured payload's signature before any rule runs
nylas webhook verify \
  --payload-file event.json \
  --signature "$X_NYLAS_SIGNATURE" \
  --secret "$WEBHOOK_SECRET"
```

## How do I test sorting rules before going live?

Test your rules locally with the built-in webhook receiver, which prints each `message.created` payload so you see the exact shape your classifier parses. The `nylas webhook server` command starts a local endpoint on the port you pick; send yourself a test email and the event lands within 2 to 3 seconds.

Run rules in dry-run first: log the action each rule would take instead of calling `nylas email mark`, so a wrong pattern can't bury a real message. Once the logged decisions look right across 20 or 30 sample messages, swap the log line for the live command. The receiver verifies the HMAC signature when you pass a secret, matching production behavior.

```bash
# Start a loopback receiver, then send yourself a test message
nylas webhook server --port 9000 --no-tunnel
```

## Next steps

- [Send and Parse Email with One API](https://cli.nylas.com/guides/send-and-parse-email-one-api) — Send with nylas email send and parse replies with nylas email…
- [Send Email Alerts to Microsoft Teams](https://cli.nylas.com/guides/email-to-teams-notifications) — Forward matching email into a Teams channel after the connector…
- [Create Zendesk Tickets from Email (CLI)](https://cli.nylas.com/guides/email-to-zendesk-tickets) — Pull inbound email as JSON with the CLI, map subject and sender to…
- [Get Alerts for VIP Sender Emails](https://cli.nylas.com/guides/vip-sender-email-alerts-cli) — Fire an alert when a VIP emails you
- [Move emails between folders](https://cli.nylas.com/guides/move-emails-between-folders) — create, list, and reassign folders for your sorting rules
- [Mark emails read and unread](https://cli.nylas.com/guides/mark-emails-read-unread-cli) — the flag actions your rules call on each match
- [Build an AI email triage agent](https://cli.nylas.com/guides/build-ai-email-triage-agent) — when deterministic rules aren't enough, classify with a model
- [Turn emails into GitHub issues](https://cli.nylas.com/guides/email-to-github-issues) — route matched messages to a tracker instead of a folder
- [Turn emails into Asana tasks](https://cli.nylas.com/guides/email-to-asana-tasks) — another rule destination driven by the same webhook
- [Command reference](https://cli.nylas.com/docs/commands) — every flag, subcommand, and example
- [Gmail API labels guide](https://developers.google.com/workspace/gmail/api/guides/labels) — how Gmail's multi-label model differs from folders
- [Microsoft Graph mailFolder](https://learn.microsoft.com/en-us/graph/api/resources/mailfolder) — the single-parent folder model on Outlook
- [RFC 3501 (IMAP)](https://datatracker.ietf.org/doc/html/rfc3501) — the mailbox and flag semantics behind every provider
