Schedule & control delivery
Control when a message is sent and how long Routee keeps trying to deliver it. Add scheduledDate, ttl, and maxAttempts to the same POST /transactional-email payload you already use.
PrerequisiteThis builds on Send your first email (HTTP API). You need a Bearer token and a verified authorized sender.
Fields
| Field | Type | Description |
|---|---|---|
scheduledDate | string (ISO-8601) | UTC time to send the message, e.g. 2026-07-10T09:00:00Z. Omit to send immediately. |
ttl | integer — minutes, min 0 | Time-to-live. If the message can't be delivered within this window, Routee stops trying. |
maxAttempts | integer, min 0 | Maximum number of delivery attempts before Routee gives up. |
Schedule for later
Set scheduledDate to a future UTC time in ISO-8601 format. The message is queued and released at that time.
curl -X POST 'https://connect.routee.net/transactional-email' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"from": { "name": "Acme", "address": "[email protected]" },
"to": [{ "address": "[email protected]" }],
"subject": "Your weekly summary",
"content": { "html": "<p>Here is your weekly summary.</p>" },
"scheduledDate": "2026-07-10T09:00:00Z"
}'Control delivery attempts
Use ttl and maxAttempts together to bound how long — and how often — Routee retries a message that can't be delivered on the first try. This is useful for time-sensitive messages such as one-time codes that lose value if they arrive late.
curl -X POST 'https://connect.routee.net/transactional-email' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"from": { "address": "[email protected]" },
"to": [{ "address": "[email protected]" }],
"subject": "Your login code",
"content": { "html": "<p>Your code is 123456. It expires in 10 minutes.</p>" },
"ttl": 10,
"maxAttempts": 3
}'import requests
payload = {
"from": {"address": "[email protected]"},
"to": [{"address": "[email protected]"}],
"subject": "Your login code",
"content": {"html": "<p>Your code is 123456. It expires in 10 minutes.</p>"},
"ttl": 10,
"maxAttempts": 3,
}
resp = requests.post(
"https://connect.routee.net/transactional-email",
headers={"Authorization": "Bearer YOUR_ACCESS_TOKEN", "Content-Type": "application/json"},
json=payload,
)
print(resp.status_code, resp.json())const res = await fetch("https://connect.routee.net/transactional-email", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json",
},
body: JSON.stringify({
from: { address: "[email protected]" },
to: [{ address: "[email protected]" }],
subject: "Your login code",
content: { html: "<p>Your code is 123456. It expires in 10 minutes.</p>" },
ttl: 10,
maxAttempts: 3,
}),
});
console.log(res.status, await res.json());
Combine scheduling with retry limitsYou can set
scheduledDatetogether withttlandmaxAttemptsin the same request — schedule the send, then bound how long Routee keeps trying once it starts.
A 200 response returns a trackingId just like an immediate send. Use it to confirm the final outcome.
Next steps
- Custom headers & List-Unsubscribe — add one-click unsubscribe and tag messages
- Delivery Status Notifications (DSN) & footers — get notified about delivery outcomes
- Full reference: Send a transactional email

