Skip to content
These docs are for Voice Monkey v3.

Reminders API

Create and manage reminders over HTTP: announcements that play on your speakers at a set time, once or on chosen days.

GET/POST/PUT/DELETE https://api-v3.voicemonkey.io/reminders
  • POST — create a reminder, or replace one by externalId.
  • GET — list reminders, or read one by id or externalId.
  • PUT — change some fields of an existing reminder.
  • DELETE — delete a reminder.

Authenticate with the same token parameter or Authorization: Bearer header as every other endpoint. See Authentication.

Terminal window
curl -X POST https://api-v3.voicemonkey.io/reminders \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"speech": "The washing is done",
"device": "kitchen-echo-abc12",
"in": "45m",
"externalId": "washing-machine"
}'

Returns 201 with the stored reminder:

{
"success": true,
"created": true,
"data": {
"id": "6f0c5a52-1d4e-4f2b-9a51-3c1f7c0e9d21",
"externalId": "washing-machine",
"name": "The washing is done",
"isEnabled": true,
"type": "once",
"at": "2026-10-06T11:45:00.000Z",
"time": null,
"days": null,
"devices": ["kitchen-echo-abc12"],
"speech": "The washing is done",
"voice": "",
"chime": "",
"screen": "",
"countdown": {
"enabled": false,
"preset": null,
"intervals": [],
"finale": { "enabled": true, "seconds": 10, "tick": "soundbank://soundlibrary/scifi/amzn_sfx_scifi_timer_beep_01", "ending": "soundbank://soundlibrary/alarms/air_horns/air_horn_01" }
},
"createdVia": "api",
"lastFiredAt": null,
"nextFireAt": "2026-10-06T11:45:00.000Z",
"nextEvent": { "kind": "main", "at": "2026-10-06T11:45:00.000Z" },
"createdAt": "2026-10-06T11:00:00.000Z",
"updatedAt": "2026-10-06T11:00:00.000Z"
}
}
Parameter Required Description
speech one of speech, chime, screen What Alexa says. Can contain placeholders, resolved when the reminder plays.
device / devices yes Speaker(s) to play on: a device ID or name, a comma-separated list, or an array. Up to 10.
at for one-off When it plays. 2026-10-07T08:15 is read in your account timezone; ISO timestamps with Z or an offset (2026-10-07T08:15:00-04:00) and Unix timestamps (seconds or milliseconds) are also accepted. Up to 366 days ahead.
in for one-off Delay from now instead of at: 45m, 1h30m, 90s, 2d, 1 hour 30 minutes, ISO 8601 PT45M, or a plain number of minutes.
time for repeating Time of day, 24-hour HH:mm, in your account timezone.
days no Days a repeating reminder plays: mon…sun (comma-separated or an array), weekdays, weekends or daily. Defaults to every day.
name no Label shown in the console. Defaults to the start of speech.
externalId no Your own ID for the reminder (letters, numbers and . _ : @ / -, up to 128 characters). See Replacing a reminder.
voice no An Alexa voice ID or one of your own voices, as on the Announcement API.
chime no Sound before the message: a soundbank:// URL or an https:// link to an Alexa-compatible MP3.
screen no ID of a Screen to show on Echo Show, Echo Spot and Fire TV.
enabled no false to save the reminder paused. Defaults to true.
countdown no Announcements before the time and a spoken finale. See Countdowns.

Use at or in for a one-off reminder, or time (and optionally days) for a repeating one. You can also pass type (once or recurring) to be explicit.

A repeating reminder every weekday:

Terminal window
curl -X POST https://api-v3.voicemonkey.io/reminders \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "School run",
"speech": "Ten minutes until we leave. Shoes on!",
"devices": ["kids-room-def34", "kitchen-echo-abc12"],
"time": "08:05",
"days": "weekdays"
}'

POST also accepts query-string parameters, so a simple GET-style integration works too:

Terminal window
curl -X POST "https://api-v3.voicemonkey.io/reminders?token=YOUR_TOKEN&device=kitchen-echo-abc12&in=20m&speech=Pizza%20is%20ready"

A countdown adds announcements before the reminder’s time and, optionally, a finale that counts the last seconds out loud so “zero” lands on the time. The simplest form is a preset name:

{ "name": "School run", "speech": "Time to go!", "device": "kids-room-def34", "time": "08:15", "days": "weekdays", "countdown": "standard" }

countdown also takes true (the Standard preset), false, or an object:

