Skip to content
These docs are for Voice Monkey v3.

Inbound Webhooks

Inbound webhooks let external systems send Voice Monkey an HTTP request, which triggers an action of your choice. Use them to fire announcements, trigger routines or start Flows from anything that can make an HTTP call — IFTTT, Home Assistant, Flic, custom code, etc.

The feature is called “inbound” because the request comes into Voice Monkey. (Outbound calls — where Voice Monkey makes HTTP requests out to other services — are handled by the Web Request node in Flows.)

  1. In the console, go to Inbound Webhooks and click Create Inbound Webhook.
  2. Give it a name. As you type, the form shows the slug that will be used in {WEBHOOK.<slug>.<key>} references (e.g. Front Door → FrontDoor).
  3. Add one or more actions to fire when the webhook is hit:
    • Announcement — make a TTS announcement on an Alexa speaker, in an Alexa voice or one of your own voices, and/or show one of your Screens on it. Payload values work inside the screen too.
    • Routine Trigger — trigger a Voice Monkey Routine Trigger device (which in turn fires an Alexa Routine).
    • Flow — start a Flow (the inbound webhook is recorded as the source in the activity log).
  4. Click Create Inbound Webhook to save. You’ll be taken to the edit page where you can copy the unique webhook URL.

Send a POST or PUT request to the URL. The body fields are stored against the webhook so you can reference them in actions and Flows.

Terminal window
curl -X POST https://api-v3.voicemonkey.io/catch/USER_ID/WEBHOOK_TOKEN \
-H "Content-Type: application/json" \
-d '{"room":"living room","status":"motion"}'

JSON, application/x-www-form-urlencoded and multipart/form-data bodies are all supported, as are query-string parameters (?room=kitchen). A request with no body still fires the actions; the payload simply stays empty.

Reference payload values with {WEBHOOK.<slug>.<key>} in any speech text, action parameter or Flow node.

Motion detected in {WEBHOOK.FrontDoor.room}

The slug is the webhook’s name converted to PascalCase — e.g. a webhook named Front Door has slug FrontDoor. The console shows the exact slug on the Inbound Webhooks list and on the edit page, right under the Name field.

Every inbound webhook also shows a Recent Payload panel listing the keys from the most recent request, each with a one-click copy for its full variable reference. Hit Refresh to fetch the latest data after firing a test request.

The same {WEBHOOK.<slug>.<key>} syntax works everywhere — inside a webhook’s own actions it resolves against the current request; anywhere else (Flows, the Announcement API) it resolves against the most recent stored payload.

Announcement actions also fill in your variables ({NAME}) and built-in variables such as {VM.TIME.TEXT12}:

Motion in the {WEBHOOK.FrontDoor.room} at {VM.TIME.TEXT12}

Any payload field or query-string parameter named var-<NAME> is saved as a variable before the actions run, so the actions (and any Flow they start) see the new value:

Terminal window
curl -X POST "https://api-v3.voicemonkey.io/catch/USER_ID/WEBHOOK_TOKEN?var-GARAGE_STATUS=open"

The response includes a variableUpdates array showing what was created or updated, and any names that were rejected. The usual name rules and plan limits apply.

  • Request body: max 64 KiB. Larger bodies are rejected with a 413 before they’re parsed.
  • Stored payload: capped at 8 KiB per webhook with individual values truncated at 512 characters. Actions read the stored payload, so the same cap applies to {WEBHOOK.<slug>.<key>} values in a webhook’s own announcement text and in Flows.
  • Free: 2 inbound webhooks.
  • Hobby: 10 inbound webhooks.
  • Ultimate: unlimited inbound webhooks.