Source: https://cli.nylas.com/guides/email-search-operators-compared

# Email Search Operators Compared

Searching email is one task with three incompatible dialects. Gmail has compact operators like from: and has:attachment, Microsoft Graph splits free-text $search from structured $filter, and IMAP uses SEARCH keys like FROM and SINCE. Knowing one doesn't help with the next, and a query that works against Gmail returns an error against Graph. This is the side-by-side reference, with one CLI syntax that papers over all three.

Written by [Caleb Geene](https://cli.nylas.com/authors/caleb-geene) Director, Site Reliability Engineering

Updated June 8, 2026

> **TL;DR:** Gmail uses compact operators (`from:`, `subject:`, `has:attachment`). Microsoft Graph splits free-text `$search` from structured `$filter` (OData). IMAP uses `SEARCH` keys (`FROM`, `SUBJECT`, `SINCE`). The three don't interoperate — and the CLI's `email search` gives you one syntax that runs server-side on whichever backend you connected.

Command references used in this guide: [`nylas email search`](https://cli.nylas.com/docs/commands/email-search) and [`nylas email list`](https://cli.nylas.com/docs/commands/email-list).

## How does email search differ across providers?

Email search differs because each provider invented its own query language for the same operations. Gmail offers a search-box syntax of `field:value` operators; Microsoft Graph exposes two separate mechanisms, a relevance-ranked `$search` and a precise OData `$filter`; IMAP defines a list of `SEARCH` keys in its protocol. The concepts overlap — sender, subject, date, attachments — but the syntax shares nothing.

That fragmentation is a real cost for anything multi-provider. A “mail from Alice with an attachment since Monday” query is three different strings across Gmail, Graph, and IMAP, and a feature that searches inboxes has to know which dialect each account speaks. The rest of this guide is the translation table, ending with a single syntax that removes the branching.

## What are the Gmail search operators?

Gmail's operators are the most compact of the three, the same ones the Gmail search box accepts. You combine `field:value` tokens with spaces (implicit AND), `OR`, and parentheses. The [Gmail search operators reference](https://support.google.com/mail/answer/7190) lists dozens; the table below covers the ones nearly every integration uses.

| Intent | Gmail | Microsoft Graph | IMAP SEARCH |
| --- | --- | --- | --- |
| From a sender | `from:alice@x.com` | `$filter=from/...eq 'alice@x.com'` | `FROM "alice@x.com"` |
| Subject contains | `subject:invoice` | `$search="subject:invoice"` | `SUBJECT "invoice"` |
| Has attachment | `has:attachment` | `$filter=hasAttachments eq true` | *(no direct key)* |
| Since a date | `after:2026/06/01` | `$filter=receivedDateTime ge...` | `SINCE 1-Jun-2026` |
| Unread only | `is:unread` | `$filter=isRead eq false` | `UNSEEN` |

## How does Microsoft Graph search work?

Graph deliberately separates two needs. `$search` does relevance-ranked full-text matching — `?$search="invoice"` finds messages mentioning the word, ordered by relevance, and can't be combined with arbitrary sorting. `$filter` does exact, structured matching with OData operators (`eq`, `ge`, `and`) over typed properties like `receivedDateTime` and `hasAttachments`.

The practical rule, from the [Graph filter documentation](https://learn.microsoft.com/en-us/graph/filter-query-parameter), is to use `$search` for “contains this text” and `$filter` for “matches these exact conditions.” Mixing them has restrictions, and some property combinations require the `ConsistencyLevel: eventual` header. This split is the single biggest difference from Gmail's one-box model.

## How does IMAP SEARCH work?

IMAP search is a protocol command, not a query string. The `SEARCH` command, defined in [RFC 3501](https://www.rfc-editor.org/rfc/rfc3501), takes space-separated keys like `FROM`, `SUBJECT`, `SINCE`, `UNSEEN`, and `BODY`, which the server ANDs together. It returns message sequence numbers, not the messages — you then fetch the ones you want.

Its limits show quickly: there's no relevance ranking, no `has:attachment` equivalent (you inspect body structure instead), and server support for extensions varies. IMAP search is reliable for the basics and awkward beyond them, which is why richer clients lean on provider APIs where they exist.

## How do you search with one syntax across providers?

The `nylas email search` command runs a query server-side against whichever provider you connected, so you write one syntax instead of three. It returns matching messages as JSON, executed on the backend rather than downloaded and filtered locally — which matters on a 50,000-message mailbox where client-side filtering would be slow. The same command works whether the account is Gmail, Outlook, or IMAP.

That uniformity is the payoff: a feature searching across mixed provider accounts uses identical calls, and you don't maintain three query builders. For Gmail-specific operator depth, the dedicated [Gmail search query guide](https://cli.nylas.com/guides/gmail-api-search-query) goes further; for shaping the JSON results, see [extract email data with jq](https://cli.nylas.com/guides/extract-email-data-jq).

```bash
# One syntax, server-side, on whichever provider is connected
nylas email search "from:alice@example.com subject:invoice" --json --limit 20

# Unread mail since a date
nylas email search "is:unread after:2026/06/01" --json

# Pipe results into jq for the fields you want
nylas email search "has:attachment" --json \
  | jq -r '.[] | "\(.from[0].email)\t\(.subject)"'
```

## Next steps

- [Gmail API search query](https://cli.nylas.com/guides/gmail-api-search-query) — Gmail operators in depth
- [Search email from the terminal](https://cli.nylas.com/guides/search-email-from-terminal) — the full `email search` walkthrough
- [Extract email data with jq](https://cli.nylas.com/guides/extract-email-data-jq) — shape JSON search results
- [IMAP vs Gmail API vs Graph API](https://cli.nylas.com/guides/imap-vs-gmail-api-vs-graph-api) — the broader protocol comparison
- [Full command reference](https://cli.nylas.com/docs/commands) — every flag and subcommand documented
