Skip to content

EmailOS Scheduled Email Sending

Send emails at a future time using EmailOS's built-in scheduler. Schedule emails with simple commands and let the watch daemon handle sending them at the right time.

Quick Start

bash
# Schedule an email for 2 hours from now
mailos send --to [email protected] \
  --subject "Meeting Reminder" \
  --body "Don't forget our 3pm meeting" \
  --schedule-in 2h

# Start the scheduler to send scheduled emails
mailos watch

How It Works

  1. Schedule emails using --schedule-at or --schedule-in flags with the send command
  2. Start the scheduler with mailos watch in a dedicated terminal or background process
  3. Emails are sent automatically at their scheduled time
  4. Sent emails are archived to ~/.email/sent-scheduled/

Scheduling Commands

Schedule Using Relative Time (--schedule-in)

Schedule emails relative to the current time using Go duration format:

bash
# 30 minutes from now
mailos send --to [email protected] \
  --subject "Follow-up" \
  --body "Checking in on the proposal" \
  --schedule-in 30m

# 2 hours from now
mailos send --to [email protected] \
  --subject "Daily Update" \
  --body "Here's today's progress report" \
  --schedule-in 2h

# 24 hours (tomorrow at this time)
mailos send --to [email protected] \
  --subject "Weekly Report" \
  --body "This week's accomplishments..." \
  --schedule-in 24h

# 1 hour 30 minutes from now
mailos send --to [email protected] \
  --subject "Contract Review" \
  --body "Please review the attached contract" \
  --schedule-in 1h30m

Supported Duration Units

  • s - seconds (e.g., 30s)
  • m - minutes (e.g., 15m)
  • h - hours (e.g., 2h)
  • Combinations (e.g., 1h30m, 2h15m30s)

Schedule Using Absolute Time (--schedule-at)

Schedule emails for a specific date and time using RFC3339 format:

bash
# Specific date and time (UTC)
mailos send --to [email protected] \
  --subject "Quarterly Review" \
  --body "Q4 results are ready for review" \
  --schedule-at "2026-01-28T09:00:00Z"

# Specific date and time (with timezone)
mailos send --to [email protected] \
  --subject "Project Launch" \
  --body "The new feature goes live today!" \
  --schedule-at "2026-02-01T15:00:00-05:00"

# ISO8601 format (without timezone assumes local time)
mailos send --to [email protected] \
  --subject "Meeting Reminder" \
  --body "Stand-up meeting in 1 hour" \
  --schedule-at "2026-01-28T10:30:00"

Time Format Requirements

  • RFC3339: 2006-01-02T15:04:05Z (UTC)
  • RFC3339 with timezone: 2006-01-02T15:04:05-07:00
  • ISO8601: 2006-01-02T15:04:05 (local time)

Note: Scheduled time must be in the future. Past times will result in an error.

Managing Scheduled Emails

List Scheduled Emails

View all pending scheduled emails:

bash
mailos schedule-list

Example output:

📬 Scheduled Emails (3)

1. ⏰ Pending
   ID: 1769539111027403000
   To: [[email protected]]
   Subject: Follow-up Meeting
   Scheduled: 2026-01-28 14:30:00 (in 2h 15m)
   Created: 2026-01-28 12:15:00

2. ⏰ Pending
   ID: 1769539212027403001
   To: [[email protected]]
   Subject: Daily Update
   Scheduled: 2026-01-28 17:00:00 (in 4h 45m)
   Created: 2026-01-28 12:15:00

3. ⚡ Due now
   ID: 1769539313027403002
   To: [[email protected]]
   Subject: Urgent Report
   Scheduled: 2026-01-28 12:00:00
   Created: 2026-01-28 11:55:00

💡 Run 'mailos watch' to start the scheduler

Watch Command - The Scheduler Daemon

The watch command monitors scheduled emails and sends them at the right time:

bash
# Start watching with default 1-minute interval
mailos watch

# Check every 30 seconds (more responsive)
mailos watch --interval 30s

# Check every 5 minutes (lower resource usage)
mailos watch --interval 5m

# Show detailed output (useful for debugging)
mailos watch --verbose

# Process due emails once and exit (useful for cron jobs)
mailos watch --once

Watch Command Output

📬 EmailOS Scheduler Started
   Checking for scheduled emails every 1m0s
   Press Ctrl+C to stop

