Variables
Variables are named, mutable values you can reference inside Speech, Web Request URLs, Conditions and any other text field that supports {VARIABLE_NAME} placeholders. Set a variable once — from the console, a Flow, an API call or a webhook — and use its current value wherever you need it.
Create a variable
Section titled “Create a variable”Go to Variables (app.voicemonkey.io/variables) and use the inline form at the top of the page: type a name, type a value, click Create Variable.
Name rules:
- Uppercase letters, numbers and underscores only, starting with a letter — e.g.
FIRST_NAME,CAMERA_STATUS,UNREAD_COUNT_2. - Up to 64 characters.
WEBHOOK,WEB_RESPONSEandVMare reserved for built-in placeholders ({WEBHOOK.<slug>.<key>},{WEB_RESPONSE.<nodeId>.<path>}and the{VM.…}built-in variables), and so is any name starting withVM_. None of these can be used as variable names.
Value rules:
- Up to 1024 characters in the console form. The API accepts longer strings but extra-long values aren’t recommended — they tend to make announcement TTS unwieldy.
- Anything you’d like — values are plain strings.
Update a variable
Section titled “Update a variable”- From the console — click the pencil icon next to the value, type the new value, hit save.
- From a Flow — use a Set Variable node.
- From an API call —
PUT https://api-v3.voicemonkey.io/variableswith{ "variable": "NAME", "value": "..." }. Or, on any other endpoint (/announce,/trigger,/flow), send avar-NAME=valueparameter — the variable is upserted before the main action runs. See the Variables API. - From an inbound webhook — add
?var-NAME=valueto the/catchURL the caller hits, or includevar-NAMEin the JSON body. Samevar-shorthand as above.
Delete a variable
Section titled “Delete a variable”Click Delete on the variable’s row in the console. Once deleted, any {NAME} placeholders that referenced it are left in the text as typed until a variable with that name exists again.
Use a variable
Section titled “Use a variable”A variable’s current value is substituted wherever its {NAME} placeholder appears, at the moment the surrounding action runs. Placeholders work in:
- Flows — any node text or URL field, a Web Request’s URL, headers and body, a Set Variable value and a Condition’s compare value.
- The Announcement API — every
/announceparameter excepttokenanddevice. - Inbound webhook announcement actions — alongside
{WEBHOOK.<slug>.<key>}.
In an announcement / Speech node
Section titled “In an announcement / Speech node”Hello {FIRST_NAME}, you have {UNREAD_COUNT} unread messages.In a Web Request URL or body
Section titled “In a Web Request URL or body”https://example.com/hook?name={FIRST_NAME}&status={CAMERA_STATUS}In a Condition
Section titled “In a Condition”A Condition node compares a variable against a value using a structured picker (operators: equals, not_equals, contains, not_contains, greater_than, less_than) and branches the Flow based on the result. The picker lists your own variables and the built-in variables. The compare value can itself be a placeholder, e.g. TEMPERATURE greater than {THRESHOLD}. When both sides are plain numbers, equals and not_equals compare them as numbers, so 05 equals 5. See Flows → Control nodes.
Built-in variables
Section titled “Built-in variables”Voice Monkey fills in a set of read-only {VM.…} placeholders for you. You don’t create them, you can’t change them, and they don’t count towards your plan’s variable limit. Use them anywhere {VARIABLE_NAME} works (Flow nodes, /announce and webhook announcement actions), or pick one in a Condition node.
Good morning {VM.USER.FIRST_NAME}, it's {VM.TIME.TEXT12} on {VM.DATE.WEEKDAY}.In the flow editor, nodes with text or URL fields have a Built-in variables list at the bottom of their settings; click an entry to copy its placeholder.
Time and date
Section titled “Time and date”Times and dates use the timezone from your console Settings (UTC if it isn’t set). Weekday and month names are in English.
| Placeholder | Value | Example |
|---|---|---|
{VM.TIME.HOUR} |
Hour on the 24-hour clock (00 to 23) | 15 |
{VM.TIME.HOUR12} |
Hour on the 12-hour clock (1 to 12) | 3 |
{VM.TIME.MINUTE} |
Minute (00 to 59) | 05 |
{VM.TIME.AMPM} |
AM or PM |
PM |
{VM.TIME.TEXT} |
Time on the 24-hour clock | 15:05 |
{VM.TIME.TEXT12} |
Time on the 12-hour clock | 3:05 PM |
{VM.TIME.TIMESTAMP} |
Unix timestamp in seconds | 1790172300 |
{VM.TIME.ISO} |
Date and time with your UTC offset | 2026-09-23T15:05:00+01:00 |
{VM.DATE.DAY} |
Day of the month (1 to 31) | 23 |
{VM.DATE.MONTH} |
Month number (1 to 12) | 9 |
{VM.DATE.MONTH_NAME} |
Month name | September |
{VM.DATE.YEAR} |
Year | 2026 |
{VM.DATE.WEEKDAY} |
Day of the week | Wednesday |
{VM.DATE.WEEKDAY_NUM} |
Day of the week as a number, 1 = Monday to 7 = Sunday | 3 |
{VM.DATE.IS_WEEKEND} |
true on Saturday and Sunday, otherwise false |
false |
{VM.DATE.ISO} |
Date as YYYY-MM-DD | 2026-09-23 |
A Flow started by a schedule sees the time the schedule was due, not the moment it actually started. A schedule set for 3 pm reads {VM.TIME.HOUR} as 15 even if it starts a few seconds late. After a long Wait, or once a Question has been answered, the time is the time the Flow carried on.
Random
Section titled “Random”| Placeholder | Value | Example |
|---|---|---|
{VM.RANDOM.NUMBER} |
Whole number from 1 to 100 | 42 |
{VM.RANDOM.DICE} |
Dice roll from 1 to 6 | 4 |
{VM.RANDOM.COIN} |
heads or tails |
heads |
Random values are picked once per Flow run, so every node in the same run (including after Waits and Questions) sees the same number. The next run gets new ones. Combine one with a Condition to pick a random branch. Each /announce call or webhook announcement gets its own roll.
Flow, account and device
Section titled “Flow, account and device”| Placeholder | Value | Example |
|---|---|---|
{VM.FLOW.NAME} |
Name of the running Flow, empty outside a Flow | Hourly chime |
{VM.FLOW.REF} |
The Flow’s 4-digit request ref, empty outside a Flow | 1234 |
{VM.RUN.SCHEDULE} |
Name of the schedule that started this run, empty otherwise | Every hour |
{VM.USER.NAME} |
Name on your Amazon account | Alex Smith |
{VM.USER.FIRST_NAME} |
First name on your Amazon account | Alex |
{VM.USER.TIMEZONE} |
Your timezone | Europe/London |
{VM.USAGE.REMAINING} |
Requests left in your current monthly period, or unlimited |
850 |
{VM.DEVICE.NAME} |
Name of the Speaker the node plays on | Kitchen Echo |
{VM.DEVICE.NAME} uses the node’s own Speaker. In nodes without one (Condition, Web Request, Set Variable) it’s the Speaker the Flow is currently using, or empty if there isn’t one yet. In an announcement it’s the Speaker you’re announcing on.
A placeholder that isn’t in these tables (for example a typo like {VM.TIME.HOURS}) is left as-is in the output, so it’s easy to spot while testing.
Storing structured (JSON) values
Section titled “Storing structured (JSON) values”The API’s var- shorthand JSON-stringifies objects and arrays before storing, so you can keep structured payloads in a single variable:
{ "var-PAYLOAD": { "temp": 72, "humidity": 45 } }Stored value: {"temp":72,"humidity":45}.
Reference fields with the dotted-path syntax anywhere placeholders work: {PAYLOAD.temp} resolves to 72. Use an index for arrays, e.g. {FORECAST.days[0].summary} or {FORECAST.days.0.summary}. A path that doesn’t exist, or a variable that isn’t valid JSON, leaves the placeholder as typed. The same works for a variable you created in the console, as long as its value is valid JSON.
Variables vs webhook payloads
Section titled “Variables vs webhook payloads”When an inbound webhook fires, its payload is also addressable via {WEBHOOK.<slug>.<key>} without being copied into a variable. Use whichever fits:
- Variables are durable — they live until you delete or overwrite them.
- Webhook payloads are stored per-webhook and overwritten each time that webhook fires; great for “latest reading”-style data without burning a variable slot.
If you want a webhook value to persist like a normal variable, send it as a var-NAME parameter on the /catch URL — that route upserts the variable on receipt.
Plan limits
Section titled “Plan limits”| Plan | Variables |
|---|---|
| Free | 3 |
| Hobby | 25 |
| Ultimate | Unlimited |
Plan limits are checked when creating a new variable. Updates to existing variables always succeed, even after a plan downgrade.
