How to Schedule Reminders From an AI Agent or Script

An autonomous agent that runs unattended for hours has no way to tell you it needs a decision, unless something schedules that message in advance. Pingwire is a developer-first messaging platform: one HTTP call, CLI command, or MCP tool call schedules a reminder that lands in a real-time chat and as a web push, at an exact future time or on a recurring cron schedule, with no polling loop required. This covers the three ways to schedule that reminder and when each one fits.

Why can't the agent just send the message when it's done?

It can, and often should, for a one-shot "the run finished" ping — that's the case covered in sending a push notification from an AI agent. The problem shows up in two other shapes: the agent needs to speak at a SPECIFIC future time it can compute now but won't be running at (a nightly batch job scheduling tomorrow's 9am status check), or it needs to speak on a RECURRING cadence without staying resident (a weekly digest, a Monday standup nudge). Sending immediately covers neither case. Scheduling a message up front, and letting a separate always-on worker deliver it later, does.

How do I schedule a reminder from a script or AI agent?

The REST endpoint is POST /api/v1/reminders, authenticated with a Bearer API key scoped to schedule. It accepts either a one-off ISO 8601 timestamp or a cron expression plus timezone:

  1. Get a scoped API key from your Pingwire account (Settings → API keys), and pick a target: a channel slug, or your own username for a private note-to-self.
  2. For a one-off reminder, POST with run_at set to the UTC instant you want it delivered.
  3. For a recurring reminder, POST with cron (standard 5-field syntax) and a timezone, so "9am Monday" survives daylight saving changes correctly.
  4. Poll GET /api/v1/reminders any time to see what's still pending and what already fired, including delivery status.
  5. Send DELETE /api/v1/reminders?id=N to cancel one your agent scheduled but no longer needs.
curl -X POST https://pingwire.dev/api/v1/reminders \
  -H "Authorization: Bearer pw_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "jlugo",
    "title": "Nightly ETL",
    "text": "Review yesterday's failed rows before the 9am standup.",
    "run_at": "2026-08-30T13:00:00Z"
  }'

A one-off reminder is stored once and fires once. A recurring one keeps recalculating its next run from the cron expression, so the agent that created it does not need to still be running when it fires. Every timestamp is stored internally as UTC; the timezone field only records how to INTERPRET a cron expression like "9am", so changing your account timezone later never silently shifts reminders you already scheduled. Reminder creation itself sits behind its own rate bucket, 60 creations per minute per key, which is worth knowing before an agent loops over a list and schedules one reminder per item instead of batching them.

The same action is one line from a shell, which matters if the agent is really just a cron-triggered script rather than something that speaks HTTP directly:

pingwire remind "+10 minutes" "Check the deploy finished cleanly" --to jlugo
pingwire remind --cron "0 9 * * 1" --channel team "Weekly sync" --tz America/New_York

The first form takes a relative offset and fires once; the second takes a cron expression and a target channel instead of a username, for a reminder the whole team should see rather than a private one.

How does Pingwire's MCP connector let an agent schedule its own pings?

Agents built on the Model Context Protocol can call Pingwire directly as a tool, without you hand-rolling the HTTP call in every project. The MCP connector exposes a scheduling tool that maps onto the same reminders endpoint, plus a send tool for immediate pings and read tools for monitors and channels. When an agent schedules a reminder to its OWN username through the connector, Pingwire routes it into that account's private "notes to self" conversation, created automatically on first use, rather than any shared channel, so an agent's internal scheduling never leaks into a team chat by accident.

This is also where the manual version stops being worth maintaining: a bash script that sleeps, wakes, checks a clock, and curls a webhook is a small dead-man's-switch you now own and debug forever. Handing the same job to Pingwire's MCP connector moves the clock-watching off your machine entirely, and the agent only has to describe WHEN and WHAT, never HOW to wait.

What this does not do

