---
title: "Schedule and cancel"
description: "Send later, move it, or stop it."
url: "https://nextmail.sh/docs/api/emails/schedule"
area: "API"
category: "Emails"
---

# Schedule and cancel

Send later, move it, or stop it.

**Also documents:** `PATCH /emails/{id}`, `POST /emails/{id}/cancel`

## Scheduling

`scheduledAt` takes an ISO-8601 instant or a duration like `PT2H`, up to a year out. A scheduled message answers `202` with `status: "scheduled"` and stays cancellable right up until it sends.

`cancellableForSeconds` does the same for an immediate send: the composer's undo-send window, exposed rather than hardcoded to a user setting that has no business deciding an API's behaviour. The two are mutually exclusive: a scheduled message is already cancellable.

`followUpAt` works with either, and with a plain send. It takes an ISO 8601 instant or a duration such as `P3D`, later than the time the message goes out, and if nobody has replied by then the thread returns to the top of the inbox, unread. Cancelling the message cancels its reminder. `GET /follow-ups` lists the reminders, and Threads describes them.

## Schedule a send

Two hours out. The response carries the id you will need to move or stop it.

**curl**

```
curl -X POST "$OE/emails" -H "$AUTH" -H "Content-Type: application/json" \
    -d '{
      "from": "billing@acme.com",
      "to": ["ada@example.com"],
      "subject": "Your September invoice",
      "html": "<p>Invoice attached.</p>",
      "scheduledAt": "PT2H"
    }'
```

**Response**

```
HTTP/1.1 202 Accepted
  Location: /emails/msg_8cd0a316930b4482a8b8440b

  {
    "object": "email",
    "id": "msg_8cd0a316930b4482a8b8440b",
    "status": "scheduled",
    "scheduledAt": "2026-09-01T10:19:41.345Z",
    "cancellableUntil": "2026-09-01T10:19:41.345Z",
    "messageId": null,
    "transport": null,
    "sentAt": null
  }
```

> `202`, not `200`: something still has to happen to it. An immediate send answers `200` with `status: "sent"`, so a caller can branch on the status code alone.

## Move it

`PATCH /emails/{id}` with `scheduledAt`, while it is queued or scheduled. The same call changes what it says and who it goes to, as the last example shows.

**curl**

```
curl -X PATCH "$OE/emails/msg_8cd0a316930b4482a8b8440b" \
    -H "$AUTH" -H "Content-Type: application/json" \
    -d '{ "scheduledAt": "PT6H" }'
```

**Response**

```
{
    "object": "email",
    "id": "msg_8cd0a316930b4482a8b8440b",
    "status": "scheduled",
    "scheduledAt": "2026-09-01T14:20:15.881Z"
  }
```

## Stop it

`POST /emails/{id}/cancel`.

**curl**

```
curl -X POST "$OE/emails/msg_8cd0a316930b4482a8b8440b/cancel" -H "$AUTH"
```

**Response**

```
{ "object": "email", "id": "msg_8cd0a316930b4482a8b8440b", "status": "cancelled" }
```

> Cancelling twice is not an error. The second call returns the same cancelled message, so a retry is safe.

> Cancelling one that has already gone is a `409 email_not_cancellable`. It cannot be un-sent, and answering anything else would be a lie.

## Change it

`PATCH /emails/{id}` with any of `subject`, `html`, `text`, `from`, `to`, `cc` and `bcc`, while it is queued or scheduled. A field you leave out keeps its value, and a recipient list replaces the stored one whole.

**curl**

```
curl -X PATCH "$OE/emails/msg_8cd0a316930b4482a8b8440b" \
    -H "$AUTH" -H "Content-Type: application/json" \
    -d '{ "subject": "Your September invoice, corrected", "to": ["ada@example.com", "grace@example.com"] }'
```

**Response**

```
{
    "object": "email",
    "id": "msg_8cd0a316930b4482a8b8440b",
    "status": "scheduled",
    "subject": "Your September invoice, corrected",
    "scheduledAt": "2026-09-01T14:20:15.881Z"
  }
```

> `from` is checked as it is on a send, so it has to be an address the key may send as.

> A message translated when it was accepted keeps its wording, so a new `subject`, `html` or `text` on it is a `409 translation_locked`. One that was encrypted keeps its wording and its recipients. Cancel those and send again.

## Reference

- [`PATCH /emails/{id}`](https://nextmail.sh/docs/api/reference/emails#patch-emails-id): full reference
- [`POST /emails/{id}/cancel`](https://nextmail.sh/docs/api/reference/emails#post-emails-id-cancel): full reference
