SendpositoryDocs
Guides

Scheduling

Send a message at a future time and cancel it before it goes, with how the schedule is held and why it is always UTC.

Updated

Add scheduled_at with an ISO 8601 timestamp and we hold the message until then.

{
  "from": "Acme <hello@mail.yourdomain.com>",
  "to": ["customer@example.com"],
  "subject": "Your trial ends tomorrow",
  "html": "<p>Renew any time.</p>",
  "scheduled_at": "2026-09-15T09:00:00Z"
}

The response is immediate, and the message sits in scheduled until its time:

{ "id": "169a3e78-d63a-4fd4-a977-44b02d45bab1" }

A time in the past sends immediately rather than erroring - that's kinder than failing a request whose clock was slightly behind.

Scheduled messages go out within about a minute of their time.

If it can't be sent when the time comes

The checks made when you schedule a message are made again when it's due. If by then the account is suspended or closed, the subscription has ended, or the sending domain is no longer verified, the message isn't sent: it becomes failed, the reason is on the message, an email.failed webhook is sent, and the quota it reserved is returned. The same happens if the mail server refuses it, or if - through an outage on our side - the message is more than 24 hours past its time: a message that late is not sent at all, because arriving a day or a week after it was meant to is usually worse than not arriving.

Cancelling

curl -X POST https://api.sendpository.com/v1/emails/{id}/cancel \
  -H "Authorization: Bearer $SENDPOSITORY_API_KEY"
{ "id": "169a3e78-...", "status": "cancelled" }

Cancelling returns the reserved quota. A cancel that succeeds is final - the message will not go, even if its time is seconds away.

Only while it's still scheduled

Once a message has been handed to the provider it's gone - no API can recall it. Cancelling a sent message returns a validation_error rather than pretending to succeed.

Quota timing

Quota is reserved when you schedule, not when the message sends. So a scheduled message can't fail later because you ran out mid-month - the allowance is already set aside. Cancelling gives it back, and so does a message that fails at its send time; either way it goes back to the month it was reserved from.

Attachments can't be scheduled

See Attachments - the file bytes aren't retained, so the combination is refused.

Self-hosting

Scheduled sends are dispatched by a worker endpoint. If you run Sendpository yourself, point a cron at it every minute:

* * * * * curl -sS -X POST https://your-app/api/cron/scheduled-sends \
  -H "Authorization: Bearer $CRON_SECRET"

On this page