TL;DR: A shared or borrowed email address breaks agent workflows at the DNS, threading, and deliverability layers. Each agent needs its own routable inbox so replies land correctly, sender reputation stays isolated, and inbound webhooks fire with full context.

An agent email address isn't cosmetic — it's load-bearing infrastructure. Without a stable, dedicated address per agent, you lose reply routing, sender reputation isolation, thread continuity, and the ability to receive inbound payloads the agent can actually act on. Every one of those failures is silent until it isn't.
This post covers the exact mechanisms that make a dedicated inbox necessary: DNS identity, SMTP envelope routing, Message-ID threading, reputation blast radius, and inbound webhook delivery.
What "dedicated" actually means at the protocol level
At the protocol layer, a dedicated agent email address means one thing: the MAIL FROM envelope, the From: header, and the inbound MX target all resolve to a single logical identity that no other process shares.
Three concrete properties follow from that:
- SPF alignment — your SPF
TXTrecord on the sending domain authorizes exactly the IP(s) that agent uses. If a second agent shares the same@address, any SPF failure from that agent is your agent's failure too. - DKIM signing — the
d=tag in the DKIM signature ties to your domain. The selector (s=) scopes the public key. Sharing a domain across agents is fine; sharing a sending identity means one misconfigured agent can burn the domain's DKIM reputation. - DMARC alignment — DMARC checks that the RFC5322
From:domain aligns with either the SPF envelope domain or the DKIMd=. A shared address where two agents send with different headers can produce inconsistent DMARC results that receivers penalize.
None of this is theoretical. According to Google's Postmaster Tools documentation, domains with persistent DMARC failures get routed to spam regardless of content — and that penalty applies to all mail from the domain, not just the offending messages.
The reply routing problem
Reply routing is where shared addresses break hardest. Consider a simple pattern: your agent sends an email and needs to process the reply.
From: agent@yourapp.com
Reply-To: agent+thread_abc123@yourapp.com
Message-ID: <abc123.1728000000@yourapp.com>
The Reply-To carries a tagged address that encodes the conversation context. When the recipient hits reply, their client sends to agent+thread_abc123@yourapp.com. Your inbound MX receives it, parses the +tag, looks up thread_abc123, and routes the webhook payload to the right agent instance.
Now put two agents behind the same base address. Agent A generates +thread_abc123. Agent B generates +thread_abc123 for a different conversation — hash collision or sequence reset. The same inbound webhook fires for both, and your routing logic has no way to distinguish them without additional context you may not have.
The fix is an address-per-agent (or at minimum a namespace-per-agent in the local part). crm-agent@yourapp.com and support-agent@yourapp.com have completely separate tag namespaces. No collision is possible.
Message-ID threading and conversation state
Email threading in clients like Gmail and Outlook depends on two headers: Message-ID and In-Reply-To (plus References for the full chain).
Message-ID: <crm-001.1728000000.abc@yourapp.com>
# Human reply
In-Reply-To: <crm-001.1728000000.abc@yourapp.com>
References: <crm-001.1728000000.abc@yourapp.com>
# Agent's follow-up reply
In-Reply-To: <human-reply-msgid@gmail.com>
References: <crm-001.1728000000.abc@yourapp.com> <human-reply-msgid@gmail.com>
If your agent can't both send with a stable Message-ID and receive the reply that references it, the thread breaks in the recipient's client. They see a new conversation instead of a continuation. Response rates drop — and more importantly, your agent can't correlate the inbound reply to the original send event without doing expensive fuzzy matching on subject lines.
A routable inbox solves this cleanly. The agent holds the Message-ID it sent. The inbound webhook delivers the reply with In-Reply-To intact. Your code does a direct key lookup.
from mailsai import agent
# Send and store the message ID
result = agent("crm-agent").send(
to="prospect@example.com",
subject="Following up on your request",
html="<p>Hi, just checking in...</p>"
)
conversation_store[result.message_id] = {"thread": "deal_456", "stage": "follow_up"}
# Inbound webhook handler (e.g., FastAPI)
@app.post("/inbound")
async def handle_reply(payload: dict):
in_reply_to = payload["headers"].get("in-reply-to")
context = conversation_store.get(in_reply_to)
if context:
# Route to the right agent action
await process_reply(context, payload)
Without a dedicated inbox, result.message_id has nowhere to receive the inbound event. The conversation is one-way.
Sender reputation isolation
Deliverability reputation accretes at the IP and domain level. Share a sending identity across multiple agents — or between agents and transactional mail — and a reputation problem in one spreads to all.
Consider the blast radius:
| Sharing model | Reputation blast radius |
|---|---|
| All agents, one shared address | Full domain reputation shared; one bad actor affects all |
| Agents on separate subdomains | Subdomain reputation isolated; root domain partially shielded |
| Agents on separate addresses, same domain | DKIM d= shared, but From: address reputation scoped |
| Dedicated IP per high-volume agent | IP reputation fully isolated; most protective for bulk senders |
Google's Gmail team has published guidance that bulk senders (≥5,000 messages/day to Gmail) must authenticate with SPF and DKIM, and must have a DMARC policy. If you're running multiple agents, each sending hundreds of messages, the cumulative volume may cross that threshold even if no single agent does — and authentication failures from a shared identity compound.
For agents sending at scale, a dedicated IP means your reputation curve is entirely your own. A single misconfigured campaign on a shared IP can shift your inbox placement from 95% to 60% overnight with no warning.
Inbound parsing requires a real MX record
Receiving email isn't a nice-to-have for agents — it's the mechanism that closes the loop. An agent that can only send is half an agent. But receiving requires an actual MX record pointing to infrastructure that can parse, classify, and deliver the payload.
The DNS chain looks like this:
agent.yourapp.com. MX 10 inbound.mail-provider.com.
When a sender's MTA does an MX lookup for agent@agent.yourapp.com, it gets inbound.mail-provider.com, connects on port 25, and delivers the message. The inbound processor then fires a webhook to your application.
sequenceDiagram
participant Sender as Sender MTA
participant DNS as DNS Resolver
participant MX as Inbound MX
participant Hook as Webhook Endpoint
participant Agent as Agent Process
Sender->>DNS: MX lookup for agent.yourapp.com
DNS-->>Sender: inbound.mail-provider.com
Sender->>MX: SMTP delivery
MX->>Hook: POST parsed payload
Hook->>Agent: route by Message-ID or tag
Without a real MX record, replies to your agent's address bounce with a 550 "No such user" or "Domain not found" error. The sender sees a failure; your agent sees nothing. Inbound email parsing infrastructure handles this MX layer, parses the raw MIME payload, and delivers structured JSON to your webhook — headers, body, attachments, and metadata all separated.
Platforms built specifically for agent email infrastructure handle the full stack: MX hosting, MIME parsing, attachment extraction, and intent classification, without requiring you to run a mail server.
Naming conventions that scale
Agent address naming matters operationally. Three patterns work well:
- Role-based:
billing-agent@yourapp.com,support-agent@yourapp.com. Clear intent, easy to read in logs. Works at small scale. - Instance-based:
agent-7f3a@yourapp.comwhere the suffix is a short hash of the agent's ID. Scales to many agent instances but harder to debug from an inbox view. - Subdomain-per-agent:
agent@crm.yourapp.com,agent@billing.yourapp.com. Isolates MX records and reputation at the subdomain level. Most flexible for teams deploying multiple agent types.
Whichever you choose, bake the agent identity into the address early. Changing an agent's From: address mid-deployment resets its sender reputation to zero and breaks any In-Reply-To chains in flight.
Authentication setup checklist
For every new agent address you provision:
- SPF: Add the sending IP range to your domain's SPF
TXTrecord. Use~all(softfail) during ramp-up, then–all(hardfail) once volume is stable. - DKIM: Generate a 2048-bit RSA key pair. Publish the public key as a
TXTrecord at<selector>._domainkey.<domain>. Rotate selectors every 6-12 months. - DMARC: Start with
p=none; rua=mailto:dmarc-reports@yourapp.comto collect aggregate reports. Move top=quarantinethenp=rejectas you confirm alignment. - MX record: Point the agent's subdomain or domain to your inbound MX provider.
- BIMI (optional): Once DMARC is at
p=quarantineor stricter, publish adefault._bimi.<domain>record with your logo URI for brand display in supporting clients.
Frequently Asked Questions
Can an agent use a shared company email address like info@company.com?
Technically yes, but practically no. A shared address means no isolated reputation, no reliable reply routing via +tags, and any inbound replies mix with human mail. Your agent either needs access to the full inbox (a security and noise problem) or misses replies entirely. Use a dedicated address.
Does each agent need its own domain, or can they share one?
Sharing a domain is fine — billing-agent@yourapp.com and support-agent@yourapp.com can coexist on the same domain with the same SPF/DKIM/DMARC setup. What they need is a distinct local part and, ideally, distinct Reply-To tag namespaces so inbound routing doesn't collide.
What happens to deliverability if I spin up 50 agents overnight?
Sudden volume spikes from new sending identities trigger spam filters. ISPs use engagement signals (opens, replies, no spam complaints) to build trust. Ramp new agent addresses: start at ~50 messages/day, double every 3-4 days, and monitor bounce rates. Keep hard bounces below 0.5% and spam complaint rates below 0.1% (Google's published threshold for Gmail delivery).
Do I need a dedicated IP for each agent, or is a shared IP pool acceptable?
Shared IP pools work for agents sending under ~5,000 messages/day. Above that, or if your use case involves cold outreach (higher complaint risk), a dedicated IP gives you full control over your IP's reputation history. The tradeoff: dedicated IPs require their own warm-up period.
How does inbound parsing work if my agent address is on a subdomain?
You publish an MX record for the subdomain: agent.yourapp.com. MX 10 inbound.provider.com. Mail sent to any address at @agent.yourapp.com routes to that MX. The inbound processor receives it, parses the MIME payload, and fires a webhook. Your application doesn't need to run any SMTP server — the MX provider handles all of that. See inbound email parsing for the webhook payload structure.
What's the minimum DNS TTL I should set for agent MX records?
Set MX TTLs to 3600 seconds (1 hour) during initial setup so you can correct mistakes quickly. Once stable, 86400 (24 hours) is fine. Lower TTLs increase DNS query load and provide little practical benefit for MX records, which change rarely.