Skip to content
Engineering

Create Email With Your Own Domain: Fast Setup Guide

| | 9 min read
Create Email With Your Own Domain: Fast Setup Guide
Create Email With Your Own Domain: Fast Setup Guide

Getting an email address on your own domain is easy. Getting one that is reliable for automation and AI agents (and does not involve logging into a human mailbox) is where teams usually lose time.

This fast setup guide shows a pragmatic path to create email with your own domain for inbound flows like signup verification, OTPs, password resets, and integration testing, with a minimal, automation-friendly architecture.

What you are actually setting up (inbound email, not a “mailbox account”)

When people say “create an email with your own domain,” they often mean one of two things:

  • Human mailbox accounts (Google Workspace, Microsoft 365, IMAP, login, folders)
  • Programmable inbound email (receive emails as machine-readable events, parse them as JSON, trigger workflows)

For LLM agents, CI, and QA automation, the second is usually the goal: you want an address on your domain that can be created on demand, isolated per run, and consumed deterministically.

A minimal inbound architecture looks like this:

  1. DNS routes mail for a domain or subdomain using MX records.
  2. An inbound provider receives SMTP and normalizes the email.
  3. Your code consumes the message via webhooks (push) and/or polling (pull).

A simple flow diagram showing DNS MX records for a subdomain routing inbound email to an email ingestion API provider, which then delivers a normalized JSON message to the customer system via webhook, with an optional polling fallback path.

If you want the exact integration contract for Mailhook (endpoints, payload shape, signature verification details), use the canonical reference: Mailhook llms.txt.

Fast decision: domain vs subdomain (pick subdomain by default)

For automation, a dedicated subdomain keeps your risk and blast radius small. It also lets you keep your human email (like @company.com) untouched.

Examples:

Use case Recommended inbound domain Why it works well
CI / automated QA ci-mail.example.com Easy to rotate and isolate, safe to delete later
Staging staging-mail.example.com Separates deliverability and routing from production
Agent workflows agent-mail.example.com Keeps “tooling email” away from human mail
Production verification (controlled) verify.example.com Lets you apply allowlists and monitoring to one zone

If you are unsure, start with one subdomain (for example ci-mail.example.com) and expand later.

Step 1: Choose how you will “receive” email in code

You have three realistic choices:

Approach Setup speed Reliability for CI/agents Operational cost Best for
Self-host inbound SMTP + parser Slow Medium (often brittle) High Specialized pipelines, deep control
Traditional mailbox provider Medium Low in parallel CI Medium Humans, not automation
Inbound email API (JSON + webhooks) Fast High Low to Medium Automation, agents, verification flows

If your goal is automation, inbound email API is typically the fastest route because you avoid running SMTP infrastructure and MIME parsing.

Mailhook is built specifically for this automation-first model (disposable inbox creation via API, emails as structured JSON, webhook notifications, polling API fallback, signed payloads, batch processing, shared domains and custom domain support). See Mailhook for the product overview.

Step 2: Decide your addressing scheme (how you generate recipients)

After MX routes mail to your inbound provider, you still need a consistent strategy for generating unique recipient addresses.

You will usually pick one of these patterns:

Pattern Example recipient State required Scales in parallel CI Notes
Encoded local-part [email protected] No Yes Great for determinism and correlation
Alias table [email protected] Yes Medium Needs lifecycle/cleanup of aliases
Catch-all + tag [email protected] Depends Medium Some senders strip tags or normalize addresses

For LLM agents and CI runs, encoded local-parts are usually the simplest, because you can generate a correlation token without coordinating shared state.

Design tip: keep tokens URL-safe and email-safe (letters, digits, a few separators), and treat the whole email address as an identifier, not a user.

Step 3: Configure DNS MX for your subdomain

MX records tell the world where to deliver email for a domain. This is the point where “I created an email address string” becomes “mail is actually routable.”

High-level checklist:

  • Create the subdomain you picked (for example ci-mail.example.com).
  • Add the MX records your inbound provider requires.
  • Wait for DNS propagation.

Most DNS providers have a UI to add an MX record. If you prefer to verify from the command line, you can use dig:

# Replace with your subdomain
DIG_DOMAIN="ci-mail.example.com"

dig MX "$DIG_DOMAIN" +short

What you are looking for is that the MX answers match what your provider expects.

Two common time sinks:

  • Editing the wrong zone (editing example.com when you meant ci-mail.example.com, or vice versa)
  • Assuming it is instant (DNS can take minutes to hours depending on TTL and propagation)

For an accessible MX primer, Cloudflare’s overview is a solid reference: MX records explained.

Step 4: Connect your inbound provider and run a one-email smoke test

Once MX is correct, do a single end-to-end test before you automate anything:

  • Generate a unique recipient on your subdomain.
  • Send one email to it.
  • Confirm you can retrieve the message in code.

If you are using Mailhook with a custom domain, rely on the canonical docs for the exact steps, payload fields, and signature verification requirements: Mailhook llms.txt.

