Skip to the documentation
API

Schedule and cancel

Send later, move it, or stop it.

PATCHapi.openemail.uk/emails/{id}

Runs any of the 2 calls on this page against your workspace, with your own key.

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.

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": "[email protected]",      "to": ["[email protected]"],      "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}. Only scheduledAt can change, and only while it is queued or scheduled.

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.