Everything you need,
start to finish.
A walkthrough for the team running support, followed by the reference for whoever deploys and operates the stack. Read it top to bottom the first time, then use the contents to jump back in.
Welcome
maildx turns your support inbox into grounded, reviewable answers.
Email arrives at your support address. maildx reads it, searches your own documentation for an answer, and writes a draft that cites where each claim came from. A human approves it — or, once you trust the pipeline, it goes out on its own.
When the evidence isn't there, maildx does not guess. It opens a ticket and hands the conversation to a person, targeting a 24-hour response. That single rule is what makes the rest safe.
Quick start
From an empty workspace to your first answered email. Budget about twenty minutes; most of it is DNS.
- Create your workspaceSign up with your work email. You'll get a 6-digit code — no password to remember. The first person to sign up becomes the workspace owner.
- Accept the Data Processing AgreementIn Settings → Advanced, accept the DPA. This is required before maildx may process real customer data, and it is the first prerequisite for auto mode.
- Connect your sending domainIn Settings → Email integration, paste a Resend API key and your support address. maildx verifies the domain and issues a webhook URL you paste into Resend.
- Add what you already knowIn Knowledge base, add your help-centre articles, policies, and the answers your team repeats most. This is the only thing maildx is allowed to answer from — the more you add, the more it can handle.
- Send yourself a test emailEmail your support address from an outside account. Watch it land in the Inbox, then open the decision trail to see which sources were cited.
- Work the review queueApprove, edit, or reject each draft. Rejections are routed straight to a human ticket, so nothing is ever left unanswered.
Connect your email & domain verification
maildx receives inbound customer inquiries and delivers verified auto-replies via Resend. Follow this step-by-step setup to publish DNS records, configure Cloudflare, and connect webhooks.
1. Required DNS records
When you add your domain (e.g., maildx.dev) in the Resend dashboard, you will be provided with cryptographic keys and mail transfer routing entries. Add these records in your DNS provider (Cloudflare, AWS Route 53, Namecheap, GoDaddy, etc.):
| Type | Name / Host | Value / Target | Priority | Purpose |
|---|---|---|---|---|
TXT | resend._domainkey | p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrDIk... | — | DKIM: Cryptographic public key that signs outbound support emails and guarantees authenticity. |
TXT | rsend / send | rsend-apne1.forge.rmta.net (or your regional forge endpoint) | — | SPF: Authorizes Resend's mail transfer agents (MTAs) to send mail on behalf of your domain. |
MX | @ (root domain) | inbound-smtp.ap-northeast-1.amazonaws.com | 10 | Inbound Receiving: Directs customer emails sent to your domain to Resend's inbound ingestion servers. |
TXT | _dmarc | v=DMARC1; p=none; rua=mailto:dmarc-reports@yourdomain.com | — | DMARC: Specifies policy for unauthenticated email and delivers delivery health reports. |
Regional Inbound MX Endpoints
The target for your root MX record depends on the region selected when you registered the domain in Resend:
- Tokyo / APAC (
ap-northeast-1):inbound-smtp.ap-northeast-1.amazonaws.com - North Virginia / US East (
us-east-1):inbound-smtp.us-east-1.amazonaws.com - Ireland / Europe (
eu-west-1):inbound-smtp.eu-west-1.amazonaws.com - São Paulo / South America (
sa-east-1):inbound-smtp.sa-east-1.amazonaws.com
2. Connecting Resend to maildx
- Generate a Resend API Key: In your Resend console, navigate to API Keys and create a key with sending permissions.
- Input Credentials in maildx: In maildx, go to Settings → Email integration. Enter your API key (starting with
re_), domain (e.g.maildx.dev), and default support address (e.g.support@maildx.dev). - Copy the Webhook URL & Signing Secret: Upon saving, maildx immediately displays your unique Webhook URL (e.g.
https://your-domain.com/api/webhooks/resend/:token) and Svix signing secret. Store the secret in your password manager — it is encrypted with AES-256-GCM at rest and never shown in plaintext again. - Register Webhook in Resend: Go to Resend → Webhooks → Add Webhook. Paste the Webhook URL and select the following events:
email.received(Required: inbound customer messages)email.delivered(Confirmation of outgoing auto-reply delivery)email.bounced(Detects invalid customer addresses and disables auto-replies)email.complained(Flags spam complaints)
3. Sending a live test
Once your DNS status displays verified in Resend, send an email to your support address from an external address (e.g. your personal Gmail or Outlook). Do not send from the support address itself, as automated loop prevention filters out emails sent from own-domain support mailboxes.
Within 3–5 seconds, the incoming email will appear in your Inbox, log step-by-step progress in the Processing Log, and present a grounded AI draft in the Review Queue.
Teach it your answers (Knowledge Base & RAG)
maildx operates on a strict non-hallucination constraint: the model can only answer using claims directly corroborated by your verified sources. Answer quality is a direct reflection of your knowledge base structure.
How Retrieval-Augmented Generation (RAG) works
When you add documentation or FAQs, maildx splits content into semantic chunks (with overlap to preserve context), generates high-dimensional vector embeddings using Google Gemini text-embedding-004 (768 dimensions), and indexes them in PostgreSQL using pgvector with HNSW cosine distance search.
At query time, maildx performs Hybrid Search: combining dense vector semantic similarity with PostgreSQL full-text BM25 search (websearch_to_tsquery) using reciprocal rank fusion (RRF). This guarantees that exact keywords (like SKU numbers, plan tiers, or error codes) and conceptual queries are both retrieved.
Structuring effective knowledge sources
- One discrete topic per document: Avoid monolithic 20-page manuals. Split guides into focused articles: "Refund policy for annual plans", "Resetting two-factor authentication", "API rate limits".
- Direct lead sentences: State the core rule or resolution in the first paragraph. Our chunk ranker weights passage headers and opening statements heavily.
- Explicit details over vague descriptions: State exact numbers, timelines, currencies, and conditions. The model is forbidden from inventing prices, dates, or URLs.
- FAQ format for recurring tickets: For common questions, write explicit question-and-answer pairs. The question text acts as a semantic anchor matching customer email queries.
- Audit & archive obsolete entries: A stale policy is worse than no policy. If terms change, edit the source immediately or archive it so it is excluded from vector search.
Tuning Retrieval Minimum Score
In Settings → AI behaviour, you can adjust the Retrieval minimum score:
- 0.65 (Recommended Default): Optimal balance between safe grounding and answering breadth.
- 0.75 – 0.85 (Conservative): Strict matching. Ideal for regulated fintech or healthcare environments where answers must exactly mirror verified policy.
- 0.50 – 0.60 (Permissive): Broad matching. Useful when knowledge articles are brief or phrased informally.
Review vs auto mode & safety gates
Safety is built into the state machine. Workspaces always start in Review mode. Auto mode can only be activated once rigorous safety prerequisites are verified by the backend.
| Mode | Execution pipeline | Human involvement | Safety fallback |
|---|---|---|---|
| Review (Default) | Inbound email → Hybrid RAG → AI draft created → Added to Review Queue. | Human reviews draft, modifies text if desired, and clicks Approve or Reject. | Zero emails are sent without human eyes. |
| Auto | Inbound email → Hybrid RAG → Verification check → Immediate dispatch via Resend. | Zero touch for high-confidence grounded answers. Human handles escalations. | Any score below threshold, low confidence, or missing citations escalates to a human ticket. |
The 4 Auto Mode Safety Gates
To prevent premature automated replies, our backend requires the following criteria before enabling Auto mode:
- Data Processing Agreement (DPA) Executed: Under DPDP Act Section 8 and GDPR Article 28, an authorized representative must review and execute terms in Legal → DPA.
- Minimum Knowledge Base Seed: Your knowledge base must contain at least 3 active, indexed sources to prevent empty hallucinations.
- Verified Domain Integration: Inbound MX and outbound DKIM/SPF must be verified with active webhook subscriptions.
- 7-Day Review Maturity or Evaluation Sign-off: The workspace must have operated in Review mode for at least 7 days, or an admin must review and sign off on the automated test evaluation suite.
Your daily loop
Four places matter day to day. Everything else is for setup.
The decision trail
Every AI answer records its model, confidence, the chunks it retrieved, and each claim's source. If you cannot see why a draft says something, do not send it — fix the source instead.
Escalations & SLA
maildx fails toward a human. Understanding when saves a lot of confusion.
A conversation becomes a ticket when
- Retrieval finds no source above your minimum score.
- Grounding confidence falls below your threshold.
- The topic is on your sensitive list — by default chargebacks, legal, security breaches, account takeover, harassment, and data rights requests.
- A human rejects the AI draft.
- The model times out, errors, or returns invalid output.
Data rights requests
Requests about personal data — access, erasure, grievance — are treated as sensitive, routed to your privacy contact, and never auto-replied. Set that contact in Settings → Compliance.
Getting better answers
When quality is not what you want, work in this order.
- Read the decision trailFind the actual source the model used. Nine times out of ten the source is stale, vague, or split across two documents.
- Fix the source, not the promptRewrite the passage so the answer is explicit in the first sentence. Re-embed by saving.
- Add the missing questionIf retrieval found nothing because nobody wrote it down, add an FAQ entry.
- Then consider thresholdsIn Settings → Advanced, raise the grounding threshold to escalate more often. Lower it only if you accept weaker evidence.
- Adjust tone lastTone changes how it sounds, never what is true. Do not use it to paper over missing sources.
FAQ
| Question | Answer |
|---|---|
| Does maildx train AI on my data? | No. Customer data is never used to train foundation models, and inference runs under zero-retention enterprise terms. |
| Can two customers ever see each other's data? | No. Every tenant table is scoped by company, enforced by PostgreSQL row-level security set per transaction, and vector search filters inside the query. |
| What happens if the AI provider goes down? | The conversation becomes a human ticket. Retries use bounded backoff, and unrecoverable jobs land in the dead-letter queue visible in the processing log. |
| Can I stop everything immediately? | Yes. The workspace AI kill switch pauses drafting for your tenant; the platform kill switch pauses all tenants. Inbound mail still becomes tickets. |
| How long is data kept? | Whatever you set in Settings → Compliance, 90 days by default. Older conversations, messages, AI runs, and webhook payloads are purged. |
| Can I export or delete one customer? | Yes, both, from Settings → Compliance. Export produces a JSON archive; deletion is permanent and cascades to messages, tickets, and AI runs. |
| Do I need a password? | No. Sign-in is a 6-digit code emailed to you, and the session lives in an httpOnly cookie. |
Resend production setup runbook
What has to be true in Resend and DNS for inbound customer mail to reach maildx reliably, pass signature checks, and deliver auto-replies without landing in spam.
- Verify Sending & Inbound Domain:In Resend Domains ↗, register your domain (e.g.
maildx.dev) in your target region. Publish all 4 DNS records: DKIM (resend._domainkey), SPF (rsend/send), Receiving MX (@root pointing toinbound-smtp.<region>.amazonaws.comwith priority10), and DMARC (_dmarc). - Disable Cloudflare Proxy (DNS Only):If managed via Cloudflare, ensure proxy status is set to DNS only (Grey cloud). Cloudflare does not proxy raw SMTP email connections — orange cloud proxying will cause incoming emails to fail silently.
- Generate a Scoped Resend API Key:Create an API key with sending permissions. In maildx, go to Settings → Email integration and save the key. maildx encrypts it with AES-256-GCM before saving to Postgres.
- Register the Svix Webhook:In Resend Console → Webhooks, add the Webhook URL provided by maildx:
https://your-domain.com/api/webhooks/resend/:webhookToken
Subscribe to:email.received,email.delivered,email.bounced, andemail.complained. - Cryptographic Signature Verification:maildx verifies the Svix signature headers (
svix-id,svix-timestamp,svix-signature) directly on the raw request body (rawBody: truein NestJS). This guarantees zero body tampering and rejects replay attacks older than 5 minutes. - Perform External Verification Test:Send an email from an external domain (e.g. personal Gmail or Outlook) to your support address (e.g.
support@maildx.dev). Check Processing log to inspect the end-to-end webhook receipt, RAG retrieval, and AI draft generation.
staging.yourcompany.com) and distinct Resend API key for non-production environments. Never share production webhook signing secrets across environments.Go-live checklist
Work through this checklist before switching DNS or announcing your support email address to real customers.
- Database migrations applied and verified in PostgreSQL 16 with pgvector extension enabled.
- Encrypted secrets configured:
AUTH_SECRET(session cookie) andENCRYPTION_KEY(AES-256-GCM for Resend keys) set and securely backed up. - Resend domain status shows verified across DKIM, SPF, and Inbound MX.
- Cloudflare proxy status confirmed to be DNS only (Grey cloud) for all mail-related DNS entries.
- Webhook registered in Resend with
email.received,email.delivered, andemail.bouncedevents enabled. - Knowledge base populated with at least 5–10 structured articles and FAQ entries covering core product workflows and policies.
- Retrieval minimum score tuned (default
0.65recommended). - Data Processing Agreement (DPA) executed in Legal → DPA.
- Privacy contact and DPO email addresses configured in Settings → Compliance.
- Retention policy window chosen and verified (e.g. 90 or 180 days).
- End-to-end test email successfully received, drafted, and approved via the Review Queue.
- Workspace launched in Review mode with assigned staff members actively monitoring incoming drafts.
Troubleshooting guide
When something doesn't behave as expected, start with the Processing log to identify the exact pipeline step.
| Symptom | Root Cause | Resolution |
|---|---|---|
| Inbound email never appears in maildx | 1. Cloudflare proxy (orange cloud) is blocking inbound SMTP. 2. Root MX record missing in DNS. 3. Webhook URL misconfigured in Resend. | Set Cloudflare DNS records to DNS only (Grey cloud). Confirm root MX record points to inbound-smtp.<region>.amazonaws.com with priority 10. In Resend Webhooks, verify delivery status shows 200 OK. |
| Webhook returns 401 Unauthorized | Svix signature mismatch or stale timestamp (>5 minutes). | Re-copy the Webhook signing secret from maildx Settings into Resend, and confirm your server or proxy system clock is properly synchronized via NTP. |
| Every email escalates to a human ticket | Retrieval score is below your configured minimum threshold (default 0.65), or no relevant documents were found. | Test query in Knowledge Base search. If no match is found, add an FAQ entry or policy document covering the customer's question. If articles exist but match loosely, consider lowering threshold to 0.60. |
| Drafts cite irrelevant or outdated documents | Conflicting sources or stale archived information outranking new content in vector search. | Search Knowledge Base for duplicate topics. Archive or permanently delete obsolete documents. Ensure article titles and opening sentences clearly distinguish specific plans or policies. |
| Outgoing replies bounce or get marked as spam | DKIM/SPF records unverified or domain reputation missing DMARC. | Verify in Resend Domains that DKIM and SPF show verified. Ensure DMARC record _dmarc is published. If sending to Gmail/Yahoo, ensure your support domain matches the sender address. |
| AI runs fail with "GEMINI_API_KEY is not set" | The API server started without an active Gemini API key and defaulted to stub mode. | Add GEMINI_API_KEY to your environment variables and restart the API server. In stub mode, dummy citations are used and real drafting is halted. |
| Background queue jobs do not run | Worker process not running, or pg-boss unable to connect to database. | Confirm node dist/worker.js (or main API worker) is running with valid DATABASE_URL and permissions to create tables in the pgboss schema. |
| Cannot toggle Auto mode in Settings | One or more of the 4 safety gates are unsatisfied. | Open Settings → Advanced to inspect the auto mode checklist. Ensure DPA is accepted, at least 3 knowledge sources are indexed, and domain integration is verified. |
Architecture & guarantees
The end-to-end lifecycle of an email through maildx, with strict data isolation and non-hallucination guarantees.
Inbound Ingestion
NestJS API Webhook Controller
Receives customer email events from Resend, verifies cryptographic integrity, persists the raw payload, and acknowledges receipt immediately without inline AI blocking.
- 1Inbound SMTP Event
Customer sends support email; Resend receives SMTP message and triggers webhook to maildx API.
- 2Svix Signature & Timestamp Validation
Verifies HMAC-SHA256 signature on exact rawBody bytes. Rejects payloads older than 5 minutes to prevent replay attacks.
- 3Idempotency & Deduplication
Deduplicates on (integration_id, provider_event_id) and RFC Message-ID to ensure zero duplicate tickets or replies.
- 4Tenant-Scoped Persistence
Saves raw event to Postgres webhook_events table under withTenant(companyId) with Postgres Row Level Security (RLS).
- 5pg-boss Enqueue & 200 OK
Pushes job to Postgres-backed queue and immediately returns HTTP 200 OK (<50ms) to ensure webhooks never timeout.
Async Queue Worker
pg-boss Background Consumer
Pulls queued jobs asynchronously, strips untrusted HTML, filters mail loops, organizes customer conversation threads, and executes hybrid RAG search.
- 1HTML Sanitization & MIME Parser
Extracts clean text body while discarding raw HTML and executable scripts to prevent prompt injection and XSS.
- 2Loop & Auto-Reply Filter
Checks Auto-Submitted, Precedence, and Return-Path headers. Drops bounces and out-of-office loops cleanly.
- 3Customer & Thread Linker
Finds or creates customer profile and links reply to existing conversation thread via References / In-Reply-To.
- 4Intent & Urgency Classification
Lightweight classifier tags billing, technical, privacy requests, and high-priority VIP customer queries.
- 5Hybrid RAG Search (pgvector + BM25)
Runs dual vector cosine similarity (pgvector) and sparse full-text search (BM25) fused via Reciprocal Rank Fusion (RRF).
Grounding & Decision Engine
Zero Hallucination AI Gate
Verifies retrieval quality against company thresholds, drafts answers exclusively from retrieved evidence, and dispatches via review queue or auto-send.
- 1Confidence Score Check (≥ 0.65)
If retrieval score is below 0.65 threshold or evidence is missing, automatically escalates to a human ticket (24h SLA target).
- 2Grounded LLM Drafting
LLM drafts response citing source IDs ([S1], [S2]) exclusively from verified company knowledge chunks. No tool execution permissions.
- 3Fact & Policy Verification Gate
Deterministic claims check validates all assertions against retrieved evidence. Any unverified claims trigger human escalation.
- 4Audit Trail Logging (ai_runs)
Records prompt version, model, retrieved chunk IDs, confidence score, token consumption, and cost for 100% compliance.
- 5Dispatch: Review Queue or Auto Send
Review Mode (default) routes draft to human approval. Auto Mode (opt-in) delivers verified email via Resend with idempotency key.
Core Engineering Non-Negotiables
- Zero Inline Webhook AI Processing: Inbound webhooks do not run LLMs inline. They persist, deduplicate, enqueue, and return 200 within 50ms to prevent webhook timeouts.
- Cryptographic Tenant Isolation: Every database table contains
company_id NOT NULLwith Postgres Row Level Security (RLS) and transaction-scopedapp.company_idconfig. - Vector Isolation: Vector similarity queries filter by
company_idinside the SQL query, preventing cross-tenant data leakage. - Zero Tool Execution for LLMs: The AI model has no independent tools or direct database/network access. It only generates drafts from verified retrieved chunks. Dispatching emails and creating tickets is strictly managed by deterministic application logic.
- Complete Audit Traceability: Every generation writes an
ai_runsentry capturing exact prompt versions, model identifiers, retrieved chunk IDs, confidence scores, token counts, and cost.
API surface
Authenticated routes are tenant-scoped and session-protected. Live OpenAPI docs are served at /api/docs.
| Endpoint | Purpose |
|---|---|
POST /api/auth/otp/request | Email a 6-digit sign-in code. |
POST /api/auth/otp/verify | Exchange the code for a session cookie. |
GET /api/conversations | Tenant-scoped conversation list. |
GET /api/conversations/:id | Full thread with AI runs and citations. |
GET /api/tickets | Tickets with SLA state. |
POST /api/tickets/:id/reply | Send an agent reply (idempotent). |
GET /api/review-queue | AI drafts waiting for human approval. |
POST /api/review-queue/:id/approve | Approve and dispatch a draft. |
POST /api/review-queue/:id/edit | Edit a draft, then dispatch. |
POST /api/review-queue/:id/reject | Reject and open a human ticket. |
GET /api/documents | Knowledge base sources. |
POST /api/documents | Create a document and queue it for embedding. |
POST /api/documents/search | Hybrid vector + full-text search. |
GET /api/processing-log | Per-email pipeline steps. |
GET /api/settings | Workspace settings and AI mode. |
GET /api/settings/auto-mode-readiness | Whether auto mode's prerequisites are satisfied. |
GET /api/integrations/resend | Configured email integration metadata. |
POST /api/integrations/resend | Save and verify Resend credentials. |
DELETE /api/integrations/resend | Revoke credentials and disconnect Resend integration. |
GET /api/privacy/retention | Retention report for the DPDP window. |
POST /api/privacy/export | Export all data for one customer. |
POST /api/privacy/delete | Permanently erase one customer. |
POST /api/webhooks/resend/:token | Inbound Resend webhook (signature verified). |
Data compliance & DPDP Act 2023
maildx is built from the ground up for strict privacy regulations including the Digital Personal Data Protection (DPDP) Act 2023 and GDPR Article 28.
Fiduciary vs. Processor Division
Under the DPDP Act, your company acts as the Data Fiduciary (determining purpose and means), while maildx acts as the Data Processor. Our platform only processes personal data on your documented instructions. A signed Data Processing Agreement (DPA) is required prior to processing live customer data.
Key DPDP Rights Supported Out-of-the-Box
- Right to Access & Portability (Section 11): Customers can request a full summary of personal data held about them. In Data & Privacy Hub or Settings → Compliance, enter the customer's email address to generate and download a comprehensive JSON archive containing all conversation histories, messages, and ticket references.
- Right to Erasure (Section 12): When a customer withdraws consent or requests erasure, enter their email address in the deletion console. maildx permanently deletes all conversations, messages, ticket entries, chunk embeddings, and AI run logs in an irreversible database cascade, writing an audit event to the CERT-In compliant log.
- Automated Data Retention & Purge: Set your data retention window (7 to 365 days). Data older than the cutoff date is identified via dry-run previews and permanently purged through automated background worker jobs.
- Sensitive Privacy Request Routing: Customer emails relating to GDPR/DPDP inquiries, data access requests, or consent withdrawal are automatically classified as sensitive. They are immediately assigned to your Data Protection Officer (DPO) and never answered automatically by AI.
- 180-Day CERT-In Log Retention: Access and audit logs are retained for at least 180 days in compliance with Indian CERT-In cyber security directives. Logs are sanitized: customer email bodies and personal identifiers are never written at info level.
Legal Templates & Sub-Processors
Thank you
You made it to the end. Here is the short version to take away.
Grounded answers come from good sources, so invest your time in the knowledge base rather than in tuning. Stay in review mode until you would happily send the drafts yourself. When something looks wrong, read the decision trail before changing anything — the answer is almost always in the source.
If you get stuck, the processing log tells you what the pipeline actually did, and the links below cover the rest.