Configuration Schema Reference
Configuration Schema Reference
Section titled “Configuration Schema Reference”Complete reference for the mailiam.config.yaml configuration file.
File Location
Section titled “File Location”mailiam looks for configuration files in this order:
mailiam.config.yamlmailiam.config.yml.mailiam.yaml.mailiam.yml
Root Schema
Section titled “Root Schema”project: # Project metadata (required)domains: # Domain configurations (required)templates: # Project-level email templates (optional)settings: # Project-level settings (optional)Project Configuration
Section titled “Project Configuration”project: name: "My Application" # Display name (required) slug: "my-application" # URL-safe identifier (required) description: "App description" # Project description (optional) version: "1.0.0" # Project version (optional) id: "project_abc123" # Auto-generated project IDProject Fields
Section titled “Project Fields”| Field | Type | Required | Description |
|---|---|---|---|
name | String | ✅ | Display name for your project |
slug | String | ✅ | URL-safe identifier (auto-generated from name) |
description | String | ❌ | Project description |
version | String | ❌ | Semantic version (default: “1.0.0”) |
id | String | ❌ | Auto-generated unique identifier |
Domain Configuration
Section titled “Domain Configuration”Domains can be configured in two ways:
Full Domain Control
Section titled “Full Domain Control”When you control all email for a domain:
domains: example.com: sender: name: "Example Team" email: "hello@example.com"
allowedOrigins: - "https://example.com" - "https://www.example.com"
forwarding: "hello@example.com": "team@company.com" "support@example.com": "tickets@zendesk.com" "*@example.com": "admin@company.com"
forms: contact: name: "Contact Form" recipient: "team@example.com" acknowledgment: enabled: true subject: "Thanks for contacting us!" settings: rateLimit: 20 spamProtection: "strict"
settings: rateLimit: 100 requireApiKey: falseDelegated Subdomain
Section titled “Delegated Subdomain”When you only control a specific subdomain:
domains: mail.example.com: type: delegated parentDomain: example.com sender: name: "Example Mail" email: "noreply@mail.example.com"
forwarding: "noreply@mail.example.com": "team@example.com"Domain Fields
Section titled “Domain Fields”| Field | Type | Required | Description |
|---|---|---|---|
type | String | ❌ | Set to “delegated” for subdomains (omit for full domains) |
parentDomain | String | ❌ | Required for delegated domains |
sender | Object | ✅ | Default sender configuration |
allowedOrigins | Array | ❌ | Allowed CORS origins |
forwarding | Object | ❌ | Email forwarding rules |
forms | Object | ❌ | Form configurations |
settings | Object | ❌ | Domain-level settings |
Email Forwarding
Section titled “Email Forwarding”forwarding: # Simple forwarding "hello@example.com": "destination@company.com"
# Multiple destinations "support@example.com": - "team1@company.com" - "team2@company.com"
# Catch-all forwarding "*@example.com": "admin@company.com"
# Subdomain forwarding "*@sub.example.com": "subdomain@company.com"Reply Identity Preservation
Section titled “Reply Identity Preservation”🔄 NEW FEATURE: Configure reply identity preservation to make replies appear from your domain even when sent from external email addresses (like Gmail).
domains: example.com: # Basic reply identity configuration replyIdentity: enabled: true # Enable SRS-based identity preservation mode: "smart" # Options: "smart", "always", "manual"
# Identity preservation settings preservation: fromDomain: true # Preserve domain identity fromName: "smart" # Options: "smart", "always", "custom" customName: "Example Support" # Custom name when fromName: "custom"
# Authorization (who can send as this domain) authorization: allowList: # Authorized senders - "*@company.com" # Wildcard patterns supported - "owner@gmail.com" # Specific addresses - "support@example.com" autoDetect: true # Auto-add form recipients
# Advanced settings advanced: srsMaxAge: 30 # Days to keep SRS mappings (default: 30) trackReplies: true # Log reply chains (default: true) signature: enabled: false # Add signature to replies text: "Sent via {{domain}}" # Text signature template html: "<em>Sent via {{domain}}</em>" # HTML signature template
# Enhanced forwarding with reply identity forwarding: rules: - match: "support@example.com" to: "team@company.com" replyIdentity: enabled: true mode: "preserve" fromAddress: "support@example.com" fromName: "Example Support" allowedSenders: - "team@company.com" - "*@company.com"
- match: "sales@example.com" to: - "john@company.com" - "jane@company.com" replyIdentity: enabled: true mode: "preserve" fromAddress: "sales@example.com" fromName: "Example Sales Team"Reply Identity Modes
Section titled “Reply Identity Modes”| Mode | Description |
|---|---|
smart | Automatically enable for authorized senders, passthrough for others |
always | Always try to preserve identity (requires authorization) |
manual | Only apply when explicitly configured per form/rule |
Form-Level Reply Identity
Section titled “Form-Level Reply Identity”forms: contact: name: "Contact Form" recipient: "team@example.com" replyIdentity: enabled: true # Enable for this form mode: "preserve" # Override domain mode fromAddress: "contact@example.com" # Specific reply identity fromName: "Example Contact Team" # Custom name allowedSenders: # Override domain allowList - "support@company.com" - "manager@company.com" signature: enabled: true text: "Reply directly to continue the conversation"Signature Templates
Section titled “Signature Templates”Add custom signatures to SRS replies with React Email templates. Signatures are injected when someone replies through a forwarded email, making replies look professional and on-brand.
domains: example.com: forwarding: enabled: true rules: # Array format with signature support - match: "support@example.com" to: "team@company.com" signature: template: "professional" # Built-in template name variables: teamName: "Support Team" phone: "+1-555-0123" tagline: "Here to help!"
- match: "sales@example.com" to: "sales-team@company.com" signature: template: "branded" variables: teamName: "Sales Team" website: "https://example.com" logoUrl: "https://example.com/logo.png" twitter: "exampleco"
# Minimal signature - match: "hello@example.com" to: "owner@gmail.com" signature: template: "minimal" variables: teamName: "Example Team"Built-in Signature Templates
Section titled “Built-in Signature Templates”| Template | Description | Variables |
|---|---|---|
professional | Standard business signature with name, contact info, and tagline | teamName, domain, phone, website, tagline |
minimal | Simple name and optional tagline | teamName, tagline |
branded | Full branding with logo and social links | teamName, domain, phone, website, logoUrl, tagline, twitter, linkedin |
Auto-populated Variables
Section titled “Auto-populated Variables”These variables are automatically available in all signature templates:
| Variable | Description |
|---|---|
{{senderName}} | Name of the person replying |
{{senderEmail}} | Email of the person replying |
{{domain}} | The domain the reply is sent from |
{{date}} | Current date (formatted) |
{{originalSubject}} | Original email subject |
Example: Professional Signature Output
Section titled “Example: Professional Signature Output”signature: template: "professional" variables: teamName: "Mailiam Support" phone: "+1-555-MAIL" website: "https://mailiam.dev" tagline: "Making email magical"Results in:
Best regards,Mailiam Supportmailiam.dev | +1-555-MAIL"Making email magical"Form Configuration
Section titled “Form Configuration”forms: contact: name: "Contact Form" # Display name recipient: "team@example.com" # Required: where to send form data acknowledgment: enabled: true # Send acknowledgment emails subject: "Thanks for contacting!" # Subject line settings: rateLimit: 10 # Override domain rate limit spamProtection: "strict" # Override spam protection level requireApiKey: false # Override API key requirement
newsletter: name: "Newsletter Signup" recipient: "marketing@example.com" acknowledgment: enabled: true subject: "Welcome to our newsletter!"Form Fields
Section titled “Form Fields”| Field | Type | Required | Description |
|---|---|---|---|
name | String | ❌ | Display name for the form |
recipient | String | ✅ | Email address to receive form submissions |
acknowledgment | Object | ❌ | Acknowledgment email settings |
settings | Object | ❌ | Form-level settings overrides |
Acknowledgment Configuration
Section titled “Acknowledgment Configuration”| Field | Type | Required | Description |
|---|---|---|---|
enabled | Boolean | ❌ | Send acknowledgment emails (default: false) |
subject | String | ❌ | Email subject line |
Templates
Section titled “Templates”Define reusable email templates at the project level:
templates: contact-thanks: subject: "Thanks for contacting us!" html: "./templates/contact-thanks.html" text: | Hi {{ form.name }},
Thanks for reaching out! We received your message:
"{{ form.message }}"
We'll get back to you within 24 hours.
Best regards, The Team
welcome: subject: "Welcome to {{ project.name }}!" html: "./templates/welcome.html" text: | Welcome to {{ project.name }}!
Thank you for signing up. We're excited to have you aboard!Template Fields
Section titled “Template Fields”| Field | Type | Required | Description |
|---|---|---|---|
subject | String | ✅ | Email subject line |
html | String | ❌ | Path to HTML template file |
text | String | ❌ | Plain text content |
Settings
Section titled “Settings”Configure default behavior with cascading settings:
settings: rateLimit: 100 # Default submissions per hour spamProtection: "enhanced" # Spam protection level requireApiKey: true # Require API key for submissionsSettings cascade in this order:
- Project settings (apply to everything)
- Domain settings (override project for that domain)
- Form settings (override domain for that form)
Settings Fields
Section titled “Settings Fields”| Field | Type | Default | Description |
|---|---|---|---|
rateLimit | Number | 100 | Maximum submissions per hour |
spamProtection | String | ”enhanced” | Spam protection level (low, normal, enhanced, strict) |
requireApiKey | Boolean | true | Require API key for form submissions |
Template Variables
Section titled “Template Variables”Available variables in all templates:
Form Variables
Section titled “Form Variables”{{ form.name }}- Sender’s name{{ form.email }}- Sender’s email{{ form.message }}- Message content{{ form.* }}- Any form field
Project Variables
Section titled “Project Variables”{{ project.name }}- Project name{{ project.description }}- Project description
System Variables
Section titled “System Variables”{{ timestamp }}- Submission timestamp{{ domain }}- Domain name
Complete Example
Section titled “Complete Example”project: name: "My SaaS App" slug: my-saas-app description: "Customer communication platform"
domains: # Full domain control myapp.com: sender: name: "MyApp Team" email: "hello@myapp.com"
forms: contact: name: "Contact Us" recipient: "support@myapp.com" acknowledgment: enabled: true subject: "Thanks for contacting us!" settings: rateLimit: 20 spamProtection: "strict"
forwarding: "hello@myapp.com": "team@myapp.com" "*@myapp.com": "admin@myapp.com"
settings: requireApiKey: false
# Delegated subdomain mail.myapp.com: type: delegated parentDomain: myapp.com sender: name: "MyApp Mailer" email: "noreply@mail.myapp.com"
templates: contact-thanks: subject: "Thanks for reaching out!" html: "./templates/contact-thanks.html" text: | Hi {{ form.name }},
Thanks for contacting {{ project.name }}! We received your message and will respond soon.
settings: rateLimit: 100 spamProtection: "enhanced" requireApiKey: true