[12:15:30] Checking for due emails...
   No emails due

[12:16:30] Checking for due emails...

📤 Sending 1 scheduled email(s)...

✅ Sent: Follow-up Meeting → [[email protected]]

Watch Command Flags

FlagTypeDefaultDescription
--intervalduration1m0sCheck interval (e.g., 30s, 1m, 5m)
--onceboolfalseProcess due emails once and exit
--verboseboolfalseShow detailed output including SMTP debug info

Storage Locations

Scheduled emails are stored in JSON format in your home directory:

  • Pending emails: ~/.email/scheduled-emails/
  • Sent archive: ~/.email/sent-scheduled/

File Format

Each scheduled email is stored as a JSON file:

~/.email/scheduled-emails/20260128_143000_1769539111027403000.json

Filename format: {scheduled_time}_{email_id}.json

Workflow Examples

Simple Daily Reminder

Schedule a daily reminder at 9 AM:

bash
# Calculate time until 9 AM tomorrow
mailos send --to [email protected] \
  --subject "Daily Task Reminder" \
  --body "Don't forget to review the project board" \
  --schedule-at "2026-01-29T09:00:00Z"

Batch Scheduling

Schedule multiple emails at once:

bash
# Morning follow-up
mailos send --to [email protected] \
  --subject "Project Update" \
  --body "..." \
  --schedule-in 2h

# Afternoon check-in
mailos send --to [email protected] \
  --subject "Status Check" \
  --body "..." \
  --schedule-in 6h

# Evening summary
mailos send --to [email protected] \
  --subject "Daily Summary" \
  --body "..." \
  --schedule-in 10h

# Start the scheduler
mailos watch

Background Scheduler

Run the scheduler as a background process:

bash
# Using nohup (output to log file)
nohup mailos watch --interval 30s > ~/mailos-scheduler.log 2>&1 &

# Using disown (bash/zsh)
mailos watch --interval 30s &
disown

# Check if scheduler is running
ps aux | grep "mailos watch"

# Stop the scheduler
pkill -f "mailos watch"

Cron Integration

Use watch --once in a cron job for scheduled checks:

bash
# Add to crontab: crontab -e
# Check every 5 minutes
*/5 * * * * /usr/local/bin/mailos watch --once >> ~/mailos-cron.log 2>&1

# Check every hour at :00
0 * * * * /usr/local/bin/mailos watch --once

# Check every 15 minutes during business hours (9 AM - 5 PM)
*/15 9-17 * * * /usr/local/bin/mailos watch --once

Auto-start on Terminal Launch

Add to your shell startup file (~/.zshrc or ~/.bashrc):

bash
# Start scheduler silently in background on terminal launch
if ! pgrep -f "mailos watch" > /dev/null; then
  nohup mailos watch --interval 30s > /dev/null 2>&1 &
fi

Advanced Usage

Scheduling with All Send Features

Combine scheduling with other send command features:

bash
# Schedule email with attachments
mailos send --to [email protected] \
  --subject "Proposal Document" \
  --body "Please review the attached proposal" \
  --attach ~/Documents/proposal.pdf \
  --schedule-in 3h

# Schedule with CC and BCC
mailos send --to [email protected] \
  --cc [email protected] \
  --bcc [email protected] \
  --subject "Contract Agreement" \
  --body "Please review and sign" \
  --schedule-at "2026-01-29T10:00:00Z"

# Schedule with custom signature
mailos send --to [email protected] \
  --subject "Purchase Order" \
  --body "Attached is the PO for review" \
  --signature "Best regards,\nProcurement Team" \
  --schedule-in 24h

# Schedule markdown email with template
mailos send --to [email protected] \
  --subject "Monthly Newsletter" \
  --file newsletter.md \
  --template \
  --schedule-at "2026-02-01T08:00:00Z"

Account-Specific Scheduling

Schedule emails from specific accounts:

bash
# From work account
mailos send --account [email protected] \
  --to [email protected] \
  --subject "Work Update" \
  --body "..." \
  --schedule-in 2h

# From personal account
mailos send --account [email protected] \
  --to [email protected] \
  --subject "Catch up" \
  --body "..." \
  --schedule-at "2026-01-29T18:00:00Z"

Troubleshooting

Email Not Sent at Scheduled Time

Problem: Email remains in scheduled queue past its scheduled time.

