Voice AI

Build a Scheduled Reminder Agent on Telnyx Edge Compute

Reminders sound simple until you try to make them behave like a real product.

Sending one SMS later is easy. The harder part is what happens after the reminder goes out.

Did the person reply? Did they ask to snooze it? Did they say "remind me in two hours"? Should the next reminder wait 30 minutes, an hour, or longer? Where does that state live? What wakes the workflow back up without a separate queue, cron job, worker, and database?

That is what this example is about.

scheduled-reminder-agent is a TypeScript example that runs on Telnyx Edge Compute with the Telnyx Agent SDK. It sends scheduled SMS reminders, stores reminder state per phone number, uses Telnyx AI Inference to detect snooze intent, and adapts the next reminder time with exponential backoff.

Code: https://github.com/team-telnyx/telnyx-code-examples/tree/main/scheduled-reminder-agent

What we are building

The app exposes a simple endpoint:

POST /remind

You send it a recipient, message, and delay. The Edge Compute function routes that request to a ReminderAgent actor keyed by the recipient's phone number.

From there, the actor owns the lifecycle:

POST /remind
  -> ReminderAgent.scheduleReminder()
  -> this.schedule(delay, "sendReminder")
  -> Telnyx Messaging sends the SMS
  -> inbound SMS reply reaches /webhooks/sms
  -> Telnyx AI Inference detects snooze vs acknowledge
  -> this.schedule(nextDelay, "sendReminder") if snoozed

The important detail is that the reminder is not stored in a stateless webhook handler. It lives with the actor that owns that recipient's reminder workflow.

Why the Agent SDK matters

The Agent SDK gives this example three primitives that are awkward to stitch together manually:

  • durable state with this.setState() and this.getState()
  • durable scheduled tasks with this.schedule()
  • zero-credential Telnyx API access with this.env.TELNYX

The state tracks active reminders, snooze count, whether the app is waiting for a reply, and the adaptive base delay.

The scheduled task fires when it is time to send the SMS.

The Telnyx binding sends the SMS and calls AI Inference without hardcoding an API key in the application code.

That combination turns a reminder into a small stateful agent instead of a loose collection of cron jobs and callbacks.

The reminder flow

When a client calls POST /remind, the app validates the message and recipient, finds the actor for that recipient, and calls:

await stub.scheduleReminder(message, delayMinutes * 60, from, to);

Inside the actor, scheduleReminder() creates a reminder record and schedules sendReminder():

await this.schedule(delaySeconds, "sendReminder", { id }, { id: `send-${id}` });

When the scheduler fires, sendReminder() sends the SMS:

await this.env.TELNYX.messages.send({
  from: state.fromNumber,
  to: state.phoneNumber,
  text: smsText,
});

Then it opens a reply window by scheduling replyTimeout().

So the workflow can continue even after the original HTTP request is long gone.

Snooze detection with AI

The user does not need to reply with a perfect command.

They might say:

snooze
not now
remind me later
in two hours
busy, try again after lunch

The actor sends the reply to Telnyx AI Inference and asks for JSON:

{
  "intent": "snooze",
  "delay_minutes": 120
}

If the model detects an acknowledgement, the reminder is marked done.

If it detects a snooze, the actor schedules the reminder again.

Adaptive timing

The example uses exponential backoff when the user asks to snooze but does not give an exact time.

The default progression is:

30 minutes
1 hour
2 hours
4 hours
8 hours

That means the agent gets less pushy over time instead of sending the same reminder over and over at a fixed interval.

If the user specifies a time, like "snooze for 2 hours," that explicit delay wins.

This is a small behavior, but it makes the reminder feel more like an assistant and less like a timer.

Testing it

After deploying with telnyx-edge ship, you can schedule a reminder:

curl -X POST https://scheduled-reminder-agent-<id>.telnyxcompute.com/remind \
  -H "Content-Type: application/json" \
  -d '{
    "to":"+15551230000",
    "from":"+15559870000",
    "message":"Time for your meeting",
    "delay_minutes":5
  }'

For local workflow testing, the sample also includes debug routes:

curl -X POST https://scheduled-reminder-agent-<id>.telnyxcompute.com/debug/reply \
  -H "Content-Type: application/json" \
  -d '{
    "from":"+15551230000",
    "text":"snooze for 2 hours"
  }'

And you can inspect actor state:

curl "https://scheduled-reminder-agent-<id>.telnyxcompute.com/debug/state?from=+15551230000"

Where this pattern goes next

This is useful beyond a basic reminder app.

The same pattern can support:

  • medication reminders
  • appointment nudges
  • payment follow-ups
  • maintenance reminders
  • onboarding check-ins
  • delivery updates
  • renewal workflows

The core pattern is durable communications state plus scheduled work.

Before using this in production, I would add webhook signature verification, SMS opt-out handling, idempotency keys, timezone-aware scheduling, stronger retry handling, and alerting for failed sends or missed reminders.

But the shape is already here.

If an agent needs to contact someone later, it needs more than a prompt. It needs state, timers, reply handling, and a way to wake itself back up.

Resources

  • Code: https://github.com/team-telnyx/telnyx-code-examples/tree/main/scheduled-reminder-agent
  • Agent SDK docs: https://developers.telnyx.com/docs/agent-sdk
  • Agent SDK quickstart: https://developers.telnyx.com/docs/agent-sdk/quickstart
  • Roll Your Own Agent: https://developers.telnyx.com/docs/agent-sdk/examples/roll-your-own
  • Edge Compute docs: https://developers.telnyx.com/docs/edge-compute
  • Messaging docs: https://developers.telnyx.com/docs/messaging
  • Telnyx AI Inference docs: https://developers.telnyx.com/docs/inference
  • Telnyx AI skills and toolkits: https://github.com/team-telnyx/ai
  • Telnyx Portal: https://portal.telnyx.com/

Ready to build with low-latency voice AI?

Join developers building the future of real-time conversations