Send email

Scheduling

Scheduled email delivery lets Lettermint accept an email now and release it later. You can schedule a single email, schedule each item in a batch, or use an SMTP header.

Scheduled email delivery is available to Growth and Pro teams. Free and Starter teams can continue to send emails immediately.

Schedule limits

The scheduled time must be from 30 seconds through 30 days after Lettermint receives the request. Both limits are inclusive.

Lettermint accepts these time formats:

FormatExample
ISO 8601 with UTC2026-08-25T07:00:00Z
ISO 8601 with an offset2026-08-25T09:00:00+02:00
Relative English timein 1 hour
English date and timetomorrow at 9am
English time with a timezoneFriday at 3pm ET

Lettermint uses the request receipt time for a relative value. It uses UTC when an English value does not contain a timezone. It converts every accepted value to UTC.

For a batch request, Lettermint uses one receipt time for all items. Each item can have a different scheduled time.

The scheduled time is the time when Lettermint starts the delivery process. It is not a guarantee that the recipient will receive the email at that exact time.

Schedule with the sending API

Add scheduled_at to a send request:

import { Lettermint } from "lettermint"; const lettermint = new Lettermint({ sendingToken: process.env.LETTERMINT_PROJECT_TOKEN!, }); const response = await lettermint.emails.send({ from: "sender@yourdomain.com", to: ["recipient@example.com"], subject: "Appointment reminder", html: "<p>Your appointment starts tomorrow.</p>", scheduled_at: "tomorrow at 9am", });

Install the current SDK release for your language before you run an SDK example. See Integrations for package links and requirements.

Lettermint returns 202 Accepted for a scheduled email:

JSONCode
{ "message_id": "0198df4e-3351-7da3-b01d-a8c77b696f96", "status": "scheduled", "scheduled_at": "2026-08-25T09:00:00+00:00" }

The response contains the normalized UTC time. An immediate send keeps the current immediate-delivery response and behavior.

An X-LM-Scheduled-At value in the API headers object does not schedule an email. Use scheduled_at for an API request.

Schedule a batch

Add scheduled_at to each item that you want to schedule:

import { Lettermint } from "lettermint"; const lettermint = new Lettermint({ sendingToken: process.env.LETTERMINT_PROJECT_TOKEN!, }); const response = await lettermint.emails.sendBatch([ { from: "sender@yourdomain.com", to: ["first@example.com"], subject: "First reminder", text: "Your first reminder.", scheduled_at: "2026-08-25T09:00:00+02:00", }, { from: "sender@yourdomain.com", to: ["second@example.com"], subject: "Second reminder", text: "Your second reminder.", scheduled_at: "in 2 hours", }, ]);

Each batch item is independent. Items without scheduled_at use immediate delivery.

Schedule with SMTP

Add exactly one X-LM-Scheduled-At header to an authenticated outbound SMTP message:

Code
X-LM-Scheduled-At: 2026-08-25T09:00:00+02:00

You can also use an English value:

Code
X-LM-Scheduled-At: Friday at 3pm ET

The header name is not case-sensitive. Lettermint rejects an empty or duplicate header, including duplicates that use different letter casing. Lettermint removes the control header before it stores customer headers or delivers the email.

Only authenticated outbound SMTP accepts this control. Use a Project API token as the SMTP password. After acceptance, the SMTP 250 response contains the normalized UTC schedule.

See Send email with SMTP for connection settings and authentication.

Change a scheduled time

Use the dashboard or the API. The SDK message methods use a Team API token with the write:messages ability. The cURL example uses the Project API token that created the message.

import { Lettermint } from "lettermint"; const lettermint = new Lettermint({ teamToken: process.env.LETTERMINT_TEAM_TOKEN!, }); const response = await lettermint.messages.reschedule( "0198df4e-3351-7da3-b01d-a8c77b696f96", { scheduled_at: "tomorrow at 3pm" }, );

The same time returns 200 OK and does not create a second reschedule event.

You can change the time only when no release worker has an active lease. A canceled email cannot be scheduled again.

Cancel a scheduled email

Use the dashboard, or send a cancel request:

import { Lettermint } from "lettermint"; const lettermint = new Lettermint({ teamToken: process.env.LETTERMINT_TEAM_TOKEN!, }); const response = await lettermint.messages.cancel( "0198df4e-3351-7da3-b01d-a8c77b696f96", );

Cancellation is final. A repeated cancellation returns 200 OK and does not create a second cancellation event.

Dashboard and events

The message status is scheduled before release and canceled after cancellation. The dashboard shows the requested time in local time and UTC. It also shows a safe failure code when a permanent check fails.

Scheduled email events are also available in the timeline and as webhooks:

  • message.scheduled
  • message.rescheduled
  • message.canceled
  • message.released

Credential checks at release

Lettermint checks the original Project API token again at release. The release fails with credential_inactive when the token was deleted, revoked, or no longer has the required access. Token expiration after schedule acceptance does not stop the release.

Lettermint also checks the current team, project, route, domain, Return-Path, and recipient restrictions before release.

Quota reservations

Lettermint reserves email quota when it accepts a scheduled email. Immediate sends and mixed batches include these reservations in their capacity checks. This prevents a team with a hard cap or a spend limit from accepting more email than its limit permits.

At release, Lettermint converts the reservation to submitted usage. It does not run a new quota capacity check. A cancellation or a permanent failure before release removes the reservation.

Idempotent retries

Use an idempotency key when you create a schedule. A retry with the same key and request body returns the original message ID and normalized schedule. Lettermint does not parse a relative value again for a matching idempotent retry.

Errors

Sending API errors

HTTP responseCodeCause
403FEATURE_NOT_AVAILABLEThe team plan does not include scheduled email delivery.
409SCHEDULE_CONFLICTThe current lifecycle state does not permit the action.
422INVALID_SCHEDULEThe time is invalid, too early, or too late.

SMTP errors

SMTP responseCauseRetry
550 5.6.0The header is invalid, empty, duplicated, too early, or too late.Do not retry.
550 5.7.1The plan does not include the feature, or the credential is not permitted.Do not retry.
550 5.7.0The idempotency key conflicts with different content.Do not retry.
451 4.3.0A temporary service, database, storage, or broker failure occurred.Retry later.