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

Standing up a working inbound email pipeline from scratch requires five separate systems:

  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)

Postfix alone has issued 12 security advisories since 2020. Each one requires a patch, a restart, and a test to confirm mail still flows.

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

1. Install

brew install nylas/nylas-cli/nylas

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

2. Authenticate

nylas auth config

Paste your Nylas API key when prompted. The CLI stores credentials in ~/.config/nylas/.

3. Create an agent account

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

# 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

Once an agent account is the active grant, the standard email surface reads its inbox. 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

Polling works for scripts and ad-hoc checks. For production, use a webhook so your server is notified the moment a message arrives.

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

Subscribe to multiple triggers at once by repeating the flag:

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

List and manage your webhooks:

# 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

For test automation, create a fresh agent account per test run. Each test gets its own clean inbox — no cross-test bleed-through, no shared state to reset between runs:

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

# 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