Guide

Receive Email Without an SMTP Server

You want an inbox that receives mail — without configuring MX records, installing Postfix, or wiring up spam filters. A Nylas agent account gives you a managed email identity backed by provider=nylas: read messages with the standard email surface and subscribe to webhooks for real-time delivery. No OAuth, no third-party mailbox.

Written by Hazik Director of Product Management

Reviewed by Caleb Geene

VerifiedCLI 3.1.1 · Gmail, Outlook, IMAP · last tested April 11, 2026

The problem with receiving email

Self-hosted inbound email requires at least five separate systems — MX records, an SMTP daemon, spam filtering, TLS certificates, and a MIME parser — each carrying its own maintenance burden and security surface. According to Postfix's own advisory list, the most popular open-source MTA has published 12 security patches since 2020, and each one demands a restart and a smoke test to confirm mail still flows. A managed agent account removes all five layers at once.

Those five systems break down as follows:

  1. MX records — DNS entries that tell the internet where to deliver your mail
  2. SMTP daemon — Postfix or Exim to accept the connection and store the message
  3. Spam filtering — SpamAssassin or rspamd to reject junk before it fills your queue
  4. TLS certificates — required by senders that enforce opportunistic TLS
  5. MIME parser — to decode multipart messages, attachments, and encoded headers (the wire format itself is defined in RFC 5322 and the multipart structure in RFC 2045; getting these wrong is a frequent source of CVEs in mail handlers)

A managed agent email account handles all five layers. You get a managed address, a JSON API, and webhook delivery — without touching DNS or a mail daemon.

1. Install

The Nylas CLI installs as a single static binary — under 30 MB on disk — and supports macOS, Linux, and Windows. Homebrew is the fastest method, pulling the latest release from the nylas/nylas-cli tap and linking the binary in one step.

brew install nylas/nylas-cli/nylas

For shell-script, PowerShell, and Go installs, see the getting started guide.

2. Authenticate

Before creating agent accounts, the Nylas CLI needs a valid API key tied to your Nylas application. Authentication takes about 5 seconds: run the config command, paste the key, and the CLI persists the credential locally so every subsequent command inherits it.

The nylas auth config command stores your key in ~/.config/nylas/. The credential is scoped to one Nylas application and never leaves your machine.

nylas auth config

Paste your Nylas API key when prompted. The credential file is plain-text, so protect it with chmod 600 on shared machines.

3. Create an agent account

An agent account is a fully managed email identity backed by provider=nylas that can receive (and send) mail without OAuth, MX records, or a third-party mailbox. The Nylas API provisions the address in under 2 seconds and assigns it a grant ID that works with every standard email endpoint. Each Nylas application can hold multiple agent accounts, so a single API key can manage support, no-reply, and test inboxes.

Pick the local-part you want, then create the account. The CLI provisions a managed address under your application's *.nylas.email zone:

nylas agent account create support@yourapp.nylas.email
✓ Agent account created successfully!

  Email:      support@yourapp.nylas.email
  Provider:   nylas
  Status:     valid

The account is backed by provider=nylas — no OAuth handshake, no third-party mailbox. Share the address wherever you want to receive mail: contact forms, transactional flows, or test automation. For a hands-on walkthrough of the full identity (send + IMAP/SMTP receive), see Create an AI Agent Email Identity.

4. List your agent accounts

Listing agent accounts returns every managed address under the current Nylas application, along with each account's status and grant ID. The default output is a human-readable table; adding --json produces machine-parseable JSON for piping into jq or other tooling. The command completes in roughly 200 ms regardless of how many accounts exist.

# Human-readable table
nylas agent account list

# JSON output (pipe-friendly)
nylas agent account list --json
Agent Accounts (2)

1. support@yourapp.nylas.email            active
   ID: 11111111-1111-1111-1111-111111111111

2. noreply@yourapp.nylas.email            active
   ID: 22222222-2222-2222-2222-222222222222

5. Read received messages

The nylas email list command reads messages from any agent account using the same email surface that works with Gmail, Outlook, and IMAP grants. By default, the CLI returns the 10 most recent messages on the active grant. Adding --grant targets a specific agent account by its grant ID, and --unread filters to unread messages only — useful for polling loops in scripts.

Pass --grant to target a specific account explicitly:

# Latest messages on the active grant
nylas email list

# JSON output
nylas email list --json

# Unread only, against a specific agent account
nylas email list \
  --grant 11111111-1111-1111-1111-111111111111 \
  --unread --json
[
  {
    "id": "msg_a1b2c3d4",
    "from": [{ "name": "Alice Smith", "email": "alice@example.com" }],
    "to":   [{ "email": "support@yourapp.nylas.email" }],
    "subject": "Login issue on mobile",
    "snippet": "Hi, I can't log in on iOS 17. The button just spins...",
    "date": "2026-03-28T09:14:22Z",
    "unread": true
  }
]

6. Set up webhooks for real-time processing

Nylas webhooks push event payloads to your server within seconds of a message arriving, eliminating the latency and wasted API calls of polling. The nylas webhook create command registers an HTTPS endpoint and subscribes it to one or more event triggers. Nylas supports 7 message-level triggers — from message.created for inbound mail to message.link_clicked for engagement tracking — so a single webhook can cover the full message lifecycle.

Register a webhook endpoint and subscribe to the message.created trigger to receive inbound mail notifications:

nylas webhook create \
  --url https://example.com/hook \
  --triggers message.created
✓ Webhook created

  Webhook ID: whk_9p0q1r2s3t4u
  URL:        https://example.com/hook
  Triggers:   message.created
  Status:     active

A single webhook can subscribe to multiple event types. Repeat the --triggers flag for each event you want to capture. This is useful when you need to track both inbound delivery and outbound engagement from the same endpoint:

nylas webhook create \
  --url https://example.com/hook \
  --triggers message.created \
  --triggers message.bounce_detected \
  --triggers message.link_clicked

The nylas webhook list command shows all active subscriptions, and nylas webhook delete removes one by its ID. Both commands complete in under 500 ms:

# List all webhooks
nylas webhook list

# Delete a webhook
nylas webhook delete whk_9p0q1r2s3t4u

Available message triggers

TriggerFires when
message.createdNew email arrives
message.updatedMessage flags change (e.g., marked read)
message.bounce_detectedA sent message bounced
message.send_successA sent message was accepted by the recipient server
message.send_failedA send attempt failed
message.openedRecipient opened the message (pixel tracking)
message.link_clickedRecipient clicked a tracked link

7. Per-test isolated inboxes

Agent accounts can be created and destroyed programmatically, which makes them ideal for test automation. Provisioning a fresh account takes under 2 seconds via the CLI, so each test run gets its own clean inbox with zero shared state. This pattern eliminates the flaky cross-test contamination that plagues shared mailboxes in CI pipelines — a problem that, according to a 2023 Launchable study, accounts for roughly 30% of flaky end-to-end test failures.

The following Node.js snippet creates a UUID-based agent account before each test and tears it down afterward. The execFileSync call uses argument-array form to avoid shell injection:

import { randomUUID } from 'node:crypto'
import { execFileSync } from 'node:child_process'

const localPart = `e2e-${randomUUID()}`
const email = `${localPart}@yourapp.nylas.email`

// Provision a one-shot agent account for this test (arg-array form, no shell)
const out = execFileSync(
  'nylas',
  ['agent', 'account', 'create', email, '--json'],
  { encoding: 'utf-8' }
)
const { id: grantId } = JSON.parse(out)

// Send your transactional email to `email`.
// Then poll the inbox: execFileSync('nylas', ['email', 'list', '--grant', grantId, '--unread', '--json'])
// Tear down at the end:  execFileSync('nylas', ['agent', 'account', 'delete', grantId, '--yes'])

Parallel test workers don't interfere with each other, and clean-up is one command per inbox.

8. Clean up

Deleting an agent account revokes its underlying provider=nylas grant, immediately stops accepting inbound mail, and removes the address from your application's account list. Webhooks are separate resources — deleting an account does not automatically remove associated webhooks, so delete those explicitly to avoid orphaned subscriptions.

Both deletions are idempotent. Re-running them against an already-deleted resource returns a 404 but causes no side effects:

# Delete an agent account (revokes the underlying provider=nylas grant)
nylas agent account delete 11111111-1111-1111-1111-111111111111 --yes

# Delete a webhook
nylas webhook delete whk_9p0q1r2s3t4u

Next steps