Inferensys

Prompt

Email Address Cleaning and Validation Prompt

A practical prompt playbook for using Email Address Cleaning and Validation Prompt in production AI workflows.
Developer doing prompt engineering on laptop, prompt variations visible on screen, casual coding session.
PROMPT PLAYBOOK

When to Use This Prompt

Understand the job this prompt performs, the ideal user, and the boundaries of its responsibility before integrating it into a production pipeline.

This prompt is designed for CRM and marketing operations engineers who need a deterministic, auditable normalization step for raw email address strings before they enter a system of record. The primary job-to-be-done is to transform free-text input from signup forms, CSV imports, or API payloads into a structured object that downstream systems can trust. It handles whitespace trimming, domain lowercasing, RFC 5322 format validation, and classification of disposable or role-based addresses. The output is not just a cleaned string; it is a decision record that separates valid, routable emails from invalid ones, each with an explicit rejection reason. This is a classification and normalization step, not a verification step—it prepares data for SMTP checks or real-time mailbox validation but does not replace them.

The ideal user is an engineer building an ingestion pipeline who needs to reduce bounce rates, prevent disposable signups, and maintain a clean CRM. Required context includes the raw email string and, optionally, a list of known disposable domains or role-based prefixes to flag. The prompt is most effective when wired into a pre-ingestion stage where invalid records are routed to a quarantine table or a human review queue rather than silently dropped. It is not suitable for real-time email verification (it does not ping mail servers), for detecting catch-all domains, or for assessing email reputation. Use it when you need structured, explainable decisions at ingestion time, not when you need to confirm mailbox existence.

Avoid using this prompt as a standalone guard against all forms of email abuse. It will not catch typos that result in valid but incorrect domains, nor will it detect temporary email addresses that are not in your disposable domain list. Always pair it with a downstream verification service for high-assurance workflows. If your pipeline processes PII, ensure the prompt's input and output are handled in compliance with your data governance policies. The next step after understanding this boundary is to copy the prompt template, adapt the placeholder lists to your domain, and integrate it with a validation harness that logs every rejection reason for auditability.

PRACTICAL GUARDRAILS

Use Case Fit

Where this email cleaning and validation prompt works well, where it breaks down, and the operational preconditions for safe use.

01

Good Fit: CRM and Marketing Ingest Pipelines

Use when: you are processing batch or streaming email records before they land in a marketing automation platform, CRM, or customer data platform. Guardrail: Run the prompt as a pre-ingestion transform with a strict output schema so invalid records are routed to a quarantine table, not silently dropped.

02

Good Fit: Signup Form and Lead Capture Normalization

Use when: you need to normalize user-entered emails at the point of capture to prevent duplicate accounts and reduce bounce rates. Guardrail: Pair the prompt with a real-time validation endpoint that returns structured rejection reasons the UI can display to the user before submission.

03

Bad Fit: Real-Time Email Verification (MX/SMTP)

Avoid when: you need to confirm an email address actually exists via SMTP handshake or MX record lookup. This prompt validates format and flags disposable domains but does not perform network-level verification. Guardrail: Use a dedicated email verification API for existence checks and treat this prompt as a pre-filter to reduce costs.

04

Bad Fit: Unstructured Free-Text with Embedded Emails

Avoid when: the input is a long email body, chat transcript, or document where email addresses must first be extracted from surrounding text. This prompt expects a single email string as input. Guardrail: Chain this prompt after an extraction prompt that isolates candidate email addresses from unstructured text with span-level source attribution.

05

Required Inputs: Explicit Disposable Domain List

Risk: The model's training data may have an outdated or incomplete list of disposable email domains, leading to false negatives. Guardrail: Provide an explicit, maintainable list of disposable domains as part of the prompt context or as a tool the model can query. Update this list outside the prompt on a regular cadence.

06

Operational Risk: Silent Normalization Drift

Risk: The prompt may change its normalization behavior (e.g., lowercasing rules, Unicode normalization form) across model versions without warning, causing downstream key mismatches. Guardrail: Pin the normalization rules explicitly in the prompt (e.g., 'apply NFC Unicode normalization, then lowercase the domain using ASCII rules') and add regression tests that assert exact output strings for known tricky inputs.

PROMPT PLAYBOOK

Copy-Ready Prompt Template

A production-ready system prompt for cleaning and validating email addresses, ready to paste into your AI harness with your specific inputs and constraints.

This prompt template is designed to be placed directly into your system instructions for an LLM tasked with email normalization. It accepts a raw email string and a set of configuration parameters, then returns a structured JSON object containing the cleaned address, its validity status, and detailed rejection reasons when applicable. The template uses square-bracket placeholders for all variable inputs, ensuring you can adapt it to different risk tolerances, downstream system requirements, and operational contexts without modifying the core logic.

