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.

📘

Prerequisite

This builds on Send your first email (HTTP API). You need a Bearer token and a verified authorized sender.

Fields

FieldTypeDescription
scheduledDatestring (ISO-8601)UTC time to send the message, e.g. 2026-07-10T09:00:00Z. Omit to send immediately.
ttlinteger — minutes, min 0Time-to-live. If the message can't be delivered within this window, Routee stops trying.
maxAttemptsinteger, min 0Maximum 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 limits

You can set scheduledDate together with ttl and maxAttempts in 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