"countdown": {
"preset": "custom",
"intervals": [
{ "before": "20m", "say": "{VM.COUNTDOWN.TIME_LEFT} until we leave." },
{ "before": "5m", "say": "Five minutes! Shoes and coats on.", "sound": "soundbank://soundlibrary/alarms/buzzers/buzzers_01" }
],
"finale": { "seconds": 10, "tick": "soundbank://soundlibrary/scifi/amzn_sfx_scifi_timer_beep_01", "ending": "soundbank://soundlibrary/alarms/air_horns/air_horn_01" }
}
Field Description
enabled false to switch the countdown off but keep its settings. Defaults to true when you send a countdown.
preset gentle (1 hour, 30, 15, 5 min), standard (30, 15, 10, 5, 2, 1 min) or intense (15, 10, 5, 4, 3, 2, 1 min). Fills intervals unless you send them.
intervals Up to 12 announcements, each 1 minute to 12 hours before the time and at least 1 minute apart. before takes a duration like in does (plain numbers are minutes); responses use beforeSeconds, which you can also send. say defaults to {VM.COUNTDOWN.TIME_LEFT} until {VM.REMINDER.NAME}. and sound to a sound that gets more urgent closer to the time; send "" for no sound.
finale true, false, a length in seconds (5, 10, 20 or 30), or { enabled, seconds, tick, ending }. On by default with 10 seconds, a tick each second and an air horn at zero. After the sound at zero, Alexa says the reminder’s speech.

Placeholders {VM.COUNTDOWN.TIME_LEFT}, {VM.COUNTDOWN.MINUTES_LEFT}, {VM.REMINDER.NAME} and {VM.REMINDER.TIME} work in every announcement. On query strings, use the preset shorthand, e.g. &countdown=gentle.

Each announcement counts as one request per speaker when it plays, and the finale and the reminder together count as one.

When a POST carries an externalId that another reminder already has, that reminder is replaced (same id, new contents) and the response is 200 with "created": false. This lets an integration resend the whole reminder whenever something changes, without keeping track of Voice Monkey’s IDs or creating duplicates.

Terminal window
curl "https://api-v3.voicemonkey.io/reminders?token=YOUR_TOKEN"
{ "success": true, "data": [ { "id": "6f0c5a52-…", "name": "The washing is done", "nextFireAt": "2026-10-06T11:45:00.000Z", "…": "…" } ] }

Reminders are listed soonest first. Read one with ?id=… or ?externalId=…, which returns { "success": true, "data": { … } } or 404 REMINDER_NOT_FOUND.

One-off reminders are deleted once they’ve played, so a 404 for one you created earlier usually means it has already played. Check Usage in the console to confirm.

PUT changes only the fields you send. Identify the reminder with id or externalId:

Terminal window
curl -X PUT https://api-v3.voicemonkey.io/reminders \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "externalId": "washing-machine", "in": "10m" }'

Sending at or in turns a repeating reminder into a one-off; sending time turns a one-off into a repeating one. Send "enabled": false to pause a reminder. To change a reminder’s externalId, identify it by id and send the new externalId.

Terminal window
curl -X DELETE https://api-v3.voicemonkey.io/reminders \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "externalId": "washing-machine" }'
{ "success": true, "id": "6f0c5a52-1d4e-4f2b-9a51-3c1f7c0e9d21" }
Field Description
id Voice Monkey’s ID for the reminder.
externalId Your ID, or null.
type once or recurring.
at For one-off reminders, when it plays (UTC).
time, days For repeating reminders, the local time and days.
nextFireAt The reminder’s next time (UTC), or null when paused.
nextEvent The next thing it plays: { kind, at } where kind is lead (a countdown announcement, with beforeSeconds), finale (sent just before the time) or main (the reminder at its time). null when paused.
lastFiredAt When a repeating reminder last reached its time.
countdown The countdown settings (see Countdowns). They’re kept while enabled is false, ready for switching back on.
createdVia console or api.

Errors return an error code and a readable message:

Status error Meaning
400 MISSING_MESSAGE No speech, chime or screen.
400 MISSING_DEVICE No speaker given.
400 MISSING_TIME No at, in or time.
400 INVALID_TIME at, in or time couldn’t be read, or both at and in were sent.
400 INVALID_DAYS days contains something other than days of the week or weekdays / weekends / daily.
400 TIME_IN_PAST The time has already passed.
400 TOO_FAR_AHEAD More than 366 days ahead.
400 INVALID_REMINDER Another field is invalid; message says which.
400 INVALID_COUNTDOWN The countdown can’t be played as sent, e.g. announcements too close together or an unsupported finale length; message says why.
400 MISSING_REMINDER PUT or DELETE without id or externalId.
401 UNAUTHORIZED / INVALID_TOKEN Missing or invalid token.
403 REMINDER_LIMIT_REACHED Your plan’s reminder limit is used up (includes "upgrade": true).
403 RECURRING_NOT_AVAILABLE Repeating reminders need the Hobby or Ultimate plan (includes "upgrade": true).
404 DEVICE_NOT_FOUND A device isn’t one of your speakers.
404 SCREEN_NOT_FOUND No screen with that ID.
404 REMINDER_NOT_FOUND No reminder with that id or externalId.
409 EXTERNAL_ID_TAKEN Another reminder already uses that externalId (on PUT).
  • Creating, reading and deleting reminders doesn’t count against your monthly requests. Each speaker a reminder plays on counts as one request when it plays.
  • var-NAME=value parameters work here too and are saved before the reminder, like on every other endpoint. See the Variables API.
  • Placeholders in speech are resolved when the reminder plays, not when it’s created, so {VM.TIME.TEXT12} says the time it plays.