Source: https://cli.nylas.com/guides/lead-capture-agent-account

# Build a Lead-Capture & Qualification Agent

Inbound leads decay fast — the firms that reach a new lead within an hour qualify it far more often than those that wait. An agent account turns that race into an automated loop. This guide builds a lead agent on a dedicated inbox: it reads each inbound message, lets a model qualify it against your criteria, saves the qualified ones to a contacts directory, and routes a notification to the right rep. The agent runs every minute, so a lead that lands at 2am is captured by 2:01.

Written by [Prem Keshari](https://cli.nylas.com/authors/prem-keshari) Senior SRE

Updated June 7, 2026

> **TL;DR:** A lead agent on a dedicated inbox reads inbound mail with `nylas email list --unread --json`, a model qualifies it, qualified leads are saved with `nylas contacts create`, and a rep is notified with `nylas email send` — all on one agent account.

## What is a lead-capture agent?

A lead-capture agent is an autonomous program that turns inbound interest into a qualified, routed contact record. It reads each message arriving at a leads inbox, extracts who the lead is and what they want, scores them against your qualification criteria, stores the good ones, and alerts a salesperson. Built on an agent account, the whole loop runs on one managed identity that owns the leads inbox and the contacts directory.

Speed is the entire point. According to a [Harvard Business Review study](https://hbr.org/2011/03/the-short-life-of-online-sales-leads), firms that contacted an online lead within an hour were close to 7 times likelier to have a meaningful qualifying conversation than those that waited even 60 minutes longer. A human checking a shared inbox can't hit that window overnight or on a weekend; an agent running on a 1-minute cron can.

Lead-capture flow: read the lead, qualify it, save it to contacts, and notify salesRead leademail listQualifymodel scoreSavecontacts createNotify salesemail send

## Why run lead capture on an agent account?

A lead agent should own a dedicated inbox, not poll a person's mailbox. On an agent account, the leads address is the agent's own, every captured contact lands in the agent's contacts directory, and the qualification loop runs without a human session in the path. Pause or retire the whole pipeline by suspending one grant.

It also keeps the agent honest. A leads inbox is fed by strangers, so the messages are untrusted input. Because the agent account's outbound rules live on the workspace, a lead containing a prompt-injection payload can't talk the agent into emailing arbitrary recipients — containment lives outside the agent's decision loop. The agent notifies your reps and no one else.

## How do I set up the lead inbox?

Create the leads identity with one command. The [`nylas agent account create`](https://cli.nylas.com/docs/commands/agent-account-create) call returns a grant in under 2 seconds, with the inbox and the contacts directory both live. Point your web form's notification or your "contact us" address at it:

```bash
nylas agent account create leads@yourapp.nylas.email
export NYLAS_GRANT_ID="$(nylas agent account get leads@yourapp.nylas.email --quiet)"
```

Any channel that can send email can now feed the agent: a form-to-email integration, a forwarded address, or a direct inbound message. The agent doesn't care about the source — it processes whatever lands in the inbox, which keeps the capture layer decoupled from your website stack.

## How does the agent read and parse new leads?

The agent polls for new mail with `nylas email list --unread --json`. The structured output carries the sender, subject, and snippet the model needs to extract the lead's details — name, company, and what they're asking for. Projecting only those fields with [jq](https://jqlang.github.io/jq/manual/) keeps the model's prompt small and its job narrow:

```bash
nylas email list --unread --json \
  | jq '.[] | {id, from: .from[0].email, subject, snippet}'
```

The model's task here is extraction: turn free-text prose into a structured lead — first name, last name, company, and a one-line summary of intent. Keep the extraction and the qualification as separate model calls, or one structured output, so the downstream code receives clean fields rather than parsing prose itself. For the deeper signature-and-header parsing pattern, see [enriching contacts from email](https://cli.nylas.com/guides/enrich-contacts-from-email).

## How does the agent qualify a lead?

Qualification is a model judgment turned into a deterministic decision. The model scores the lead against your criteria — company size, budget signals, whether it's a real buyer or a vendor pitch — and returns a verdict your code acts on. A simple, auditable contract is a category plus a score: the model returns `qualified`, `nurture`, or `spam`, and the code branches on it.

Keep the threshold in code, not in the prompt. The model is good at the soft judgment — "does this read like a serious buyer?" — and bad at being a consistent gatekeeper. By having the code decide what happens to each category, a borderline lead always gets the same treatment, and you can tune the routing without retraining anything. Use the [human-in-the-loop pattern](https://cli.nylas.com/guides/build-human-in-loop-email-agent) when a person should confirm the high-value ones before outreach.

## How does the agent save the lead and notify sales?

A qualified lead becomes two actions: a contact record and a notification. The `nylas contacts create` command saves the lead to the agent's directory with structured fields, so it's searchable later and ready to sync to a CRM. Then `nylas email send` alerts the right rep:

```bash
# Save the qualified lead to the contacts directory
nylas contacts create \
  --first-name "Jane" \
  --last-name "Doe" \
  --email "jane@prospect.com" \
  --company "Prospect Inc" \
  --notes "Inbound: evaluating for a 50-seat rollout"

# Notify the rep who owns this segment
nylas email send \
  --to ae-west@yourcompany.com \
  --subject "New qualified lead: Jane Doe (Prospect Inc)" \
  --body "Inbound lead evaluating a 50-seat rollout. Saved to contacts. Reply within the hour."
```

Saving to the directory first means the lead exists as a record even if the notification is missed, and a later run can resolve the contact by email instead of re-creating it. The [contacts directory guide](https://cli.nylas.com/guides/agent-account-contacts) covers resolving and deduping these records as the list grows.

## How do I run the capture loop?

The loop is a script a cron job runs every minute — the cadence that beats the lead-decay clock. It reads the first unread lead the CLI returns, qualifies it, acts on the category, and marks the message read so the next run doesn't reprocess it — all under `set -euo pipefail` so a failure surfaces instead of silently dropping a lead. The `qualify_lead` function is the stand-in for your own model call; it returns JSON with a category and the extracted fields:

```bash
#!/usr/bin/env bash
set -euo pipefail

lead=$(nylas email list --unread --json | jq -r '.[0] // empty')
[ -z "$lead" ] && exit 0
id=$(echo "$lead" | jq -re '.id')
from=$(echo "$lead" | jq -re '.from[0].email')
body=$(echo "$lead" | jq -r '.snippet')

# qualify_lead is your LLM call; returns JSON: {category, first_name, summary}
verdict=$(qualify_lead "$body")
category=$(echo "$verdict" | jq -r '.category // "spam"')
name=$(echo "$verdict" | jq -r '.first_name // "lead"')
summary=$(echo "$verdict" | jq -r '.summary // "inbound lead"')

case "$category" in
  qualified)
    nylas contacts create --first-name "$name" --email "$from" --notes "$summary"
    nylas email send --to ae-west@yourcompany.com \
      --subject "New qualified lead: $from" --body "$summary" ;;
  nurture)
    nylas contacts create --first-name "$name" --email "$from" --notes "Nurture: $summary" ;;
  spam)
    echo "spam from $from — skipping" >&2 ;;
  *)
    echo "unexpected category '$category' from $from — treating as spam" >&2 ;;
esac

# Mark the lead handled so the next cron run skips it
nylas email mark read "$id"
```

The `case` has an explicit `spam` arm and an unknown-category arm that logs to stderr, so model drift is visible rather than silently dropped. The default-value guards on each `jq` read keep a missing field from aborting the run, and `nylas email mark read` at the end stops the next run from reprocessing the same lead. Add audit logging around each branch — the [audit guide](https://cli.nylas.com/guides/audit-ai-agent-activity) covers structured logging for agent decisions.

## How do I keep the pipeline clean and safe?

Two hygiene jobs keep a lead pipeline trustworthy: dedup and containment. The same lead often arrives twice — a form submission and a follow-up email — so resolve by email before creating, and periodically scan the directory for duplicates. On the safety side, the leads inbox is untrusted input, so an outbound rule confines where the agent can send. Block any recipient domain a malicious lead might try to redirect a notification toward:

```bash
# Notifications only go to your team — block a flagged exfil domain
nylas agent rule create \
  --name "Block flagged lead-agent outbound" \
  --trigger outbound \
  --condition recipient.domain,is,exfil.example \
  --action block
```

Because the rule lives on the workspace, the agent can't prompt its way past it. Pair it with a policy send cap so a loop bug can't flood your reps, and reconcile notification recipients against your own team list in code. The [rules and policies guide](https://cli.nylas.com/guides/agent-rules-and-policies) documents every trigger and limit, and [Stop Your AI Agent From Going Rogue](https://cli.nylas.com/guides/stop-ai-agent-going-rogue) covers the full containment pattern.

## Next steps

- [Give Your AI Agent a Contacts Directory](https://cli.nylas.com/guides/agent-account-contacts) — resolve and dedupe the lead records this agent creates
- [Getting Started with Agent Accounts](https://cli.nylas.com/guides/getting-started-agent-accounts) — the architecture behind the leads inbox and its workspace
- [Build a Human-in-the-Loop Email Agent](https://cli.nylas.com/guides/build-human-in-loop-email-agent) — require a person to confirm high-value leads before outreach
- [Enrich Contacts from Email](https://cli.nylas.com/guides/enrich-contacts-from-email) — pull richer fields from signatures and headers as you save leads
- [Agent Rules and Policies](https://cli.nylas.com/guides/agent-rules-and-policies) — the outbound guardrails and send caps that contain the agent
- [Full command reference](https://cli.nylas.com/docs/commands) — every `nylas email`, `nylas contacts`, and `nylas agent` flag
- [Nylas v3 API documentation](https://developer.nylas.com/) — the API surface behind these commands
