Start with a confirmation that cannot move anything
Home Assistant actionable notifications add buttons to phone messages. For a simple “shall I turn on the reading lamp?” question, use a script that sends the prompt, waits briefly for its matching answer, and performs the action only on Yes. A script is a saved sequence of steps; it can run from a dashboard or an automation.
Begin with the practice version below. It turns on a Toggle helper—a software on/off switch inside Home Assistant—so an incorrect tap cannot operate a real device. Once Yes, No and expiry behave as expected, change its final action to your lamp. You need Home Assistant, its official Companion App, and a working phone-specific notification action. This walkthrough uses the script editor and YAML, the indented text format for those steps.
Choose a button that performs an action when the answer should change something. Choose a navigation button when you only want to open a dashboard. Those are separate behaviors in the Companion button documentation.
Research method: researched from current Home Assistant and Companion App documentation on September 14, 2026. The example was checked for YAML syntax and template outcomes; it was not run on a Home Assistant installation or tested on physical phones or lamps. The cover is an AI-generated residential illustration.
1. Confirm the phone and create the practice switch
- Open the Companion App and allow notifications. In Home Assistant, go to Settings → Tools → Actions. Older versions call this Developer tools → Actions.
- Find your exact
notify.mobile_app_…action and send a plain message such as “Notification practice.” Copy its full name. Use that name in both phone-action lines below. This example follows the Companion App payload format; do not substitute the genericnotify.notifyaction. - Go to Settings → Devices & services → Helpers → Create helper → Toggle. Name it “Notification test.” Open its settings and copy its entity ID—the internal name Home Assistant uses, such as
input_boolean.notification_test. Replace the example ID if yours differs. - Leave the new helper Off. Keep its control open in another tab or on your dashboard so you can see the result.
The Tools guide explains the testing interface, and the Toggle helper documentation covers the practice switch. If the plain message fails, use the phone notification delivery checklist before adding buttons.
2. Save one complete Yes/No script
Open Settings → Automations & scenes → Scripts, create a new script, and use its menu to Edit in YAML. Replace the new script's contents with the following. Paste it into a single script's editor, without a surrounding script: key; it is not a complete configuration.yaml file.
Replace notify.mobile_app_your_phone in both places and check the helper ID at the end. Preserve the indentation, straight quotation marks and double braces. The code boxes scroll sideways on small screens; copy the whole block. Save the script, then run it once.
alias: Notification confirmation practice
mode: single
sequence:
- variables:
yes_action: "{{ 'TARA_PRACTICE_YES_' ~ context.id }}"
no_action: "{{ 'TARA_PRACTICE_NO_' ~ context.id }}"
prompt_tag: "{{ 'tara_practice_' ~ context.id }}"
- action: notify.mobile_app_your_phone
data:
title: "Home Assistant practice"
message: "Turn on the test helper? Reply within five minutes."
data:
tag: "{{ prompt_tag }}"
actions:
- action: "{{ yes_action }}"
title: "Yes, run test"
authenticationRequired: true
- action: "{{ no_action }}"
title: "No, leave it"
- wait_for_trigger:
- trigger: event
event_type: mobile_app_notification_action
event_data:
action: "{{ yes_action }}"
- trigger: event
event_type: mobile_app_notification_action
event_data:
action: "{{ no_action }}"
timeout: "00:05:00"
continue_on_timeout: true
- alias: "Try to remove this prompt"
action: notify.mobile_app_your_phone
continue_on_error: true
data:
message: clear_notification
data:
tag: "{{ prompt_tag }}"
- if:
- condition: template
value_template: >-
{{ wait.trigger is not none
and wait.trigger.event.data.action == yes_action }}
then:
- action: input_boolean.turn_on
target:
entity_id: input_boolean.notification_test
The inner data.actions list supplies the button labels. Each response ID is a name used internally to match a button to its question; context.id supplies this run’s identifier. A tap returns a mobile_app_notification_action event—a message inside Home Assistant—containing the selected identifier. The script listens only for this request's identifiers. This follows the documented response-matching pattern.
The if block is the permission check. After a timeout, wait.trigger is empty, so the test action is skipped. continue_on_timeout: true lets the script reach cleanup; it does not mean “assume Yes.” See the script wait result.
mode: single keeps this practice script to one active run. Running it again while it waits does not send another question. The script modes reference describes that behavior.
3. Check Yes, No and an expired prompt
Use the checks in order, resetting the helper to Off before each new run. On iPhone, touch and hold the notification to reveal its actions. On Android, expand the notification if the buttons are hidden. Select the labeled button; tapping the message body is not the same as answering Yes.
- Yes: run the script and select “Yes, run test.” Unlock the phone if asked. Confirm that the helper becomes On.
- No: turn the helper Off, run a fresh prompt and select “No, leave it.” Confirm that the helper stays Off.
- No answer: run again and leave the prompt alone for more than five minutes. The helper should stay Off and the script should finish. The waiting period starts in Home Assistant, after it sends the notification; delayed phone delivery reduces the time available to reply.
- Late or old answer: if an expired notification is still visible, tap Yes on it. It should not change the helper. Run a fresh prompt and check that its own Yes still works.
- Busy script: while a fresh prompt waits, run the script again. Expect no second question. Finish the first with No before continuing.
The script attempts to remove the prompt using its tag. Removal is best effort: phone operating-system restrictions can leave a message visible. The clearing documentation describes those limits. Once the script stops waiting, the old response cannot run its action, even if the message remains visible.
Worked example: ask before lighting the reading corner
After the practice checks pass, change the message to “Turn on the reading lamp? Reply within five minutes,” and the Yes label to “Yes, turn it on.” Replace only the final helper action with the following, using a lamp you already control successfully in Home Assistant:
- action: light.turn_on
target:
entity_id: light.reading_lampKeep the existing then: line and everything above it. An entity ID beginning with light. needs the light action; a lamp connected through a switch. entity needs switch.turn_on and that switch's ID. Check your actual entity rather than changing only the name. The Light integration documents the light action.
For a first household trial, run the adapted script yourself around reading time. Later, select this saved script as an action in a suitable automation. Name it “Ask about the reading lamp” so another household member understands that it sends a question.
Here is the intended behavior if the waiting step begins at 8:00 pm. These are illustrative outcomes derived from the configuration, not measured delivery times.
Scroll sideways to compare the situations on a small screen.
| Situation | What this script does | Household meaning |
|---|---|---|
| Yes reaches Home Assistant at 8:02 | Runs the lamp's turn-on action once, then finishes. | You agreed while this prompt was active. Confirm the lamp actually responded. |
| No arrives at 8:02 | Ends without sending any lamp command. | “No” leaves the lamp as it is; it does not turn it off. |
| No answer arrives before 8:05 | Expires and skips the lamp command. | Silence means no change. |
| An old Yes arrives at 8:07 while a fresh prompt waits | The fresh run ignores the old response ID. | A previous question cannot approve this later one. |
| Home Assistant restarts at 8:03 | The pending run ends; its remaining wait is not resumed. | Request a new prompt after Home Assistant returns. |
The last row is why this confirmation should not be used to keep unfinished tasks across restarts. A response already processed before a restart may already have operated the lamp; restarting does not undo it. If you need reminders that keep repeating until acknowledged, use the separate repeating reminder guide.
When a button does nothing
- Check whether this prompt is still active. Open the script's trace, Home Assistant's record of its steps. An expired, stopped or interrupted run needs a fresh request.
- Check the return event. In Settings → Tools → Events, start listening to
mobile_app_notification_action, then answer a fresh prompt. Stop listening when finished. If no event appears, check that the phone can open this Home Assistant server on its current network. - If the event arrives, compare its action ID. It must match this run's
yes_actionorno_actionin the trace. Another prompt's event should be ignored. - If the Yes branch runs, check the final action. Verify the helper or lamp ID and look for an action error in the trace. Successful event matching is not proof that a device responded.
For an away-from-home trial, switch the phone to mobile data, confirm you can open Home Assistant through your existing secure remote connection, and repeat the helper test. A received push alone does not test that return route. See the remote-access options if you need to configure it.
Keep the question easy to trust
Use this pattern for optional, reversible choices. Keep normal physical controls available. Do not adapt the practice script into an unattended door opener, alarm-disarming control or heating safety system: it does not verify who is in the room, whether movement is safe, or whether a device reached the requested state.
The Yes button requests phone authentication. The Companion documentation lists support on iOS and Android 12 or later; this setting is not a substitute for a secured phone and appropriate account access. Keep private household details out of lock-screen message text.
Tara's recommendation is to begin with one low-stakes question at a useful moment and make “No” mean exactly what it says. A configured home automation kit with household routines should make these choices understandable to everyone using the home.
Other practical questions
Is this fully local?
The script runs on your Home Assistant server. Ordinary mobile push uses outside delivery services. Companion Local Push can deliver over a supported active local connection, with platform-specific requirements. Test both delivery and the answer during an internet outage before depending on that path.
Can the button just open a dashboard?
Yes. Use a button with action: URI and a uri pointing to your dashboard view. That is navigation, so it does not need the Yes/No wait shown here. Copy your view's real path rather than assuming every dashboard uses /lovelace/.
Does swiping away or snoozing the message count as No?
Not in this script. It waits for the two defined button events or its timeout. Swiping away does not send the configured No response, and snoozing the phone message does not extend the script's five-minute wait. Use a fresh prompt when you are ready to answer.