What “good” looks like for automation

A good provider workflow for tests and agents usually includes:

  • Create a disposable inbox via API
  • Receive emails as structured JSON
  • Get real-time delivery via webhook
  • Keep polling as a fallback for reliability
  • Verify authenticity with signed payloads

Those capabilities map directly to Mailhook’s feature set (disposable inboxes, JSON output, webhook notifications, polling API, signed payloads, batch processing, shared domains, custom domain support).

Step 5: Implement the minimal “inbox tool” your agent or test harness needs

Whether you are building an LLM tool or a QA helper library, keep the interface tiny and deterministic. A practical contract is:

  • createInbox({ domain }) -> { email, inbox_id, expires_at }
  • waitForEmail({ inbox_id, matcher, deadline }) -> { message_json }
  • extractArtifact({ message_json }) -> { otp | verification_url }
  • expireInbox({ inbox_id })

You do not need to expose full HTML to the agent. In fact, you usually should not.

Here is provider-agnostic pseudocode that shows the shape without inventing any Mailhook endpoints:

// Pseudocode: consult your provider docs for exact endpoints and fields.

const inbox = await createInbox({ domain: "ci-mail.example.com", ttlSeconds: 900 })
// inbox.email might look like: "[email protected]"

await triggerSignup({ email: inbox.email })

const message = await waitForEmail({
  inboxId: inbox.inbox_id,
  deadlineMs: 60_000,
  match: {
    subjectIncludes: "Verify your email",
    fromDomain: "your-app.example",
  }
})

const artifact = extractVerificationArtifact(message)
await completeVerification(artifact)

await expireInbox({ inboxId: inbox.inbox_id })

Why this is agent-friendly

  • Isolation: inbox-per-run (or inbox-per-attempt) prevents collisions.
  • Determinism: explicit deadline beats hard sleeps.
  • Safety: the agent sees only the minimum artifact it needs.

Step 6: Use webhooks first, keep polling as a safety net

Webhooks are the fastest way to make your tests and agents responsive, but polling is still valuable for resilience.

A reliable hybrid posture:

  • Webhook handler writes the message into your datastore or queue.
  • If the webhook does not arrive by a deadline, your harness polls the inbox.

Webhook security essentials (do these even in test environments)

If you consume inbound email as JSON, your webhook endpoint becomes an attack surface. Treat it like any other public API.

At minimum:

  • Verify signed payloads using the provider’s documented algorithm.
  • Verify the signature over the raw request body (before parsing JSON).
  • Add replay protection, for example rejecting repeated delivery IDs.
  • Fail closed, if verification fails, do not process.

Mailhook supports signed payloads, and the exact verification details should come from the canonical integration reference: Mailhook llms.txt.

Step 7: Avoid the top 5 “why didn’t my email arrive?” problems

These are the issues that most often cause delays during a “fast setup.”

1) Confusing envelope recipient with the To: header

SMTP routing is based on the envelope recipient (RCPT TO), which may not match the To: header you see in the email body. If your system relies on the header only, you will misroute forwarded or BCC scenarios.

If you want the standards context, RFC 5321 defines the SMTP transaction semantics: RFC 5321.

2) MX added, but to the wrong host name

A classic mistake is adding MX for example.com when you meant ci-mail.example.com, or vice versa.

3) DNS propagation not complete

Your local resolver might show the new MX, but other resolvers still have the old value cached.

4) Catch-all collisions

If you use a catch-all domain without a strong correlation token, parallel tests can read each other’s messages.

5) Over-parsing HTML

For automation, prefer stable, minimal extraction from text content and structured fields. HTML is a rendering format, it is not a contract.

Step 8: Add two guardrails that save hours later (retention and logging)

Even if your goal is “fast,” add these two practices early:

Retention and cleanup

  • Use short TTLs for disposable inboxes.
  • Expire inboxes when you are done.
  • Keep only what you need for debugging (often the normalized JSON and a message ID).

Mailhook supports disposable inbox lifecycle patterns and batch processing, which helps when you create many inboxes for CI and agent workloads.

Log IDs, not entire emails

For debuggability without leaking secrets:

  • Log inbox_id, message IDs, timestamps, and matcher decisions.
  • Avoid logging full bodies unless you are in a controlled, redacted environment.

Putting it together with Mailhook (quick start mindset)

If you want to move fast without running SMTP infrastructure, Mailhook is designed for the exact workflows this guide targets:

  • Create disposable inboxes via API
  • Receive email as structured JSON
  • Get webhook notifications in real time
  • Use polling as a fallback
  • Verify signed payloads
  • Support shared domains for instant start and custom domains when you need allowlisting or brand control

To implement against the real contract (instead of guessing), start here: Mailhook llms.txt. Then, when you are ready to try it, go to Mailhook (no credit card required) and wire your first custom-domain inbox end to end.

Related Articles