Skip to content

HTTP Actions

HTTP Actions let you fire any HTTP/REST request you define — a webhook, a smart-home API, a self-hosted script — straight from a watch tile, a Quick Menu, or Siri. The request runs in-app: no jump to Shortcuts, no app switch, no Home Assistant round-trip. Tap, get a haptic, done.

An HTTP Action is a reusable, named request you build once and reference anywhere. The watch fires it; you can even pull a value out of the reply and show it on the tile like a sensor.

  • Hit a webhook — fire a Node-RED, n8n, or IFTTT webhook with a tap.
  • Call a non-HA service — anything that speaks HTTP, including a box your Home Assistant doesn’t manage.
  • Run a self-hosted script — POST to your own server behind a private CA or mutual TLS.
  • Read a value back — pull a price, a temperature, or a status line out of the reply and pin it on the tile.

The free tier includes exactly one HTTP Action — enough to wire up your most-used request. Creating a second one (via New or Duplicate) is a Pro feature, behind the Unlock Unlimited HTTP Actions paywall. Buy Pro and the locked buttons unlock live, no restart needed.

Open the editor for an action and set:

  • Name — shown in pickers and used as the default tile label.
  • MethodGET, POST, PUT, PATCH, or DELETE.
  • URLhttp:// or https:// only. A space or a stray % typed straight into the URL is percent-encoded for you, so you don’t have to hand-encode a query.
  • Headers — an ordered list (order and duplicates are preserved).
  • Body — only on body-carrying verbs (POST/PUT/PATCH/DELETE). GET hides the Body section.
  • Body typeNone, JSON, Form, or Text. The app sets the matching Content-Type (application/json, application/x-www-form-urlencoded, or text/plain) automatically — unless you set a Content-Type header yourself.
  • Timeout — request deadline in seconds (defaults to 10).

The editor’s tabs are Request (timeout, headers, body, variables), Auth (authentication and TLS), and Output (reply value extraction and the inline Test).

The Auth tab has an Authentication card that composes a header for you — Bearer Token, Username & Password (Basic), or API Key Header. Whatever you choose is saved as an ordinary header, so it inherits the same encryption, backup stripping, and watch sync as everything else.

Each action can carry a custom icon and color.

Every editor has a Test button (on the Output tab) that fires the real request from the phone and shows you the status, the reply, and the extracted value — so you debug your setup on the phone, never by squinting at watch toasts. If the action has variables, Test prompts you for them first.

Don’t want to type a request out by hand? Tap Import cURL and paste a curl command — from API docs or a browser’s Copy as cURL menu — and the method, URL, headers, body, and basic auth (-u) all fill in.

The importer models the flags people actually copy. Transport-only flags it can’t honor on-device — -k (insecure), -L (follow redirects), -s (silent), -v, -i, and friends — are silently dropped. A -d/--data flag implies POST; -G forces GET and folds data into the query. A @file body is skipped (the file can’t be read on-device), but you still get a POST skeleton to complete.

In the editor, add an HTTP Action tile and pick the action from the HTTP Actions picker. The tile only references the action — the request itself lives in your library — so editing the action in one place updates every tile that points at it.

If you delete an action, any tile still pointing at it shows a warning and stops firing (a failure haptic, no silent no-op). Re-point the tile at a live action to fix it.

Drop a {{name}} token into the URL, a header, or the body and it becomes an input variable — a value you’re prompted for each time the action fires. The editor keeps the variable list in sync with the tokens you type. Each variable has a kind:

  • Text — escaped safely wherever it lands (percent-encoded in a URL, JSON-escaped inside a JSON body, CR/LF-stripped in a header).
  • Number — injected unquoted in a JSON body when it’s a valid number (so {"brightness": 100}, not "100").

Give a variable a list of quick values and they appear as tappable suggestions at fire time, so you usually tap instead of type.

Flip Quick values only and fire time skips the keyboard, dictation, and scribble entirely — you get a clean full-screen tappable list of just your quick values. It auto-enables the first time you add a quick value to a variable. If you later remove every quick value, the flag goes inert and the variable falls back to a normal typed prompt rather than dead-ending the action.