text
You are an email validation and normalization engine. Your task is to process a single raw email address and return a structured JSON object.

## Input
- Raw Email: [RAW_EMAIL_INPUT]

## Configuration
- Disposable Domain List: [DISPOSABLE_DOMAINS]
- Role-Based Prefix List: [ROLE_BASED_PREFIXES]
- Allowed Domains (if domain-restricted): [ALLOWED_DOMAINS]
- Output Schema: [OUTPUT_SCHEMA]

## Processing Rules
1. **Clean**: Trim leading/trailing whitespace. Remove any `mailto:` prefix if present.
2. **Normalize**: Convert the domain part (after the '@') to lowercase. Preserve the case of the local part (before the '@') as-is, per RFC 5321.
3. **Validate Format**: Check the address against RFC 5322 standards. It must have exactly one '@', a non-empty local part, a non-empty domain with at least one dot, and no invalid characters.
4. **Flag Disposable**: If the domain is in the provided [DISPOSABLE_DOMAINS] list, set `is_disposable` to true.
5. **Flag Role-Based**: If the local part matches any prefix in [ROLE_BASED_PREFIXES] (e.g., admin@, info@, support@), set `is_role_based` to true.
6. **Check Domain Restriction**: If [ALLOWED_DOMAINS] is provided and not empty, the domain must be present in that list. If not, flag as `domain_not_allowed`.

## Output Instructions
Return ONLY a valid JSON object conforming to the [OUTPUT_SCHEMA] provided. Do not include any text outside the JSON object. If the input is invalid, the `normalized_email` field should be null and the `rejection_reasons` array must contain specific, non-generic reasons.

To adapt this template, replace the square-bracket placeholders with your specific values. For [DISPOSABLE_DOMAINS], provide a JSON array of strings like ["mailinator.com", "guerrillamail.com"]. For [ROLE_BASED_PREFIXES], use an array such as ["admin", "info", "sales", "support", "noreply"]. The [OUTPUT_SCHEMA] should be a JSON Schema object defining the exact structure you expect, including fields for normalized_email, is_valid, is_disposable, is_role_based, and rejection_reasons. If you are not enforcing a domain allowlist, set [ALLOWED_DOMAINS] to an empty array []. For high-risk workflows where a bad email could cause a customer-facing error, ensure your application layer validates the JSON output against the schema before ingestion and routes any record with is_valid: false or a non-empty rejection_reasons array to a human review queue.

IMPLEMENTATION TABLE

Prompt Variables

Required and optional inputs for the email cleaning prompt. Each placeholder must be supplied at runtime. Validation notes describe how to check the input before calling the model.

PlaceholderPurposeExampleValidation Notes

[EMAIL_ADDRESS]

Raw email string to clean and validate

Required. Must be a non-empty string. Pre-check for null or whitespace-only input before prompt assembly.

[DISPOSABLE_DOMAIN_LIST]

Known disposable email domains to flag

['mailinator.com', 'guerrillamail.com', '10minutemail.com']

Optional. Must be a JSON array of strings. Validate array structure before injection. If null, the prompt should still flag common patterns.

[ROLE_BASED_PREFIXES]

Role-based local-part prefixes to flag

['admin', 'noreply', 'support', 'info', 'sales']

Optional. Must be a JSON array of lowercase strings. Validate array structure. If null, the prompt should use a reasonable default set.

[BLOCKED_DOMAINS]

Domains to reject outright

['spamdomain.com', 'tempmail.org']

Optional. Must be a JSON array of strings. Validate array structure. If null, the prompt should skip domain blocklist checks.

[OUTPUT_SCHEMA]

Expected JSON structure for the response

{ email: string, is_valid: boolean, ... }

Required. Must be a valid JSON Schema object or a clear structural description. Validate parseability before injection to prevent model format drift.

[STRICT_RFC_CHECK]

Toggle for strict RFC 5322 compliance

Required boolean. Use 'true' for strict validation or 'false' for lenient mode. Validate type before injection to avoid string 'true' misinterpretation.

[LOCALE_HINT]

Locale for domain normalization rules

en-US

Optional string. Use ISO language-region format. If null, the prompt should default to en-US. Validate format to prevent injection of arbitrary strings.

PROMPT PLAYBOOK

Implementation Harness Notes

How to wire the email cleaning prompt into a production application with validation, retries, and routing logic.

This prompt is designed to be a single step in a larger data pipeline, not a standalone chatbot interaction. The implementation harness should treat the LLM call as a deterministic transformation function: structured input in, structured output out. The harness is responsible for enforcing the output schema, handling model failures, and routing records based on the status field. The prompt itself is stateless, so the harness must supply all context—the raw email string and any domain blocklists or configuration—in each request.

