# IMAP vs the Nylas Email API

Source: https://developer.nylas.com/docs/cookbook/email/imap-vs-email-api/

You can talk to most mailboxes two ways: open a raw IMAP socket yourself, or call a REST email API that wraps IMAP for you. Raw IMAP is the protocol email clients have spoken since 1996, and it works against almost any server. A REST email API trades that low-level control for JSON, one auth flow, push notifications, and the same schema across providers.

The choice here is about the protocol, not the connection steps. Writing directly against IMAP (RFC 3501) means you own the sockets and parsing; calling a unified REST API means the same work arrives in one request. For the IMAP connection steps in Nylas, see the [IMAP provider guide](/docs/provider-guides/imap/), and for the read recipe, see [list IMAP email messages](/docs/cookbook/email/messages/list-messages-imap/).

## IMAP vs the Nylas Email API

Raw IMAP is a stateful, socket-level protocol (RFC 3501) for reading one mailbox: you open a TCP connection, log in, `SELECT` a folder, then issue `FETCH` and `SEARCH` commands. A REST email API wraps that in one HTTPS call to `GET /v3/grants/{grant_id}/messages`, returns JSON, and reaches 6 providers (Google, Microsoft, Yahoo, iCloud, generic IMAP, and Exchange) through a single schema.

The two solve different layers of the same problem. IMAP is a transport: it moves messages and folder state between a server and a client, and it does that one account and one connection at a time. A REST API is an integration layer on top of that transport, so instead of managing sockets and parsing `FETCH` responses, you make a request and get a parsed message back. IMAP also stops at reading. It has no concept of sending (you add SMTP), no contacts, and no push, so a real integration is rarely "just IMAP." The table compares the work each approach actually requires.

| Task | Raw IMAP | Nylas Email API |
| --- | --- | --- |
| Protocol | TCP socket, stateful session (RFC 3501) | HTTPS, stateless JSON requests |
| Read mail | `SELECT` folder, then `FETCH`/`SEARCH` | `GET /v3/grants/{grant_id}/messages` |
| **Send mail** | **Separate SMTP server and library** | **`POST /v3/grants/{grant_id}/messages/send`** |
| Contacts | Not in the protocol, parse headers yourself | `GET /v3/grants/{grant_id}/contacts` |
| New-mail notifications | Poll, or hold an IMAP IDLE connection open | `message.created` webhook |
| Providers | One server per connection, quirks per host | 6 providers, one schema |
| Auth | Username and password or app password per box | One OAuth or app-password grant |

Bold rows mark where a REST API removes work you'd otherwise own. For a single mailbox you fully control, raw IMAP is a fine, dependency-light choice. Across many accounts and providers, the unified API is the recommended path.

## What does raw IMAP require to read and send email?

Raw IMAP requires a persistent TCP connection, a login, a selected folder, and `FETCH` or `SEARCH` commands to read mail, plus a completely separate SMTP connection to send it. IMAP (RFC 3501) is read-and-organize only; it has no command to send a message. So a working integration speaks two protocols at once: IMAP for reading, SMTP (RFC 5321) for sending.

A few things make this more involved than a single library import. IMAP is stateful, so you keep a session alive, handle `UIDVALIDITY` changes when the server renumbers messages, and decode MIME parts and encodings yourself. There's no built-in push: to learn about new mail you either poll on a timer or hold an IMAP IDLE connection open per mailbox, and IDLE connections drop and need re-establishing. Multiply all of that by every account you connect, since one IMAP session reads exactly one mailbox. That's the 30-line `FETCH` loop that quietly becomes a connection-pool, a MIME parser, and a reconnect strategy.

## How does a REST email API change the integration?

A REST email API collapses read, send, and notifications into stateless HTTPS calls against one grant. You list mail with `GET /v3/grants/{grant_id}/messages`, send with `POST /v3/grants/{grant_id}/messages/send`, and receive new-mail events through a `message.created` webhook, so there's no socket to keep alive and no separate SMTP path to configure. One grant covers all 6 providers with the same JSON.

The request below lists the 20 most recent messages from a connected account, whether that account is generic IMAP, Gmail, or Outlook. The API handles the IMAP session, the MIME parsing, and the provider differences, and returns each message with `from`, `to`, `subject`, and `body` already decoded. The `grant_id` stands in for the per-mailbox IMAP login you'd otherwise manage by hand.

```bash
curl --request GET \
  --url 'https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/messages?limit=20' \
  --header 'Authorization: Bearer <NYLAS_API_KEY>'
```

```python [imapVsApi-Python SDK]
from nylas import Client

nylas = Client(api_key="<NYLAS_API_KEY>")

messages = nylas.messages.list(
    "<NYLAS_GRANT_ID>",
    query_params={"limit": 20},
)

for message in messages.data:
    print(message.subject, message.from_)
```

Sending works the same way: one `POST /v3/grants/{grant_id}/messages/send` routes through the account's own mailbox, so the message lands in the provider's Sent folder without a separate SMTP relay. For the full read flow and IMAP-specific filters, see [list IMAP email messages](/docs/cookbook/email/messages/list-messages-imap/).

## How do you get new-mail notifications without IMAP IDLE?

Subscribe to the `message.created` webhook and the API delivers an event when mail arrives, with no open connection to maintain. Raw IMAP offers no real push: you either poll a mailbox on a timer, which adds latency and load, or hold an IMAP IDLE session open per account and re-establish it every time the server or network drops it. A webhook moves that work to the server.

This matters most as account count grows. IDLE binds one held connection to one mailbox, so watching 5,000 inboxes means 5,000 long-lived sockets you monitor and reconnect. The webhook model inverts that: you expose one HTTPS endpoint, and the API posts a small JSON event per new message across every connected account and provider. You still get raw mail access where you need it, but you stop running a connection pool just to find out something changed. Contacts follow the same pattern, derived from the account and read through one call, as covered in [list IMAP contacts](/docs/cookbook/contacts/list-contacts-imap/).

## When should you use raw IMAP directly?

Use raw IMAP directly when you integrate one mailbox you control, want zero third-party dependencies, and need byte-level access to the protocol. If you're building a desktop mail client, a personal mail archive, or a migration tool that reads a single server you own, a mature IMAP library and an SMTP library cover it, and a REST layer would only add a hop. Full control over `FETCH` ranges, flags, and folder operations is genuinely useful at that level.

The math changes once you add accounts or providers. Two providers over raw IMAP means two sets of host quirks, two auth schemes, and your own polling or IDLE loop for each; six means six. A unified REST API keeps one schema, one auth model, and one webhook stream across all 6 providers, so adding the next account is a new grant rather than new code. If you only ever touch one mailbox, raw IMAP wins on simplicity. Past that, the per-provider work you avoid is the reason the API exists.

## What's next

- [IMAP provider guide](/docs/provider-guides/imap/) for the IMAP connection and authentication steps in Nylas
- [List IMAP email messages](/docs/cookbook/email/messages/list-messages-imap/) for the unified read call, filters, and pagination on IMAP accounts
- [List IMAP contacts](/docs/cookbook/contacts/list-contacts-imap/) to read an address book the IMAP protocol doesn't provide
- [Getting started with Nylas](/docs/v3/getting-started/) to create a project, connector, and your first grant