Cancel a scheduled transactional email
DELETE
https://emails.routeon.io/api/v1/transactional/{message_id}
Cancels a message still queued with a future send_at, before the scheduler ticks it into delivery. There is no reschedule endpoint: to move a send time, cancel and send again with a NEW Idempotency-Key — the 24 h idempotency dedup window means the same key would just replay the original (now canceled) send. Answers 200 both for a message just canceled and one already canceled, so a client can safely retry a timed-out DELETE.
Parameters
message_id
string<uuid>
required
path
Responses
200
OK
404
Resource not found within tenant scope
409
Uniqueness/state conflict. Where the cause is actionable, meta.details.code carries it — e.g. invalid_state, concurrent_update, suppression_exists, last_owner_protected. Send-path codes: otp_resend_cooldown (POST /otp/request inside the resend cooldown window of the last still-valid code for the same identifier+purpose), content_moderation_pending (fail-closed block while an AI verdict is unavailable — retryable; POST /transactional/send and /transactional/send-batch also raise it when the moderation check is busy or unreachable), idempotency_key_conflict (same Idempotency-Key replayed with a different request body — permanent, pick a new key), idempotency_in_progress (an earlier request holding the same Idempotency-Key is still executing — transient, retry shortly and the same key will replay its result), otp_reserve_not_applied (the credit reserve for POST /otp/request was declined for a reason other than an empty balance, most often because the ledger already held an entry under the same idempotency key — nothing was charged and nothing was sent; retry), and message_not_scheduled (DELETE /transactional/{message_id} on a message that is not `queued` with a future `send_at` — most commonly, the scheduler already picked it up). Sender profiles add sender_already_exists (POST /senders with a local_part the tenant already uses), sender_in_use (DELETE /senders/{id} while a route or campaign still points at the profile) and default_sender_undeletable (DELETE /senders/{id} on the tenant's default profile — promote another profile with is_default first). POST /domains/{id}/provider adds provider_change_in_progress: another change for this same domain is already committing, most commonly a double-submit — retry once the first one settles.
Example response · 200
{
"status": "success",
"http_code": 0,
"payload": {
"message_id": "00000000-0000-0000-0000-000000000000",
"status": "canceled"
},
"meta": []
}
Example response · 404
{
"status": "error",
"http_code": 0,
"payload": [],
"meta": {
"reason": "VALIDATION_ERROR",
"validation_error": [
{
"field": "string",
"message": "string"
}
],
"details": []
}
}
Example response · 409
{
"status": "error",
"http_code": 0,
"payload": [],
"meta": {
"reason": "VALIDATION_ERROR",
"validation_error": [
{
"field": "string",
"message": "string"
}
],
"details": []
}
}