Scheduling in Letta uses absolute timestamps via the /v1/agents/{agent_id}/messages/scheduled endpoint. But agents aren’t great at calculating exact times from relative delays like “in 1 hour.”
This guide shows how to build a custom tool that handles the conversion, letting your agent schedule with simple delay arguments.
The Problem
The scheduling API requires ISO 8601 timestamps:
client.agents.messages.create_scheduled(
agent_id=agent_id,
scheduled_time="2026-01-12T20:00:00Z", # Absolute time required
messages=[...]
)
Agents struggle to calculate “current time + 1 hour” reliably.
The Solution: A Delay-Based Tool
def schedule_delayed_message(delay_seconds: int, message: str) -> str:
"""
Schedule a one-time message to be sent after a delay.
Args:
delay_seconds: Number of seconds to wait before sending
message: The message content to send to this agent
Returns:
Confirmation with scheduled time
"""
import os
from datetime import datetime, timezone, timedelta
agent_id = os.getenv("LETTA_AGENT_ID")
# Calculate absolute time from delay
now = datetime.now(timezone.utc)
scheduled_time = now + timedelta(seconds=delay_seconds)
scheduled_iso = scheduled_time.isoformat()
# Create the scheduled message
result = client.agents.messages.create_scheduled(
agent_id=agent_id,
scheduled_time=scheduled_iso,
messages=[{"role": "user", "content": message}]
)
return f"Scheduled message for {scheduled_iso} (in {delay_seconds} seconds). Job ID: {result.id}"
Usage Examples
Once attached to your agent, it can:
- “Remind me about the meeting in 3600 seconds” (1 hour)
- “Send me a follow-up in 86400 seconds” (24 hours)
- “Check back in 300 seconds” (5 minutes)
Convenience Wrapper with Units
For friendlier UX, add unit conversion:
def schedule_reminder(delay: int, unit: str, message: str) -> str:
"""
Schedule a reminder with human-friendly time units.
Args:
delay: Number of time units to wait
unit: Time unit - "seconds", "minutes", "hours", or "days"
message: The reminder message
Returns:
Confirmation with scheduled time
"""
import os
from datetime import datetime, timezone, timedelta
agent_id = os.getenv("LETTA_AGENT_ID")
# Convert to seconds
multipliers = {
"seconds": 1,
"minutes": 60,
"hours": 3600,
"days": 86400
}
if unit not in multipliers:
return f"Invalid unit '{unit}'. Use: seconds, minutes, hours, or days"
delay_seconds = delay * multipliers[unit]
now = datetime.now(timezone.utc)
scheduled_time = now + timedelta(seconds=delay_seconds)
result = client.agents.messages.create_scheduled(
agent_id=agent_id,
scheduled_time=scheduled_time.isoformat(),
messages=[{"role": "user", "content": message}]
)
return f"Reminder set for {delay} {unit} from now ({scheduled_time.isoformat()})"
Now the agent can say: “I’ll remind you in 2 hours” and call schedule_reminder(2, "hours", "Follow up on proposal").
Setup
- Create the tool via ADE or SDK
- Attach to your agent
- Ensure
LETTA_AGENT_IDis available (automatic on Cloud, add as tool variable on self-hosted)
Notes
- The
clientvariable is pre-injected on Letta Cloud - For self-hosted, you’ll need to instantiate the client inside the tool
- Scheduled messages are one-time by default; for recurring, see the cron_expression parameter in the docs
Docs reference: Scheduling messages | Letta Docs