Solution:

  1. Check if mailos watch is running: ps aux | grep "mailos watch"
  2. Verify no errors in watch output: mailos watch --verbose
  3. Check system time is correct: date
  4. Manually process due emails: mailos watch --once

Watch Command Not Finding Due Emails

Problem: Watch command reports "No emails due" when emails should be sent.

Solution:

  1. List scheduled emails: mailos schedule-list
  2. Verify scheduled time is in the past
  3. Check file permissions: ls -la ~/.email/scheduled-emails/
  4. Run watch with verbose flag: mailos watch --once --verbose

Cannot Schedule Past Times

Problem: Error: "scheduled time must be in the future"

Solution:

  • Verify your system time is correct: date
  • For --schedule-at, ensure timezone is specified correctly
  • For --schedule-in, use positive durations only

Scheduler High Resource Usage

Problem: Watch command using too much CPU or memory.

Solution:

  • Increase check interval: mailos watch --interval 5m (instead of default 1m)
  • Use cron with --once instead of continuous watch
  • Check for orphaned watch processes: pkill -f "mailos watch"

Email Sent But Still in Queue

Problem: Email was sent but still appears in mailos schedule-list.

Solution:

  • Check sent-scheduled folder: ls ~/.email/sent-scheduled/
  • Manually remove from queue: rm ~/.email/scheduled-emails/{email_file}.json
  • Restart watch command

Integration Examples

With Email Groups

Schedule bulk emails to groups:

bash
# Schedule to email group
mailos send --group team-leads \
  --subject "Leadership Meeting" \
  --body "Agenda attached" \
  --schedule-at "2026-01-29T14:00:00Z"

With Natural Language

Combine with natural language parsing:

bash
# Natural language will be parsed, then scheduled
mailos send "remind the team about tomorrow's meeting" --schedule-in 12h

Preview Before Scheduling

Preview the email before scheduling:

bash
# Preview the email (won't schedule)
mailos send --to [email protected] \
  --subject "Test" \
  --body "Preview content" \
  --preview

# Then schedule if satisfied
mailos send --to [email protected] \
  --subject "Test" \
  --body "Preview content" \
  --schedule-in 1h

Best Practices

  1. Keep watch running: Use background process or cron for reliable sending
  2. Use relative times for near-future emails (easier than calculating exact times)
  3. Use absolute times for emails that must go at specific times (e.g., 9 AM daily)
  4. Check scheduler logs: Use --verbose to debug timing issues
  5. Set appropriate intervals: 1 minute for time-sensitive, 5 minutes for general use
  6. Monitor sent folder: Review ~/.email/sent-scheduled/ periodically
  7. Test with short durations: Use --schedule-in 1m to test your setup
  8. Archive old scheduled emails: Clean up ~/.email/sent-scheduled/ monthly
  • mailos send - Main email sending command with all flags
  • mailos schedule-list - List all scheduled emails
  • mailos watch - Scheduler daemon to send scheduled emails

Files and Directories

PathPurpose
~/.email/scheduled-emails/Pending scheduled emails (JSON format)
~/.email/sent-scheduled/Archive of sent scheduled emails
~/.email/.email/config.jsonAccount configuration used by scheduler

Technical Details

Email Message Structure

Each scheduled email is stored with complete metadata:

json
{
  "id": "1769539111027403000",
  "scheduled_at": "2026-01-28T14:30:00Z",
  "message": {
    "to": ["[email protected]"],
    "cc": [],
    "bcc": [],
    "subject": "Follow-up Meeting",
    "body": "Let's discuss the project status",
    "attachments": [],
    "include_signature": true
  },
  "account_email": "[email protected]",
  "created_at": "2026-01-28T12:15:00Z"
}

Scheduling Algorithm

  1. Email is saved to ~/.email/scheduled-emails/ with timestamp in filename
  2. Watch command checks directory every interval (default: 1 minute)
  3. Compares scheduled_at time with current time
  4. Sends email if scheduled_at <= current_time
  5. Moves sent email to ~/.email/sent-scheduled/
  6. Removes from scheduled queue

Time Precision

  • Check interval determines precision (default: 1 minute)
  • Emails sent within 1 minute of scheduled time (or your custom interval)
  • For more precise timing, use shorter intervals: --interval 10s

See Also

Released under the MIT License.