crontoolModern Cron Expression Builder

Cron Job Send Newsletter Every Tuesday

Schedule your weekly newsletter to send every Tuesday at 8am via Resend, Postmark, or Mailchimp — fully automated.

0 8 * * 2
At 08:00 AM, only on Tuesday
Open in builder →

What this schedule does

The expression 0 8 * * 2 fires at exactly 8:00 AM every Tuesday. The five fields mean: minute=0, hour=8, any day of month, any month, day 2 (Tuesday). It never runs on any other day of the week.

Tuesday morning is a popular choice for newsletters — subscribers are past the Monday rush and still early in their week. The 8am window catches people before their morning standup and typically yields higher open rates than midday or end-of-week sends.

How to send a newsletter with a script

A newsletter send script fetches your subscriber list, renders your content, and calls your email provider's API. The pattern works identically with Resend, Postmark, Mailchimp, or any transactional email service that exposes a REST API.

The script below uses Resend (a developer-friendly email API). Swap the API call for Postmark's /email/batch or Mailchimp's /campaigns/{id}/actions/send endpoint if needed.

#!/usr/bin/env python3
"""Send weekly newsletter via Resend API — runs every Tuesday at 8am."""
import os
import json
import urllib.request
import urllib.error

RESEND_API_KEY = os.environ["RESEND_API_KEY"]
FROM_EMAIL     = os.environ.get("FROM_EMAIL", "newsletter@yourdomain.com")
RESEND_URL     = "https://api.resend.com/emails"

def get_subscribers() -> list[dict]:
    """
    Return your subscriber list. In production, query your database or
    call your list provider (ConvertKit, Buttondown, etc.).
    """
    return [
        {"email": "alice@example.com", "name": "Alice"},
        {"email": "bob@example.com",   "name": "Bob"},
    ]

def render_html(name: str) -> str:
    """Build the email HTML. Replace this with your template engine."""
    return f"""
    <html><body>
    <h2>Hey {name}, here's your Tuesday brief</h2>
    <p>This week's highlights:</p>
    <ul>
      <li>Story one — summary here</li>
      <li>Story two — summary here</li>
    </ul>
    <p><small><a href="{{unsubscribe_url}}">Unsubscribe</a></small></p>
    </body></html>
    """

def send_email(to_email: str, to_name: str) -> None:
    payload = json.dumps({
        "from":    FROM_EMAIL,
        "to":      [to_email],
        "subject": "Your Tuesday Newsletter",
        "html":    render_html(to_name),
    }).encode()

    req = urllib.request.Request(
        RESEND_URL,
        data=payload,
        headers={
            "Authorization": f"Bearer {RESEND_API_KEY}",
            "Content-Type":  "application/json",
        },
        method="POST",
    )
    try:
        with urllib.request.urlopen(req) as resp:
            result = json.loads(resp.read())
            print(f"Sent to {to_email}: id={result.get('id')}")
    except urllib.error.HTTPError as e:
        print(f"Failed to send to {to_email}: {e.code} {e.read().decode()}")

def main():
    subscribers = get_subscribers()
    print(f"Sending newsletter to {len(subscribers)} subscribers...")
    for sub in subscribers:
        send_email(sub["email"], sub["name"])
    print("Done.")

if __name__ == "__main__":
    main()

Platform snippets

Standard crontab
# crontab -e
0 8 * * 2    /usr/bin/python3 /path/to/send_newsletter.py
GitHub Actions
on:
  schedule:
    - cron: '0 8 * * 2'   # UTC — adjust for your timezone

jobs:
  send-newsletter:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'
      - name: Send newsletter
        run: python send_newsletter.py
        env:
          RESEND_API_KEY: ${{ secrets.RESEND_API_KEY }}
          FROM_EMAIL: newsletter@yourdomain.com
AWS EventBridge
# EventBridge cron (6 fields — adds year, UTC)
cron(0 8 ? * TUE *)
Kubernetes CronJob
apiVersion: batch/v1
kind: CronJob
metadata:
  name: newsletter-sender
spec:
  schedule: "0 8 * * 2"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: sender
            image: your-image:latest
            command: ["python", "send_newsletter.py"]
            env:
            - name: RESEND_API_KEY
              valueFrom:
                secretKeyRef:
                  name: newsletter-secrets
                  key: resend-api-key
          restartPolicy: OnFailure

Timezone note

Standard crontab uses the system timezone. GitHub Actions and AWS EventBridge run in UTC — if you're on US Eastern time (UTC-5), use 0 13 * * 2 to fire at 8am ET. If you're on US Pacific time (UTC-8), use 0 16 * * 2. Kubernetes 1.27+ supports spec.timeZone: "America/New_York" to avoid the manual offset math.

More guides

Morning brief Social post scheduler Weekly metrics report Database backup