# Schedule recurring emails and reminders

> Send an email now, at a set time, or every day, week or month through your own SMTP, with timezones and unsubscribe links. Plus cron and GitHub Actions.

Source: https://formsmtp.com/guides/schedule-recurring-emails · Last updated November 3, 2026

## Three ways to schedule an email

| Way | Best for | Schedules |
| --- | --- | --- |
| **Dashboard** (*Emails*, Pro plan) | Reminders, newsletters and updates to people in your contacts | Now, once at a set time, or daily, weekly or monthly |
| **Your AI assistant** (MCP) | “Send this every Monday at 9” in plain words | Same as the dashboard |
| **Cron + send API** | Any other rhythm, or emails built from your own data | Whatever your cron can express |

## 1. Create a FormSMTP project

[Sign up free](https://app.formsmtp.com/#/signup) and add a project. Pick your email provider so the SMTP host and port fill in, enter your login, and click *Test connection*. Gmail, Google Workspace, Microsoft 365, Zoho, Amazon SES, Brevo, SendGrid, Resend, Mailgun and any other SMTP server work. Personal Outlook.com and Hotmail addresses don’t, because Microsoft only allows OAuth sign-in for them.

## 2. Design the email

Open *Templates* and build the email in the visual builder, or paste HTML. Use variables to personalise it: `{{first_name|there}}` fills in each contact’s first name, with “there” as the fallback. A contact’s `name`, `email` and custom fields are filled in automatically, and you can set extra variables, such as a link, that are the same for everyone.

## 3. Choose who gets it

Scheduled emails go to contacts. In *Emails*, pick everyone who’s subscribed, one or more tags, or type in addresses (up to 500; they’re added as contacts). For a reminder to yourself, type your own address.

To build a list, add people in *Contacts*, import a CSV (an `email`, `name` and `tags` column are recognised; other columns become custom fields), or collect them with a signup form, as in the [waitlist guide](https://formsmtp.com/guides/waitlist-form).

## 4. Pick when it sends

Under **When to send**, choose:

- **Send now**: goes out right after you confirm.
- **Schedule**: one send at the date and time you pick.
- **Repeat**: daily, weekly or monthly from the first send, with an optional **Stop after** date.

Times are in your browser’s timezone, and repeats keep the same local time, so a 9:00 weekly email stays at 9:00 when the clocks change. A monthly email set for the 31st goes out on the last day of shorter months. You can stop a scheduled or repeating email at any time; it goes back to being a draft.

## Unsubscribe links, handled

Each person gets their own copy, with a personal unsubscribe link. If your template doesn’t include `{{unsubscribe_url}}`, FormSMTP adds a small link at the bottom. Every email also carries `List-Unsubscribe` headers for one-click unsubscribe in mail apps. People who unsubscribe are skipped in every later send, and their page lets them subscribe again if it was a mistake.

## Limits to know

- Scheduled emails count toward your plan’s monthly limit (50,000 a month on Pro). Once it’s reached, the rest of that run fails and shows in *Logs*.
- If the project has **Allowed recipients** set, contacts outside that list are skipped. Send list email from a separate project with Allowed recipients left empty, rather than clearing it on a project whose API key or AI connections send other mail: with the list empty, that key can email anyone.
- Your SMTP provider’s own daily limits still apply. For lists of more than a few hundred, use an account built for bulk email, such as Amazon SES, Brevo or Mailgun.

## Or ask your AI assistant

Connect FormSMTP to Claude, ChatGPT or Cursor (see the [MCP setup guide](https://formsmtp.com/guides/mcp-email-server)) and say what you want:

 Send the “Weekly digest” template to everyone tagged team every Monday at 9am Asia/Kolkata until the end of March. 

The assistant uses the `schedule_email` tool, which takes the same options as the dashboard: template, audience, first send time, timezone, repeat and an end date. It should confirm the audience and timing with you before scheduling, and `cancel_scheduled_email` stops it later.

## Custom schedules: cron and the send API

FormSMTP’s HTTP API sends immediately; it doesn’t take a schedule. When you need a rhythm the dashboard doesn’t offer, such as weekdays only or the first Monday of the month, or an email built from your own data, run a cron job that calls `POST /api/v1/send`. Use the project’s API key (`fs_…`), keep it in an environment variable, and leave *Allowed websites* empty, since the request comes from a server.

```bash
# crontab -e
FORMSMTP_KEY=fs_your_api_key

# 08:30 on weekdays, in the server's timezone
30 8 * * 1-5 curl -s -X POST https://app.formsmtp.com/api/v1/send \
  -H "Authorization: Bearer $FORMSMTP_KEY" \
  -H "Content-Type: application/json" \
  -d '{"to":"you@example.com","subject":"Daily standup in 30 minutes","text":"Notes doc: https://example.com/notes"}'
```

The same in Node.js 18 or later, with a saved template:

```js
// remind.mjs: run with node remind.mjs
const res = await fetch("https://app.formsmtp.com/api/v1/send", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.FORMSMTP_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    to: "team@example.com",
    template: "Weekly report",
    variables: { week: new Date().toISOString().slice(0, 10) },
  }),
});
const data = await res.json();
if (!data.success) throw new Error(data.error);
```

### No server? Use GitHub Actions

A scheduled workflow runs for free on GitHub’s machines. Save your key as a repository secret named `FORMSMTP_KEY` and add:

```yaml
# .github/workflows/reminder.yml
name: Weekly reminder
on:
  schedule:
    - cron: "0 9 * * 1"
      timezone: "Europe/London"
  workflow_dispatch:

jobs:
  send:
    runs-on: ubuntu-latest
    steps:
      - run: |
          curl -s -X POST https://app.formsmtp.com/api/v1/send \
            -H "Authorization: Bearer ${{ secrets.FORMSMTP_KEY }}" \
            -H "Content-Type: application/json" \
            -d '{"to":"you@example.com","subject":"Weekly review","text":"Time for the weekly review."}'
```

GitHub runs schedules on the default branch, no more often than every 5 minutes, and runs can be delayed when Actions is busy. In public repositories, scheduled workflows are switched off after 60 days without activity. Without a `timezone`, the cron time is UTC.

Emails from the send API don’t get unsubscribe links added. For anything that goes to a list, use the Emails scheduler, which handles unsubscribes for you.

## FAQ

### Can I send recurring emails for free?

Yes, with a cron job or a GitHub Actions schedule that calls the send API: that works on the Free plan, which covers 1,000 emails a month through your own SMTP account. Scheduling and repeating sends in the dashboard (or by asking your AI) is part of Pro, $5/month for 50,000 emails.

### Can I schedule an email reminder to myself?

Yes. Create a template, open Emails, type your own address as the recipient and choose Schedule for one reminder or Repeat for a daily, weekly or monthly one.

### Which timezone are scheduled emails sent in?

The dashboard uses your browser’s timezone. AI assistants can pass any IANA timezone, such as Asia/Kolkata or America/New_York. Repeats keep the same local time across daylight saving changes.

### Can I schedule through the API?

The HTTP API sends straight away and has no schedule option. Use a cron job or a GitHub Actions schedule that calls POST /api/v1/send, or schedule from the dashboard or an AI assistant.

## More guides

- [Can Claude send emails? Connect it to your SMTP](https://formsmtp.com/guides/claude-send-email)
- [MCP email server: send email from Cursor, ChatGPT & more](https://formsmtp.com/guides/mcp-email-server)
- [How to send email from a static website (no backend)](https://formsmtp.com/guides/send-email-from-static-website)
- [HTML contact form that emails you (copy-paste, no backend)](https://formsmtp.com/guides/html-contact-form)