Wire the prompt into your application using a model that supports strict JSON mode or structured outputs (e.g., GPT-4o with response_format: { type: 'json_object' } or Claude with tool-use extraction). Before calling the model, pre-process the input by trimming leading/trailing whitespace and rejecting null or empty strings at the application layer to avoid wasting tokens. After receiving the response, validate the JSON against the expected schema: status must be one of valid, invalid, risky, or disposable; normalized_email must be present for valid and risky statuses; rejection_reasons must be a non-empty array for invalid and disposable statuses. If validation fails, retry once with the validation error injected into the prompt as additional context. If the retry also fails, log the raw response and route the record to a manual review queue.

For high-throughput pipelines, implement batching with care. Send records individually or in small batches (5–10) within a single prompt, requesting a JSON array in response. Always include a unique record_id in the input and require it in the output to maintain traceability. Log every normalized result—including the original input, normalized output, model version, and timestamp—to an audit table. This audit trail is critical for debugging normalization drift when model behavior changes. For domains with strict deliverability requirements, add a post-processing step that checks risky emails against your internal suppression lists before routing to downstream systems. Never send disposable or invalid emails to your CRM or marketing automation platform; route them to a quarantine table for periodic review.

IMPLEMENTATION TABLE

Expected Output Contract

Fields, types, and validation rules for the email cleaning and validation prompt output. Use this contract to build a parser, validator, and downstream router that can consume the prompt response without ambiguity.

Field or ElementType or FormatRequiredValidation Rule

original_email

string

Must match the exact [INPUT_EMAIL] string provided to the prompt

cleaned_email

string | null

Must be a trimmed, lowercased RFC 5322 addr-spec or null if validation fails; null only when is_valid is false

is_valid

boolean

Must be true when cleaned_email passes RFC 5322 format check, false otherwise; no null allowed

rejection_reason

string | null

Required when is_valid is false; must be one of the enum values defined in [REJECTION_REASONS] or null when is_valid is true

domain

string | null

Extracted domain portion of cleaned_email, lowercased; null when is_valid is false or email cannot be parsed

is_disposable

boolean

Must be true when domain matches [DISPOSABLE_DOMAIN_LIST], false otherwise; null when domain cannot be extracted

is_role_based

boolean

Must be true when local-part matches role patterns from [ROLE_PATTERN_LIST], false otherwise; null when local-part cannot be extracted

normalization_steps

array of strings

Ordered list of transformations applied; must include at minimum 'trim_whitespace' and 'lowercase_domain'; empty array not allowed

PRACTICAL GUARDRAILS

Common Failure Modes

What breaks first when normalizing email addresses and how to guard against it in production.

01

Over-Aggressive Lowercasing

What to watch: The local part of an email (before the @) is technically case-sensitive per RFC 5321. While most major providers treat it as case-insensitive, blindly lowercasing the entire address can break delivery for strict, legacy, or custom mail servers. Guardrail: Always lowercase the domain part. For the local part, preserve original casing unless a specific domain policy (like Gmail or Microsoft 365) is confirmed. Flag any case mismatch for review rather than silently mutating.

02

Regex-Only Validation Bypass

What to watch: A simple regex check can pass malformed addresses (e.g., double dots, leading hyphens) or reject valid internationalized email addresses with non-ASCII characters. Relying solely on a regex pattern creates a false sense of security. Guardrail: Use the prompt to enforce a multi-step validation: structural check, domain MX record existence hint, and syntax validation against RFC 5321/5322 rules. Route any address that passes regex but fails deeper checks to a manual review queue.

03

Disposable Domain Drift

What to watch: A hardcoded list of disposable email domains becomes stale within days. New burner domains appear constantly, causing the prompt to miss throwaway addresses and pollute your CRM. Guardrail: Treat the disposable domain list as an external, updatable tool or context injection, not a static part of the system prompt. Instruct the model to flag domains not on the known-good list as "unverified" and to check for patterns like random strings or known disposable keywords.

04

Unicode Homograph Attacks

What to watch: Malicious actors can register domains using visually identical Unicode characters (e.g., 'mіcrosoft.com' with a Cyrillic 'і'). A naive normalization prompt will pass this as valid. Guardrail: Add a step to detect and flag any non-ASCII characters in the domain part. If internationalized domains are allowed, enforce Punycode conversion and flag the original Unicode for security review before allowing the address into automated workflows.

05

Role-Based Address False Positives

