If you run many AI agents that send email, putting them all on one domain means one badly behaved agent can hurt delivery for the rest. This guide shows how to set up your own domains on PostNuvia, when to use subdomains versus separate domains, and how to run thousands of agent inboxes without their reputations bleeding into each other.
Every email you send is judged partly by the domain it comes from. Gmail and Outlook keep a reputation score for each sending domain, and when mail from that domain gets marked as spam, everything else sent from it starts landing in spam too.
With one agent, that is easy to manage. With hundreds, it is not. A sales agent sending cold emails and a billing agent sending receipts should not share a reputation, and if you sell agents to your own customers, one customer's mistakes should not sink another's.
The answer is to give your agents domains you own, and to decide on purpose which agents share a domain and which get their own. Here is how to do that on PostNuvia, the email API that gives each agent its own inbox, from adding your first domain to running thousands of inboxes across many customers.
Why domains matter for agent fleets
Reputation is attached to the domain, not to the individual address. Mailbox providers watch how recipients treat mail from a domain over time, and the more of it that gets deleted unread or marked as spam, the less of it reaches an inbox at all.
That is why the shared @postnuvia.com domain every new inbox starts on is fine for a prototype and wrong for production. Every agent on a shared domain inherits whatever the noisiest agent on it did yesterday, and you have no way to separate them.
Once you own the domain, you decide where the boundaries are. You can put the whole fleet on one domain, split it by what the agents do, or give every customer their own. The rest of this guide is about making that choice deliberately.
Adding and verifying a domain
You buy the domain at your registrar, then tell PostNuvia about it. PostNuvia gives you back the DNS records to publish, and checks them until they resolve.
Four record types do the work, and each one answers a different question a receiving server asks. SPF says which servers are allowed to send mail for your domain. DKIM is the signature that proves an email really came from your domain and was not altered on the way. DMARC tells receivers what to do when a message fails those two checks, and where to send reports about it. MX says where mail addressed to your domain should be delivered, which is what makes replies possible.
There is a fifth thing worth knowing about, a wildcard MX. That is an MX record that covers every subdomain at once, so anything.example.com routes without you publishing a record for each one.
from postnuvia import PostNuvia
client = PostNuvia(api_key="YOUR_API_KEY")
domain = client.domains.create(
domain="agents.example.com",
subdomains_enabled=True,
)
print(domain.status)
print(len(domain.records))
# output: NOT_STARTED or PENDING, then N DNS records including wildcard MX
client.domains.verify(domain_id=domain.domain_id)
zone = client.domains.get_zone_file(domain_id=domain.domain_id)
# import zone into Cloudflare, Route 53, or PorkbunPublish those records at your DNS host. If it accepts a BIND zone file, importing the one PostNuvia generates is faster than typing each record by hand. On Route 53 there is one trap worth knowing: a TXT value over 255 characters has to be split into adjacent quoted strings with no space between them, or DKIM will silently fail to verify.
DNS takes anywhere from a few minutes to two days to propagate, so the domain moves through a series of states rather than flipping straight to ready. Poll the domain and watch each record, which reports as missing, invalid or valid on its own. Do not create production inboxes until the whole domain reads as verified, because mail sent before then can bounce.
Subdomains or separate domains
This is the decision that matters, and it is worth being deliberate about it.
Turning on subdomains gives you address space. You publish one wildcard MX on the parent domain, and after that any subdomain works without registering it separately. That is cheap to operate: one domain slot, one set of DNS records, unlimited addresses underneath it.
What it does not give you is separation. Every inbox on every subdomain signs with the parent domain's DKIM key, so they all share one reputation. If an agent on one subdomain gets a wave of spam complaints, every other subdomain feels it.
Registering each subdomain as its own domain costs more and buys you exactly that separation. Each one gets its own DKIM signature and its own reputation, so a cold outreach sequence that goes badly on one does not touch the others.
The rule of thumb: share a domain when the agents on it carry the same risk, and split when they do not. Receipts and cold outreach are not the same risk. If you are sending enough volume that one domain would get throttled, keep a pool of verified domains and assign the next one as you create each inbox.
Turning subdomains on for a domain you already verified adds the wildcard MX and puts the domain back into a pending state until that record resolves. Mail from existing inboxes keeps flowing while that happens.
Creating inboxes at scale
Once a domain is verified, creating inboxes on it is a loop. Each call takes a username and the domain, and returns an inbox whose address is the two joined together.
Pass a client id you generate yourself. If the call times out and you retry it, that id is what stops you creating the same inbox twice.
from postnuvia import PostNuvia
client = PostNuvia(api_key="YOUR_API_KEY")
usernames = [f"agent-{i:04d}" for i in range(1, 101)]
inboxes = []
for name in usernames:
inbox = client.inboxes.create(
username=name,
domain="agents.example.com",
client_id=f"fleet-{name}-v1",
)
inboxes.append(inbox.inbox_id)
print(len(inboxes))
# output: 100 inbox ids such as agent-0001@agents.example.comFor a wildcard subdomain, pass the subdomain itself as the domain. Asking for an inbox on a subdomain when subdomains are switched off returns a 422, which is usually the first sign that the wildcard MX never verified.
Inbox count is a separate ceiling from domain count, and at fleet scale it is normally the one you hit first. If you want the wider sizing picture, we wrote about running thousands of agent inboxes separately.
Giving each customer their own space with Pods
If you sell agents to your own customers, you need a boundary between them. A Pod is that boundary. It holds one customer's inboxes, domains and API keys, and reads and sends cannot cross from one Pod into another.
Be precise about what that buys you, because it is easy to over-read. A Pod separates data and credentials: one customer's agent cannot read another customer's mail, and a leaked key stays inside the tenant it belongs to. A Pod does not separate sending reputation. If two customers send from the same domain, they share its reputation no matter which Pods they sit in.
Reputation separation comes from the domain, not from the Pod. Give each customer, or each risk profile, its own domain inside its Pod, and their deliverability stops being each other's problem.
from postnuvia import PostNuvia
client = PostNuvia(api_key="YOUR_API_KEY")
pod = client.pods.create(client_id="tenant-acme-v1")
domain = client.pods.domains.create(
pod.pod_id,
domain="mail.acme.example",
)
# publish domain.records, then:
client.pods.domains.verify(pod.pod_id, domain_id=domain.domain_id)
inbox = client.pods.inboxes.create(
pod.pod_id,
username="support",
domain="mail.acme.example",
)
key = client.pods.api_keys.create(pod.pod_id, name="acme-agent")
print(inbox.inbox_id)
# output: support@mail.acme.example inside the Acme Pod onlyIn practice most teams end up with a mix. High-risk or high-volume customers get a registered domain of their own. Everyone else shares subdomain space on a parent you have already verified, which is fine as long as you have decided that sharing reputation between them is acceptable. There is more on the isolation model in our write-up on Pods and multi-tenant email.
What it costs
Custom domains start on the Developer plan, which includes 10. Startup includes 150. On either plan you can add one more for $2 a month, and annual billing takes 20 percent off both the plan and the add-ons. The free tier has no custom domains, so domain work starts at Developer.
Inboxes are counted and billed separately from domains, so price the two independently when you are sizing a fleet. Enterprise removes the inbox ceiling and negotiates the domain count. Our write-up on pay-as-you-go billing has the full breakdown if you want to model it out.
What PostNuvia does not do
We do not sell you domains. You buy them at your registrar and publish the DNS yourself; PostNuvia generates the records and verifies them.
We also do not run a warmup network. Gradually ramping a fresh mailbox to build its reputation is its own product, and if you are running cold outreach sequences, a service like Mailforge is built for that. PostNuvia is for agents that hold real conversations on addresses you own.
Dedicated IPs are Enterprise only, so everything below that shares sending IPs. Domains that PostNuvia configures default to a strict DMARC policy that rejects mail failing authentication, which is the safe default; you can relax it in your own DNS if you understand what you are giving up.
PostNuvia is the first email provider built for AI agents. Create an inbox in one API call, send and receive email, no OAuth and no domain verification. Free tier, no credit card required.