The editor also offers an inline {{ picker so you can insert a token (or a global) without typing the braces.

A global variable is a library-level {{name}} constant you set once and reuse across every action — perfect for a base URL or an API host. Change {{haurl}} in one place and every action that references it follows.

Globals and input variables share the {{name}} syntax; they’re told apart by name, not by brace count:

  • A {{name}} that matches a defined global expands to that global’s fixed value before the request is built.
  • Any other {{name}} prompts at fire time.
  • A global therefore wins over a same-named prompt — define a global message and an action’s {{message}} stops asking.

On the Output tab, turn on extraction by picking a Source other than None, and the app pulls one value out of a successful reply. Choose from:

  • JSON Field — a simple dot-path into the JSON reply. Dictionary segments are keys; a bare integer indexes an array, so data.0.temp reaches the first array element’s temp. An empty path returns the whole body.
  • Regex Capture — pulls a value out of any text reply (JSON, XML, HTML, plain text, logs). Returns capture group 1 when your pattern declares one, else the whole match — there’s no group picker. The dot matches across newlines.
  • Status Code — the HTTP status as the value.
  • Body Text — a one-line snippet of the response body.
  • Response Header — read a named header. The lookup is case-insensitive.

An optional Unit suffix is appended to the value exactly as you type it. The leading space in " W" is intentional — it’s how you put a gap between the number and the unit.

Where the reply appears is a per-tile choice, set in the editor — while the extraction itself lives on the action, so two tiles firing the same request can display it differently:

  • Banner — the value flashes in the bottom banner after each fire (or the raw body snippet, if the action has no extraction).
  • Tile Value — the extracted value is pinned on the tile like a sensor reading. This needs the action to have an extraction configured. A user-initiated tap or pull flashes the tile green on success; if the last fire failed, the tile flags the held value as stale.

Pick Tile Value and the tile drops its icon, handing the whole face to the extracted value — a price, a temperature, a status line shown like a built-in sensor. The unit from the action’s Reply Value is already appended.

Each Tile Value tile carries its own look, set under the display picker in the editor:

  • Show Name — captions the value with the tile’s name, so a glance reads “humidity 55” instead of a bare “55”. On by default; turn it off for a pure big-number look.
  • Text Size6–36 pt, or Auto (scales with the tile’s icon size). Drag to pin a size; tap Auto to clear it.
  • Lines — cap how many lines the value may wrap to (1–8), or Auto (grows with the tile’s row span).
  • Line Spacing — extra points between wrapped lines, Default up to +12 pt.
  • Vertical Position — nudge the value Up or Down (±20 pt) from Center.
  • Text Color — a theme swatch or a custom color; Reset returns to the default.

A Tile Value normally only changes when you tap the tile. Auto-Refresh lets it keep itself current while you’re looking at it. It’s one escalating ladder — pick a single rung:

  • Off — only re-fires on tap (the default).
  • On Open — re-fires once each time you swipe to the tile’s page.
  • 1s / 3s / 5s / 10s / 30s — keeps polling on a timer so the value ticks like a live sensor.

A separate Refresh on Pull toggle re-fires whenever you pull-to-refresh the page — an explicit refresh, independent of the ladder.

The tile tells you whether the number you’re seeing is trustworthy:

  • Green pulse — a tap or pull just reloaded the value successfully. It’s the “it worked” cue even when the refreshed number is unchanged. Silent timer and on-open refreshes do not pulse — a polling tile never strobes green every tick.
  • Red exclamation + dimmed value — the last fire failed (a non-2xx, a transport error, or a request that wouldn’t build), so the value on screen is the last good one, now flagged stale. A later successful fire clears the flag.

The same action runs from every surface:

  • Standalone tile — tap the HTTP Action tile.
  • Quick Menu slots — assign Run HTTP Action to a slot in an Entity, Universal, or per-entity Quick Menu.
  • Hold-and-slide — point any tile’s press-and-slide direction at an HTTP Action.
  • Widgets & complications — fire from a complication or widget.
  • Siri & Shortcuts — use the Run HTTP Action Shortcuts action.

Variable handling differs by surface:

  • Tile, Quick Menu, hold-and-slide — prompt for any variables at fire time (or show the quick-value list). An action whose tokens are all globals fires immediately.
  • Widgets & complications — a variable-free action direct-fires from the widget with no app launch. An action with variables opens the watch app to prompt, then fires.
  • Siri & Shortcuts — substitutes preset (or empty) values; it never prompts.

The Shortcuts action is Run HTTP Action (Wrist Assistant). It returns the extracted reply value, so a Shortcut can chain the result into the next step. There is no spoken Siri phrase — build the shortcut manually in the Shortcuts app, then run it however you like.

For a self-hosted endpoint, the Auth tab has two independent, per-action TLS opt-ins, both off by default and both scoped to that action’s own host (never sent to a host it might redirect to):

  • Allow self-signed certificate — accept an untrusted server certificate (self-signed or private CA) for this action’s host. Loosens trust in the server’s certificate only.
  • Send client certificate — present the app’s imported mutual-TLS identity when firing this action — for a server behind mTLS or Cloudflare Access. This option only appears once you’ve imported a certificate in Credentials.
  • Requests are stored in the device Keychain (encrypted at rest) and synced to the watch over the encrypted Watch Connectivity link.
  • The request details (URL, headers, body) and any global values are excluded from plaintext backups — they ride only the encrypted backup envelope. After a plaintext-only restore, an action comes back as a “Needs setup” skeleton for you to re-supply.
  • HTTP Actions never present Home Assistant’s own mTLS client certificate to an arbitrary endpoint — the identity is offered only when you turn on Send client certificate for that specific action.