A scheduled reminder is a message, not a check. It fires unconditionally at the time or cadence you set, on the assumption you'll read it. If you need something that only fires when a condition is FALSE, like "alert me if the nightly job never checks in," that is a monitor with a heartbeat, a separate feature covered in monitoring long-running agent runs, not a reminder.

Reminders vs. monitors vs. a plain cron job: which one fits?

These three solve adjacent but different problems, and picking the wrong one means building the other one later anyway.

MechanismFires whenNeeds a live process?Good for
System cron + curlIts own schedule, if the host is upYes, on that hostSimple internal jobs you already operate
Pingwire reminderA time or cron expression you set onceNo — Pingwire's worker owns itAgent-scheduled human-facing nudges
Pingwire heartbeat monitorAn expected check-in goes silentNo — absence-based, not schedule-based"Did the job even run?" dead-man's-switches

A cron job you already run is fine as long as YOU are the one who has to notice a silent failure. The moment the point is to notify a HUMAN at a specific moment, or to catch the job not running at all, the schedule and the notification are better split into two separate, purpose-built primitives instead of one script doing both.

Is it safe to let an agent schedule messages on my behalf?

The honest concern here is scope creep: an agent with a general-purpose API key could message anyone, not just remind you. Pingwire API keys are scoped per-capability (a key issued for schedule cannot post to arbitrary channels it wasn't also granted), and self-hosting the platform is supported if you'd rather the whole message store sit on infrastructure you control instead of a hosted account. Neither removes the need to review what an agent is authorized to do before granting a key, but a scoped key limits the blast radius of a compromised or over-eager agent to exactly the one action you gave it.

The other honest limit: Pingwire delivers reminders through its chat UI and web push. It is not an SMS or phone-call platform, so a reminder that lands while your phone is off or notifications are muted waits for you the same way any other push notification does, it does not escalate to a different channel on its own.

Set up your first agent-scheduled reminder

Create a scoped API key, point one POST /api/v1/reminders call at your own username with a run_at five minutes out, and confirm it arrives as a push before wiring it into a real agent workflow. From there, swap in the MCP connector if your agent already speaks MCP, or the CLI and REST reference if it doesn't. Create a free Pingwire account to get your first API key.

Frequently asked questions

Can an AI agent schedule a reminder without staying running?

Yes. Once a reminder is created through POST /api/v1/reminders with a run_at timestamp or a cron expression, Pingwire's own scheduler worker owns delivery from that point on. The agent or script that created it can exit immediately; it does not need to be alive when the reminder actually fires.

What is the difference between a one-off and a recurring reminder?

A one-off reminder takes a single run_at ISO 8601 timestamp and fires exactly once. A recurring reminder takes a standard 5-field cron expression plus a timezone, and Pingwire recalculates its next run time after each firing, so it keeps repeating without being recreated.

Does scheduling a reminder require the MCP connector?

No. The MCP connector is a convenience layer for agents that already speak the Model Context Protocol; it calls the same underlying reminders endpoint. Any script or backend can schedule a reminder directly with a plain HTTP POST and a Bearer API key, with no MCP involved.

Where does a reminder an agent schedules to itself get delivered?

When a Bearer-authenticated caller schedules a reminder to its own username, Pingwire delivers it into that account's private notes-to-self conversation, created automatically on first use. It never lands in a shared team channel unless the agent explicitly targeted one.

Can I cancel a reminder an agent scheduled earlier?

Yes. DELETE /api/v1/reminders?id=N cancels it by id, and GET /api/v1/reminders lists every reminder tied to your account, active and historical, so an agent can look up the id of a reminder it created earlier before deciding whether to cancel it.

Is a scheduled reminder the same thing as a heartbeat monitor?

No. A reminder fires unconditionally at the time you set. A heartbeat monitor instead watches for an expected check-in and alerts you when one goes silent, which is the right tool for catching a job that failed to run at all rather than one that ran and needs to notify you.

Try Pingwire

Send your first alert in under 30 seconds — one HTTP call, straight to a chat and your phone.

Create a free account Read the API docs

More from the blog