What to watch: Aggressively flagging all role-based addresses (e.g., info@, support@) as invalid can block legitimate B2B leads and operational contacts. Guardrail: Instead of a binary valid/invalid flag, use a tiered classification: 'personal', 'role-based', 'disposable', 'unknown'. Route role-based addresses to a separate marketing suppression list rather than deleting them, preserving them for transactional or operational use cases.

06

Silent Truncation of Whitespace

What to watch: A raw email string like 'user @domain.com' with an internal space is structurally invalid. Trimming it to 'user@domain.com' without logging the change hides a data quality issue that could indicate a broken upstream form or integration. Guardrail: Never silently fix structural errors. Return the cleaned version alongside a 'corrections_applied' array detailing every change (e.g., "removed internal whitespace"). Route records with structural corrections to a data quality monitoring dashboard.

IMPLEMENTATION TABLE

Evaluation Rubric

Use this rubric to test the email cleaning prompt before shipping. Each criterion targets a common failure mode in production email normalization pipelines. Run these checks against a golden dataset of 50-100 known emails covering valid, invalid, and edge-case inputs.

CriterionPass StandardFailure SignalTest Method

RFC 5322 Format Validation

All syntactically valid emails pass; all invalid emails fail with specific rejection reason

Valid email rejected or invalid email accepted without flag

Run against RFC compliance test suite with known-valid and known-invalid addresses

Whitespace and Casing Normalization

Leading/trailing whitespace removed; domain portion lowercased; local part preserved as-is per spec

Domain contains uppercase characters in output; whitespace present in cleaned value

Feed emails with mixed casing and surrounding whitespace; assert output matches expected normalized form

Disposable Domain Detection

Known disposable domains flagged with [DISPOSABLE_DOMAIN] rejection reason; false positive rate under 2%

Disposable address accepted as valid; legitimate custom domain flagged as disposable

Test against curated list of 20 known disposable domains and 20 legitimate custom domains

Role-Based Address Flagging

Addresses like admin@, info@, support@ flagged with [ROLE_BASED] warning but not rejected

Role-based address silently accepted without flag; personal address incorrectly flagged as role-based

Feed 15 common role prefixes and 15 personal addresses; verify flagging accuracy

Null and Empty Input Handling

Null input returns null output with [MISSING_INPUT] reason; empty string returns empty with [EMPTY_INPUT] reason

Null or empty input causes parsing error, hallucinated email, or unhandled exception

Pass null and empty string inputs directly; assert output contract fields populated correctly

Rejection Reason Completeness

Every rejected email includes exactly one rejection reason from defined enum: INVALID_FORMAT, DISPOSABLE_DOMAIN, ROLE_BASED, MISSING_INPUT, EMPTY_INPUT

Rejected email missing reason field; multiple reasons returned when one is sufficient; reason not in allowed enum

Validate output schema for all rejected records; check reason field presence and enum membership

Confidence Score Calibration

Confidence score between 0.0 and 1.0 for every output; valid emails score above 0.95; ambiguous cases score below 0.85

Confidence score missing, outside 0-1 range, or 1.0 for clearly ambiguous inputs

Inspect confidence field across 100-record test set; verify distribution aligns with actual ambiguity

Downstream Routing Contract

Output schema matches expected contract: email, is_valid, rejection_reason, confidence, original_input fields all present with correct types

Missing field, wrong type, or extra field that breaks ingestion pipeline

Validate output JSON against schema definition; test deserialization in target ingestion code

ADAPTATION OPTIONS

Adapt This Prompt

How to adapt

Use the base prompt with a single model call and relaxed output schema. Focus on core cleaning (trim, lowercase domain) and basic RFC 5322 validation. Skip disposable domain checks and role-based flagging if they add latency without a downstream routing decision yet.

Simplify the output to { "email": "[CLEANED_EMAIL]", "valid": true/false, "reason": "[REJECTION_REASON_IF_INVALID]" }. Run a handful of known-good and known-bad examples manually.

Watch for

  • Over-cleaning: stripping intentional plus-addresses or case-sensitive local parts before you know the downstream system's contract.
  • False positives on valid but unusual TLDs.
  • No confidence signal, so invalid emails and ambiguous emails look the same.
Prasad Kumkar

About the author

Prasad Kumkar

CEO & MD, Inference Systems

Prasad Kumkar is the CEO & MD of Inference Systems and writes about AI systems architecture, LLM infrastructure, model serving, evaluation, and production deployment. Over 5+ years, he has worked across computer vision models, L5 autonomous vehicle systems, and LLM research, with a focus on taking complex AI ideas into real-world engineering systems.

His work and writing cover AI systems, large language models, AI agents, multimodal systems, autonomous systems, inference optimization, RAG, evaluation, and production AI engineering.