Questions · Updated 2026-09-28

How do I cancel a scheduled email?

Cancel a scheduled email with POST /emails/{id}/cancel. The status becomes canceled and the event is email.canceled. POST /emails/bulk-cancel cancels many at once, and POST /emails/{id}/reschedule revives a canceled email.

Cancel a scheduled email with POST /emails/{id}/cancel. The operation summary is "Cancel a scheduled or queued email. Already-sent mail is history, not cancellable." The reply carries id and status, the status is canceled, and GET /emails/{id}/events records an email.canceled event whose data names the previous_status. Nothing is delivered. The same message can be revived later, so a cancel is a pause, not a deletion.

What can be cancelled

Only a message whose status is scheduled or queued. Any other status is refused with invalid_parameter, and the message is "Email … is …; only scheduled or queued mail can be cancelled." with the id and the current status filled in. retryable is false on that refusal, so do not send it again. A message that is already sent has left; GET /emails/{id}/explain tells you what happened to it.

On a message you did cancel, GET /emails/{id}/explain returns verdict canceled, the sentence "Canceled before sending — nothing was delivered." and one action, "Reschedule it if the cancel was a mistake.", whose call names POST /emails/{id}/reschedule.

curl -sS -X POST https://api.agentisend.com/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/cancel \
  -H "Authorization: Bearer $AGENTISEND_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"
201
{
  "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42",
  "status": "string"
}
Response

Cancelling many at once

POST /emails/bulk-cancel is the batch form. Its summary is "Cancel many emails at once: by explicit ids or every scheduled/queued email before a time." The body takes ids, a list of message ids, and before, an ISO 8601 time compared against each message's scheduled_at. Send one or both. A body with neither is refused with "Provide ids and/or before — an unbounded cancel is never what you meant."

The reply has two lists. canceled holds the ids that were cancelled. skipped holds one row per message the call could not catch, each with id and status; a row there was already sent, delivered, canceled or otherwise past the point a cancel applies, so read its status rather than retrying. Each cancelled message gets its own email.canceled event, with bulk: true in the data.

curl -sS -X POST https://api.agentisend.com/emails/bulk-cancel \
  -H "Authorization: Bearer $AGENTISEND_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"
201
{
  "canceled": [],
  "skipped": []
}
Response

Undoing a cancel

POST /emails/{id}/reschedule moves a canceled message back onto the calendar. Its summary is "Move an email to a new time. Works from scheduled AND canceled — a cancel is never terminal." Pass scheduled_at in the same grammar POST /emails accepts: an ISO time, a phrase such as in 2 hours, or now to send it straight away. The status returns to scheduled and an email.scheduled event is recorded with previous_status: canceled. PATCH /emails/{id} is the same act; its summary calls it "the same act as POST /emails/:id/reschedule, under the verb a Resend integration already uses."

What cannot be revived is a message whose delivery is settled. For sent, delivered, bounced, complained, failed or suppressed, the reschedule is refused with "Email … is …; its delivery is already settled."

Next