OpenClaw iOS app: Gateway pairing, node capabilities, and fixes

Set up the OpenClaw iPhone and iPad app, pair it with a Gateway, and use node capabilities like screen snapshot, camera, and Talk mode. Includes troubleshooting for common issues.

Read this when

  • Pairing or reconnecting the iOS node
  • Starting live voice with Siri or Shortcuts
  • Using voice input and spoken replies on Apple Watch
  • Setting up standalone Apple Watch voice
  • Enabling or troubleshooting the direct Apple Watch node
  • Running the iOS app from source
  • Debugging Gateway discovery or iOS node commands
  • Choosing colors for native chat sessions
  • Snoozing or waking a session

Availability: The official iPhone app is distributed through the App Store. You can also run local development builds from source.

The app needs iOS 26.2 or iPadOS 26.2 or newer.

What it does

  • Talks to a Gateway over WebSocket (LAN or tailnet).
  • Provides node capabilities: Screen snapshot, Camera capture, Location, Talk mode, Voice wake, and opt-in Health summaries.
  • Accepts node.invoke commands and emits node status events.
  • From the Agents surface (Files), browses the selected agent's workspace in read-only mode: directory drill-down, syntax-highlighted text previews, image previews, and share-sheet export. Writes are not possible; the Gateway caps preview sizes.
  • Maintains a small read-only offline cache of recent chat sessions and transcripts for each paired Gateway: cold opens paint the last known transcript right away and refresh once the Gateway answers, recent chats remain browsable while disconnected, and reset/forget wipes the protected local cache.
  • Holds text messages sent while disconnected in a durable per-gateway outbox (up to 50): queued bubbles appear in the transcript, flush in order on reconnect without duplicating sends on retries, stay durable until saved history confirms the send, retry with backoff before showing a retry/delete action, and expire rather than send after 48 hours offline; reset/forget clears the queue along with the cache.
  • Send text while a reply is running: tapping Send follows the Gateway's configured queue mode, and /steer behaves as a normal slash command. Touch and hold Send to apply the opposite action to that message: Steer now when the default is Queue, or Queue next when it is Steer. Both options show if the Gateway uses a different mode or does not report its default. The follow-up appears at once with its delivery status while the current reply keeps streaming. A menu choice survives reconnect and leaves the session default unchanged. Attachments and local session reset/compact commands still wait for the current reply to finish.
  • Chat is the one place for text and voice. Chat actions can open the full Sessions screen without leaving Chat and can show or hide assistant reasoning and tool activity. Tap the microphone for draft dictation, open its menu to record a voice note, or use the inline Talk control for realtime voice; while listening or speaking, the Talk control animates from live microphone or playback level.
  • Assistant reasoning shows only when /reasoning on is set and the local Show reasoning & tool activity setting is on. /reasoning off hides it after history reload and relaunch. Tool activity follows the local setting on its own.
  • Sessions offers Active, Snoozed, Automations, and Archived scopes. Snoozed sessions stay out of the active sidebar and Overview until they wake.
  • Agent narration appears inline as each segment finishes, including after reconnect. Narration, tool activity, and the reply stay grouped in one response. Compact-width layouts hide the assistant avatar to leave more room for text; regular-width layouts keep a single top-aligned avatar. Completed standalone bubbles use sender-side tails where the avatar is hidden, and accessible reply containers keep the assistant's name. On iPhone and iPad, completed chat turns fold earlier work into a Worked for … disclosure above the reply. Tap it to inspect the work. Final answers and media stay visible, and active or unanswered work stays expanded.
  • Chat takes images from the photo picker, camera, Files, paste, and the iOS share sheet. Assistant-generated images render inline from short-lived Gateway artifact URLs, open in a full-screen preview, and remain available after reconnect or history reload without storing image bytes in the transcript cache.
  • Pick + → File to attach audio, video, PDFs, text/code, CSV, JSON, Markdown, ZIP archives, and Office documents from Files. Removable chips show filenames and sizes. Files obey the Gateway's advertised attachment size limits and keep their original bytes through the durable outbox. The file limit also caps total attachment bytes per message, counting images after resizing; oversized drafts stay in the composer when you try to send. For older Gateways that do not advertise limits, native chat caps non-image files and the combined attachment budget at 19,464,192 bytes (the decoded budget for a 25 MiB frame), and processed images at 5 MB after resizing. Image source reads have a separate 64 MiB cap to bound resize-input memory; a larger source photo within that cap can be sent when its resized JPEG fits the image and batch budgets. Empty or unreadable files show Could not attach; oversized files show Too large to send. Sent uploads remain visible after history refresh; downloading inbound uploads from native history is not supported yet. Recorded voice notes keep their separate recording flow.
  • Assistant file attachments offer a Download file action. Tap it to fetch the managed file and open the system share sheet, where you can pick Save to Files or another app. Downloads use the current Gateway connection and its scoped artifact access; a file that has expired or been removed must be sent again. Documents are limited to 100 MB.
  • Dictation shows when it is starting and listening, a live microphone waveform, and the words recognized so far. Tap Done to add the transcript to your draft or Cancel to discard it. Attachments show Preparing attachments… while loading and Sending attachments… during delivery; failed photo loads show an error so you can select them again.
  • Keeps Markdown paragraph breaks, including before lists and while responses are streaming.
  • Renders completed Mermaid code fences as inline diagrams, with source/copy controls and a full-screen zoomable preview. Diagram rendering relies on bundled assets and works offline.
  • Long-press a message or open its actions menu and choose Select Text to select and copy any span in a native text view; code fences show a copy button that copies the raw code.
  • Settings opens the Dashboard settings pages when connected with operator.admin; the native Gateway screen remains available for connection and pairing.
  • Speaks assistant messages on demand: long-press a message in Chat and choose Listen. The app plays supported Gateway tts.speak clips with the configured TTS provider and falls back to on-device speech when Gateway audio is unavailable or unplayable. Playback stops on session switch or backgrounding.

Chat text size

Chat uses a 13.5-point base text size for a denser transcript. It still follows your system or per-app Dynamic Type setting, including accessibility text sizes. At the same setting, this makes chat text smaller than the previous 17-point base; raise the app's text size in iOS Settings if you want larger text.

At accessibility text sizes, the composer shows a model icon rather than a cramped model name. Its accessibility label and value still identify the selected model. Icon glyphs stay within their controls while chat text continues to scale.

Model sign-in

Open the model menu in the chat composer and choose Model sign-in. The menu stays available during a response, while session settings are saving, and when no models are listed. Model choices still respect their existing permission and busy-state restrictions; opening sign-in does not grant permission to change them.

When the selected model cannot send because its credentials are missing or invalid, a Model sign-in link also appears beside the composer. The link stays available when camera or voice-note capture replaces the model menu. Provider authentication and Gateway permissions are unchanged.

Settings

Open Settings in the sidebar to use the same Dashboard settings pages as the web and macOS apps. A connected operator session with operator.admin is required. The toolbar's Gateway button opens the native connection screen, including setup, paired Gateways, manual connection, and advanced connection options. The sidebar footer also provides Gateway access: Add Gateway when none are saved, a direct connection-settings button when one is saved, and a quick picker when multiple Gateways are saved. The picker keeps saved Gateways available even when they are offline and includes a management action for setup and pairing. Selection identifies the focused Gateway, not whether it is connected. Finish recording or delivering attachments and send or clear the current draft before using the quick picker. It does not move drafts to another Gateway. Approvals opens the native approval inbox and shows the pending count.

A badge next to a native sidebar session indicates whether the oldest request still pending is a question or an approval. Tapping it reveals a short preview along with a count of further requests of the same type. Session totals are summarized by the agent and section headings, and those totals include requests that fall outside the visible recent-session list. You can tap a badge, activate it with a keyboard, or have VoiceOver read the details, all without leaving the current chat. Questions remain reachable even after you navigate away from Chat. Requests that are completed, cancelled, or expired vanish from these previews, and answer drafts plus credential drafts are never shown. Approvals for Gateway administration open the existing Dashboard review page, whereas native exec and plugin approvals keep the actions they already had.

The Gateway has to serve Dashboard pages that the companion iOS app can work with. Should a loaded Settings page not report that support, a native banner prompts you to update the Gateway. Open Gateway takes you to the native connection screen, and Gateway setup and pairing stay available there. The offline Device section likewise stays usable even without Dashboard support.

Instead of handing embedded Dashboard pages the app's private device key or a stored device grant in their startup script, those pages request native signatures. As the Gateway protocol requires, the connection response may carry a device token in memory; the native authentication path never writes it to page storage.

Appearance, notification delivery, camera access, keep-awake behavior, and optional Health summaries all live on the This iPhone or This iPad page. Notification, camera, microphone, speech, location, contacts, calendars, reminders, and photo access are listed on its Permissions page. Native iOS prompts handle permission requests; Precise Location displays the system's current state and links out to iOS Settings. This device's Voice Wake, Talk, Talk control, background listening, and speakerphone settings sit on the Dashboard Talk page. Before Voice Wake, camera access, Health summaries, or Always location can be turned on, a native confirmation is requested first.

Provider, voice, and speech language are owned by the Gateway's Talk configuration. Overrides saved on iOS no longer take effect, and the retired app speech-language preference is cleared at startup. The default share instruction is retired as well and cleared at startup. Only an instruction supplied explicitly for a given share is included in share messages. None of this removes the Gateway's talk.speechLocale option.

Native Apple Watch, Diagnostics, Licenses, and About screens are also opened from This iPhone and This iPad. In three situations, disconnected, connected without admin access, or running in demo or screenshot mode, Settings presents a native fallback: the Gateway connection controls, then those four rows, under a Device section. Loading the Dashboard is not needed for the connection or for these device screens.

The Dashboard is where Channels (/settings/channels) and Skills (/skills) are managed. Appearance, notifications, privacy, permissions, and Voice & Talk settings likewise rely on the Dashboard pages; the separate native settings screens and the system-agent settings chat are gone. Agent selection and read-only Files browsing are still native.

Without web navigation chrome, the sidebar loads these Gateway pages into the embedded Dashboard:

Sidebar destinationDashboard path
Activity/activity
Workboard/workboard
Skill Workshop/skills/workshop
Instances/settings/devices
Dreaming/settings/memory/dreams
Usage/usage
Automations/automations

Settings and these pages both need the same connected operator.admin session. Lacking that access, they display the native Gateway connection guidance. Devices is what Instances opens: the Dashboard's owner of paired nodes and connected clients.

Configured names or agent IDs appear in the native New Thread agent picker as soon as the roster arrives. Each choice is updated with resolved identities without holding up selection; configured names take precedence, and Assistant is the Gateway's default identity. Opening the picker refreshes the catalog, which stays bound to the selected Gateway.

Cloudflare Access sign-in

Should a Gateway URL or setup code run into a Cloudflare Access sign-in challenge, tap Connect to sign in to the Gateway website in the system browser inside OpenClaw. Finish the Access sign-in, then tap Done. To authorize the app connection and complete any Access approval, choose Continue. Only after you choose Continue does the app begin its encrypted session transfer. Once the app verifies the returned session, the browser closes and normal Gateway pairing resumes. When the connection check already succeeds, existing Gateway credentials, service headers, and WARP connections keep working with no extra prompt.

This browser carries its own app session. Being signed in with Safari does not mean you are signed in here. Authorizing the native connection takes more than a website sign-in. Tap Cancel to stop; to try again, use Sign in in the native Gateway settings. A return from the background never launches a browser on its own.

Connections pause if Access expires or is revoked, and Gateway settings then asks you to sign in again. Your Gateway pairing and device keys stay saved. Signing out of Access deletes the shared grant for that host and closes any connections that use that Access session. The sign-out control tracks the focused saved Gateway rather than the manual credential editor. Above the button, Access Host displays the full, selectable origin of the shared session that will be removed. Access status and sign-in guidance likewise follow the focused profile, so a sign-out message belonging to another profile will not show up next to a valid session. Gateways that use their own service headers remain connected. Your identity-provider session may persist in the browser; that does not sign you out of the provider. Forget Gateway deletes a single profile and its active work. Access sessions of other profiles on the same host are kept; forgetting the last profile also deletes that grant. If a setup code expires while you are signing in, scan a fresh one. A setup code that is invalid or already used counts as a Gateway pairing error and calls for no new Access login.

Native pairing, chat, and authenticated media rely on the Access session. Embedded Dashboard pages and widgets show an explanation, with native Gateway settings reachable; support for browser sessions on those surfaces is handled separately. For an Access-protected Gateway, the share extension instructs you to send from OpenClaw. Access credentials are never exported to Apple Watch or to cloud workers.

Sessions

Pick All Sessions… in the sidebar to browse sessions under Active, Snoozed, Automations, or Archived. Sessions created by automations are kept out of ordinary browsing, pinned rows included, unless you select them. Their transcripts are found by opening Automations; sidebar search also returns matching automation sessions. Pins you saved are kept.

Long-press a session that qualifies and pick Snooze: In 1 hour, In 3 hours, This evening (18:00 local, offered only when more than one hour away), Tomorrow (09:00 on the next calendar day), or Next week (next Monday at 09:00). Next week is omitted on Sundays because it would match Tomorrow. The local wake time is displayed for every preset.

The Snoozed scope displays Wakes together with the scheduled time. To bring a snoozed row back early, long-press it and pick Wake session. A session also wakes at its deadline, on arrival of a real inbound message, or when an agent run finishes. Pinning or archiving a session clears its snooze. Snoozing is not possible for protected main sessions, child/subagent sessions, or archived sessions.

Snoozed sessions held in cache can still be browsed offline under the Snoozed scope.

A snooze only hides a session from active lists. It does not stop a run, block messages, or turn off automations. Because the wake time is stored by the Gateway, it is shared among connected clients; a conversation that is open stays open.

Session colors

To reach a session's actions, long-press it in the sidebar or on the Sessions screen, then pick Color. Choose from red, blue, green, yellow, purple, orange, pink, or cyan. Default removes the color.

Sessions with a color assigned get a slim stripe at the leading edge in session lists, plus a small dot next to the title in Chat. No marker appears when no color is set. Color names, rather than hex values, are what the Gateway keeps; the app shifts their hues to suit light and dark appearances.

Reactions

Emoji reaction chips appear on saved prompts and assistant replies, showing counts and reactor names for VoiceOver. Tapping a chip toggles your own reaction, and long-pressing a message then picking Add Reaction opens the quick palette. One typed or pasted emoji is accepted through More…. While the session stays open, reactions refresh live and generate no notifications. Whether reaction controls appear depends on the methods the Gateway advertises, operator scopes, the session cap, and the current sharing role; view-only sessions display the chips but no reaction controls. Reactions are unavailable in archived sessions and catalog sessions.

Message times and models

For completed message groups, relative time is shown for the past week, while older messages get a compact local date, with usage displayed too when it is available. VoiceOver announces the exact date, time, and time zone. When the originating model is known, assistant replies display the model recorded at the time; picking a different model leaves older replies untouched. These footers are not added to streaming text, commentary, or tool activity.

Sources in chat

Up to eight compact Sources cards are shown on completed answers, one per cited page that web search or web fetch returned during that answer's run. Reading the recorded Search snippet or Page excerpt takes a tap on a card, after which Open source visits the page. When no excerpt was recorded, the card states that. The preview never fetches the page again.

Icons for sources obey the Gateway's automatic favicon preference and come from the Gateway's authenticated favicon service. If icons are turned off or cannot be loaded, a globe is shown instead. Link cards for session links and GitHub issue or pull request links stay as they are.

Diagrams in chat

Diagrams are displayed by writing a fenced mermaid block. A diagram appears once its closing fence arrives or the response ends; a fence still streaming stays readable as code. Code fences of the ordinary kind keep their normal presentation.

Tapping the diagram opens a full-screen preview that supports pinch-to-zoom. The corner menu switches between the diagram and its source, and the copy button copies the full source. Should rendering fail, the source is still available; transient failures offer Retry diagram.

Bundled renderer output is produced by local source builds during pnpm ios:gen. Before generating the Xcode project, run pnpm install from the repository root so the pinned renderer dependencies are in place.

Requirements

  • A Gateway running on a different device (macOS, Linux, or Windows through WSL2).
  • The network path, one of:
    • The same LAN over Bonjour, or
    • A tailnet over unicast DNS-SD (example domain: openclaw.internal.), or
    • A manual host/port as a fallback.

Quick start (pair + connect)

A short pairing explainer comes first on launch, followed by Gateway setup. No aggregate permissions page is shown. Optional access is requested either at the moment you use the related feature or via Settings -> This iPhone (This iPad on iPad) -> Permissions. The native iOS authorization prompt appears when a permission is requested. Granted access can be revised afterward in the iOS Settings app.

  1. Bring up an authenticated Gateway whose route your phone can reach. For remote access, Tailscale Serve is the recommended option:
openclaw gateway --port 18789 --tailscale serve

On a trusted same-LAN setup, an authenticated gateway.bind: "lan" is the alternative. A phone cannot reach the default loopback bind. When the Gateway is not configured yet, run openclaw onboard first, so that setup-code creation has a token or password auth path.

  1. Open the Control UI, go to Nodes, and on the Devices page click Pair device. Full access is the recommended choice and is selected by default; pick Limited access only if you want to leave out administrative Gateway controls, then click Create setup code.

  2. In the iOS app, go to Settings -> Gateway, then scan the QR code (or paste the setup code) and connect. Use a mobile setup code from Control UI or openclaw qr, not a gateway join URL from openclaw devices join-code.

    Paired Gateways stay listed under Gateways. The focused Gateway is marked with the checkmark; to keep another row's operator session connected at the same time, use the bolt control on that row. Changing focus leaves other enabled Gateways connected. The iPhone's capability-bearing node session goes only to the focused Gateway, so camera, screen, location, and other device commands always have a single clear owner. Once the app moves to the background, iOS may suspend these foreground connections.

  3. The official app connects on its own. When a request appears under Pending approval, check its role and scopes before you approve.

    Settings → Gateway indicates whether the saved operator connection has Full or Limited access. For bearer-token safety, plaintext LAN ws:// setup is limited automatically. If it is limited, set up wss:// or Tailscale Serve, scan a new full-access code from Control UI or openclaw qr, then reconnect so settings and upgrades become available.

The Control UI button needs an already paired session with operator.admin. As a terminal fallback, choose a discovered Gateway in the iOS app (or turn on Manual Host and enter host/port), then approve the request on the Gateway host:

openclaw devices list
openclaw devices approve <requestId>

When the app retries pairing with different auth details (role/scopes/public key), the earlier pending request is superseded and a new requestId is created. Run openclaw devices list again before approving.

Optional: if the iOS node always connects from a tightly controlled subnet, you can opt in to first-time node auto-approval using explicit CIDRs or exact IPs:

{
  gateway: {
    nodes: {
      pairing: {
        autoApproveCidrs: ["192.168.1.0/24"],
      },
    },
  },
}

This is off by default. It covers only fresh role: node pairing that requests no scopes. Operator/browser pairing, plus any change to role, scope, metadata, or public key, still needs manual approval.

  1. Confirm the connection:
openclaw nodes status
openclaw gateway call node.list --params "{}"

Health summaries

An opt-in, read-only HealthKit aggregate for the current calendar day can be returned by the iOS node. iOS device consent and explicit Gateway command authorization are separate gates. Setup, invocation, payload fields, privacy behavior, and troubleshooting are covered in HealthKit summaries.

Apple Watch voice and chat

OpenClaw offers two distinct Watch voice paths:

  • Talk to Claw relies on watchOS dictation, text relayed via the paired iPhone, and system-voice readback on the Watch, handling one turn at a time.
  • Talk on Watch places a realtime audio call from the Watch once you connect it in iPhone Settings. The iPhone does not relay its audio or chat.

On the Watch, neither path runs a full agent or the stock Codex runtime. Agent execution and tool policy belong to the Gateway; input, playback, and call controls are provided by the Watch.

Pair the Watch with the iPhone in Apple's Watch app, install OpenClaw via Watch app -> My Watch -> Available Apps, then launch OpenClaw once on each device.

Talk to Claw with the iPhone

No separate Watch Gateway pairing is needed for this companion path. Its Talk controls act on Talk on the paired iPhone; they do not turn on a standalone Watch call.

  1. Connect the iPhone to your Gateway and pick the chat you want to use.
  2. On the Watch, open Talk to Claw, then tap the voice button next to Message OpenClaw.
  3. Dictate and submit your message with the native input sheet. To hear the reply, keep Chat open on the Watch. Native input also opens from the message pill, but no spoken reply is requested that way.

Messages can only be relayed while the iPhone is available. If its Gateway connection is asleep, Watch messages fall back to the same bounded background reconnect used by Watch quick replies, honoring the iPhone's auto-connect setting. Update OpenClaw on both devices. Because a companion chat payload without ownership information cannot prove safe delivery, the phone rejects it with an update-required error. A Watch app older than that ownership check may still label a background transfer as queued. That label does not mean the phone accepted it. Check the phone's delivery warning and update both apps before sending again.

Delivery state gets persisted by both apps before either one acknowledges anything. While the Watch waits for the phone to accept a command, it keeps the original; the phone, in turn, stores the accepted run plus its reply before the result travels back. So if an app is reopened, or a result acknowledgment goes missing, a saved reply can be delivered again without the same chat being submitted twice. A queued message still does not confirm that the Gateway has processed it.

A permanent rejection (an expired message or a retired Gateway route, for example) does not count as the phone accepting the message. The Watch logs that outcome and does not retry the command. Saved result delivery is retried when the Watch reconnects or when Refresh is requested, and no additional chat is submitted.

Should delivery stall, go to Settings -> This iPhone -> Apple Watch -> Message Delivery on iPhone. Delivery uncertain indicates the phone cannot prove whether a send reached the Gateway; review the original conversation before resending. That send is never repeated automatically. Saved messages without delivery context show up as Needs review. If you still want to send the text, copy it to Chat; to delete it, use Discard. Completed cards offer Dismiss, which hides the card but keeps its original receipt for the Watch. Neither action is available on active deliveries. Dismiss neither cancels a Gateway run nor extends the reply's expiry.

When the Gateway accepts a message but the phone fails to save that acceptance, a later refresh or reconnect retries the local save without a second send. If the app quits before saving, reopening treats the send as uncertain.

New commands, along with their saved app-local copies, expire 48 hours after their original submission, not after the latest retry. Expiration halts automatic delivery and reply replay; remote work is not cancelled and the Gateway conversation is not deleted. Expired app-local copies are cleared on the next delivery operation or when the delivery list is opened, not by a background timer. Messages already saved as Needs review stay on iPhone until you discard them or forget their Gateway.

Hash-only import markers are kept by the phone after Discard or Forget, so a saved queue from an older app cannot bring back identical deleted text during a later upgrade. Where older messages conflict with saved delivery data or with a forgotten Gateway, the app keeps their source and displays a recovery error. To recover those messages, contact support. Reset Onboarding intentionally wipes all local client state, the old queue and its import markers included; it is not a way to delete specific messages.

Only the reply for the submitted turn is spoken. Changing the Gateway or chat on iPhone retires the pending spoken reply and clears the old Watch preview. Playback stops when you leave Watch Chat or background the app; a reply that arrives while you are away can be read on return, provided its wait has not expired.

The spoken-reply wait times out after 90 seconds and displays Spoken reply timed out. Check Chat on iPhone., including after the Watch app is reopened. Cancelling that wait or stopping speech does not cancel the Gateway chat run and does not remove a queued message. When no reply is spoken, refresh Chat or check the conversation on iPhone before resending. Long runs and interrupted return delivery may still need this manual readback. Keep the Gateway updated so reply attribution stays reliable when messages are collected into a later run.

The Gateway, agent and exact session are captured by the phone at the moment it offers a chat or quick-reply action. A queued message cannot be retargeted by later changes to the selected chat, shared main or global sessions included. If that delivery context is missing, reconnect and refresh from iPhone instead of guessing the destination.

Forgetting a Gateway deletes its phone delivery records and invalidates old commands, even when you pair the same Gateway again. A disconnected Watch cannot be erased remotely right away; it clears a stale command once it receives the phone's rejection. Forget direct setup on the Watch affects only its separate direct connection, not the iPhone relay.

These are app-local SQLite journals. They migrate when the apps open and need neither a Gateway database upgrade nor an openclaw doctor run.

Standalone voice

Standalone voice requires a current Gateway running Gateway-controlled WebRTC Talk, an iPhone connection with operator.admin for setup, and a secure Gateway URL that the Watch can reach on its own. Apply the same secure endpoint and initial pairing requirements as direct Watch node setup: watchOS must trust the HTTPS certificate, and an iPhone-only or tailnet-only route will not do when the Watch is away from the phone.

  1. On the Gateway, configure realtime Talk mode with the webrtc transport and a provider/authentication pairing that supports gateway-control-v1 and returns an ICE-lite answer with UDP candidates. Provider credentials remain on the Gateway.
  2. On iPhone, go to Settings -> This iPhone -> Apple Watch -> Connect Apple Watch. Voice access comes with normal Watch setup; no separate voice enable setting exists.
  3. Launch OpenClaw on the Watch before the setup code expires. Open Talk on Watch and wait for Ready to talk.
  4. Tap Start, grant microphone access, and pick an agent if asked. Leave OpenClaw on screen until Connected appears. Merely opening the voice screen does not activate the microphone.
  5. Speak, tap Mute or Unmute as needed, and tap End when finished. The screen displays the latest user and assistant transcripts; conversation history is kept by the Gateway.

Through the one-time setup, the Watch receives its own node credential plus an operator credential carrying exactly operator.read and operator.talk. No admin access is granted, and the iPhone's saved Gateway token or password is not copied. Setup configuration lives in the Watch Keychain; issued device credentials live in its protected native-state SQLite database, scoped to that Gateway. If setup is incomplete or has expired, send it again from iPhone Settings. Watches paired under the older node-only setup must run Connect Apple Watch once more to authorize voice. Existing grants are never silently expanded, and revoked access is not restored automatically. Pairing starts no call and does not turn on the microphone.

Audio travels between Watch and provider as native WebRTC with Opus over UDP. Call control and transcript events, not microphone audio, go over the secure Gateway WebSocket. Provider tools and agent consultations are controlled by the Gateway; the Watch never opens a provider data channel and never holds a permanent provider API key. Unsupported provider/authentication or transport choices fail visibly rather than falling back to another voice path. ICE-lite is mandatory for the native Watch transport; Gateway-controlled WebRTC support on its own is not enough.

Provider error notifications show on the Watch without ending a call that is otherwise active. Another turn can be tried; the call still ends on an explicit session closure or an unrecoverable connection failure.

Every new call uses its own session for the chosen agent. Network recovery is bounded and preserves that agent and chat session; after a terminal error, Try Again begins a new call. The iPhone's currently selected chat is not resumed by this, and the companion chat and approval features continue to use the iPhone relay.

For OpenAI Gateway-controlled WebRTC calls, a 30-minute active-session lease is scheduled by the Gateway at setup; audio activity does not renew it. On receiving the session-ended event caused by lease expiry, the Watch displays Call unavailable and retries nothing automatically. Bring OpenClaw to the foreground and tap Try Again to begin a new call. The lease does not guarantee 30 minutes of usable audio, and calls may end sooner.

A call that is already established keeps running on background audio. It is not deliberately terminated just because the screen dims or the app is sent to the background. If startup goes to the background before a connection is made, the attempt stops and a message asks you to keep OpenClaw on screen. A call ends when you navigate back, tap End, disable, change or forget the Watch's Gateway connection, hit an audio interruption, or encounter an unrecoverable failure.

Microphone/speaker routing on a physical Watch, wrist-down operation, Wi-Fi/cellular handoff, battery consumption, and reliability across multiple hours still require validation on a device. Neither simulator tests nor native macOS provider-audio checks prove those behaviors. The Gateway connection is not arbitrarily always-on: watchOS low-level networking needs an active audio session. UDP has to be reachable; the Watch transport configures no TURN relay and no TCP/WebSocket media fallback.

Review command approvals

Pending exec requests on iPhone can be reviewed by an operator connection that has operator.admin, or by a paired operator.approvals connection that the Gateway explicitly targets. The approval card displays the Gateway's sanitized command preview, warning, host context, expiry, and only those decisions the request offers. Through the existing iPhone relay, the paired Apple Watch gets the same reviewer-safe prompt and offers the compact allow-once/deny subset of decisions. Approval prompts are not carried in direct Watch Gateway mode.

Approval state is shared with the Control UI and the supported chat surfaces. Whichever answer is committed first wins. iPhone and Watch fetch the Gateway's saved terminal record after another surface resolves the request, after a remote resolved notification, and whenever a resolve acknowledgement may have been lost. Until that readback confirms whether the request is still pending, actions remain unavailable.

Approval ownership is tied to the selected Gateway. An old prompt cannot be applied to the replacement connection when Gateways are switched. Gateways older than the unified approval methods fall back to the shipped exec-specific methods; retained terminal state and richer cross-surface results need an updated Gateway.

Answer agent questions

For operator connections with operator.questions (or operator.admin), chat displays pending Gateway questions as native cards. Single- and multi-select options, option descriptions, free-text Other answers, and an expiry countdown are all supported. Pending questions are reloaded from the Gateway on reconnect. A card locks once this device answers it, once another surface answers it first, or once the question expires or is cancelled.

Optional direct Apple Watch node

In direct mode, the watch gets a signed node identity of its own plus its own Gateway connection. While OpenClaw is active, supported node commands keep working over watch Wi-Fi or cellular even if the paired iPhone is unavailable.

Requirements:

  • The iPhone must be connected to the Gateway with operator.admin scope.
  • The setup code must advertise a wss:// Gateway endpoint with a certificate that watchOS trusts; the watch polls the matching https:// origin. Plain HTTP, self-signed trust, and fingerprint-only trust are unsupported. Endpoint configuration is covered in Gateway-owned pairing. Routes that are loopback, iPhone-only, or tailnet-only cannot be reached by the watch on its own.
  • Cellular use needs a cellular-capable Apple Watch with active service.
  • OpenClaw must be active on the watch. The non-voice direct node relies on short HTTPS polls and reconnects when the app comes back to the foreground; it keeps no generic background connection. Standalone voice takes the separate active-audio networking path. Refer to Apple's watchOS low-level networking guidance.

Setup:

  1. On iPhone, open Settings -> This iPhone -> Apple Watch (or Device -> Apple Watch in the offline fallback).
  2. Tap Connect Apple Watch.
  3. Open OpenClaw on the watch before the short-lived setup code expires.
  4. Confirm the separate Apple Watch row showing openclaw nodes status.

The setup code carries a short-lived bootstrap credential for the Watch's node and limited read/Talk roles; until it expires, treat it like a password. It never includes the iPhone's saved Gateway password or token. Once pairing completes, the watch stores its own device credentials and deletes the bootstrap credential. The same setup covers the commands listed below and standalone voice; calls still need Start and microphone permission. Companion chat, iPhone Talk controls, approvals, and the existing watch.* notification flow stay as iPhone-relay features.

A watch.notify receipt reports delivery or queuing by the Watch transport, not completion of the best-effort iPhone notification mirror. Cancellation is checked before a new Watch transfer or phone mirror starts; it cannot recall work already handed to WatchConnectivity. After the phone mirror is handed off, it continues independently of the invoke.

Direct watchOS node commands:

SurfaceCommandsNotes
Devicedevice.info, device.statusWatch identity, battery, thermal, storage, and network.
Notificationssystem.notifyWhile the app is active; requires watch permission.

Relay-backed push for official builds

Rather than publishing the raw APNs token to the Gateway, official distributed iOS builds go through an external push relay. Official App Store builds from the public release lane use the hosted relay at https://ios-push-relay.openclaw.ai; for App Store distribution this base URL is hardcoded and no override is read.

A custom relay deployment needs an iOS build/deployment path that is deliberately separate, with a relay URL matching the Gateway relay URL. A custom relay URL is never accepted by the App Store release lane. If your build uses a custom relay, set the matching Gateway relay URL:

{
  gateway: {
    push: {
      apns: {
        relay: {
          baseUrl: "https://relay.example.com",
        },
      },
    },
  },
}

How the flow works:

  • Using App Attest and a StoreKit app transaction JWS, the iOS app registers with the relay.
  • An opaque relay handle and a registration-scoped send grant come back from the relay.
  • The iOS app fetches the paired Gateway identity (gateway.identity.get) and includes it in relay registration, which delegates the relay-backed registration to that specific Gateway.
  • With push.apns.register, the app forwards that relay-backed registration to the paired Gateway.
  • For push.test, background wakes, and wake nudges, the Gateway uses that stored relay handle.
  • Should the app later connect to a different Gateway, or to a build with a different relay base URL, it refreshes the relay registration rather than reusing the old binding.

What the Gateway does not need for this path: no deployment-wide relay token, and no direct APNs key for official App Store relay-backed sends.

Expected operator flow:

  1. Install the official iOS app.
  2. Optional: set gateway.push.apns.relay.baseUrl on the Gateway only when using a deliberately separate custom relay build.
  3. Pair the app to the Gateway and let it finish connecting.
  4. Once an APNs token exists, the operator session is connected, and relay registration succeeds, the app publishes push.apns.register.
  5. From then on, push.test, reconnect wakes, and wake nudges can use the stored relay-backed registration.

Background alive beacons

When a silent push, background refresh, or significant-location event wakes the app, iOS triggers a short node reconnect followed by a call to node.event with event: "node.presence.alive". Only after the authenticated node device identity is known does the Gateway record this as lastSeenAtMs/lastSeenReason on the paired node/device metadata.

The app counts a background wake as successfully recorded only if the Gateway response contains handled: true. Older Gateways may acknowledge node.event with { "ok": true }; that response is compatible, but it does not count as a durable last-seen update.

Background refresh wakes are requested through the system BackgroundTasks scheduler each time the app moves to the background, after a silent push that could not be applied, and again after every refresh run; when they actually execute is up to iOS. If Background App Refresh is turned off for OpenClaw in iOS Settings, they stop, leaving push and significant-location wakes.

Compatibility note:

  • OPENCLAW_APNS_RELAY_BASE_URL still works as a temporary env override for the Gateway (gateway.push.apns.relay.baseUrl is the config-first path).
  • The push mode of the App Store release build hardcodes the hosted relay host and never reads a relay-URL override, the OPENCLAW_PUSH_RELAY_BASE_URL build-time env var affects only local/sandbox iOS build modes.

Authentication and trust flow

Direct APNs on the Gateway cannot give official iOS builds two guarantees, so the relay enforces them:

  • Hosted relay access is limited to genuine OpenClaw iOS builds that Apple distributes.
  • Relay-backed pushes from a Gateway reach only iOS devices paired with that particular Gateway.

The path, step by step:

  1. iOS app -> gateway: pairing with the Gateway happens through the standard Gateway auth flow, which yields both an authenticated node session and an authenticated operator session. The relay is called from the operator session via gateway.identity.get.
  2. iOS app -> relay: over HTTPS, the app hits the relay registration endpoints, supplying App Attest proof and a StoreKit app transaction JWS. Bundle ID, App Attest proof, and Apple distribution proof are all checked by the relay, which also demands the official/production distribution path. That requirement is exactly why local Xcode/dev builds are refused by the hosted relay: a local build cannot produce the official Apple distribution proof.
  3. gateway identity delegation: the app retrieves the paired Gateway identity from gateway.identity.get before registering and puts it into the registration payload. Back comes a relay handle plus a registration-scoped send grant delegated to that Gateway identity.
  4. gateway -> relay: the relay handle and send grant received via push.apns.register are stored by the Gateway. When push.test fires, on reconnect wakes, and on wake nudges, the Gateway signs the send request using its own device identity. The relay then checks the stored send grant and the Gateway signature against the delegated Gateway identity recorded at registration. Even a Gateway that somehow got hold of the handle cannot reuse that stored registration.
  5. relay -> APNs: production APNs credentials and the raw APNs token for the official build belong to the relay. For relay-backed official builds the Gateway stores no raw APNs token at all; the final push reaches APNs from the relay, acting for the paired Gateway.

Reasons behind this design: production APNs credentials stay off user Gateways, raw official-build APNs tokens are never kept on the Gateway, hosted relay use is restricted to official OpenClaw iOS builds, and one Gateway is stopped from sending wake pushes to iOS devices that belong to a different Gateway.

Direct APNs is still what local/manual builds use. Testing those builds without the relay means the Gateway must still have direct APNs credentials:

export OPENCLAW_APNS_TEAM_ID="TEAMID"
export OPENCLAW_APNS_KEY_ID="KEYID"
export OPENCLAW_APNS_PRIVATE_KEY_P8="$(cat /path/to/AuthKey_KEYID.p8)"

These are runtime env vars for the gateway host, not Fastlane settings. Only App Store Connect auth such as APP_STORE_CONNECT_KEY_ID and APP_STORE_CONNECT_ISSUER_ID is kept in apps/ios/fastlane/.env; direct APNs delivery for local iOS builds is not configured there.

Recommended storage on the gateway host, matching how other provider credentials live under ~/.openclaw/credentials/:

mkdir -p ~/.openclaw/credentials/apns
chmod 700 ~/.openclaw/credentials/apns
mv /path/to/AuthKey_KEYID.p8 ~/.openclaw/credentials/apns/AuthKey_KEYID.p8
chmod 600 ~/.openclaw/credentials/apns/AuthKey_KEYID.p8
export OPENCLAW_APNS_PRIVATE_KEY_PATH="$HOME/.openclaw/credentials/apns/AuthKey_KEYID.p8"

Never commit the .p8 file, and do not put it inside the repo checkout.

Discovery paths

Bonjour (LAN)

On local., the iOS app browses _openclaw-gw._tcp, plus the wide-area DNS-SD discovery domain when one is configured. Gateways on the same LAN show up automatically from local.; for cross-network discovery the configured wide-area domain can be used with no change to the beacon type.

Tailnet (cross-network)

When mDNS is blocked, fall back to a unicast DNS-SD zone (pick a domain; example: openclaw.internal.) together with Tailscale split DNS. The CoreDNS example is in Bonjour.

Manual host/port

Go to Settings → Gateway, turn on Use Manual Gateway, then supply the Gateway host and port (default 18789).

IPv6 host fields take raw addresses like fd00::1 as well as bracketed ones like [fd00::1]. A full Gateway URL needs the address in brackets, e.g. wss://[fd00::1]:18789.

Multiple Gateways

Every Gateway the app has paired with is kept in a registry, so switching among them does not require pairing again:

  • Settings → Gateway lists Paired Gateways with the active one marked. Tapping an entry switches to it: current sessions are torn down and the app reconnects to the chosen Gateway.
  • Per Gateway, the app stores credentials, TLS trust decisions, per-gateway preferences, and cached chat history. State is never mixed across Gateways when switching, and push registration tracks the active Gateway.
  • To Forget a paired Gateway, swipe it (or use its context menu). This deletes its credentials, device tokens, TLS pin, and cached chats.
  • A discovered Gateway must be visible on the network before you can switch to it; manual Gateways come back via their saved host and port.
  • Saved Gateways are hidden in demo and screenshot mode: the sidebar picker and Settings → Gateway show just the fixture connection, with no Paired Gateways list and no manual Gateway, credential, or custom header settings. Connecting a real Gateway requires scanning a QR code or pasting a setup code.

Computer Use relationship

The iOS app serves as a mobile node surface; it is not a Codex Computer Use backend. Codex Computer Use and cua-driver mcp drive a local macOS desktop via MCP tools, whereas the iOS app exposes iPhone capabilities through OpenClaw node commands such as camera.*, screen.*, location.*, and talk.*.

Agents can still drive the iOS app through OpenClaw by invoking node commands, though such calls travel over the Gateway node protocol and are bound by iOS foreground/background limits. For local desktop control use Codex Computer Use; for iOS node capabilities, use this page.

Voice wake + talk mode

  • Voice wake and Talk mode live on the Dashboard's Settings -> Talk page.
  • Recognized commands from voice wake go to the active session; spoken assistant replies come from Talk mode.
  • When talk.realtime.transport is webrtc, OpenAI realtime Talk uses client-owned WebRTC; if gateway-relay is set explicitly, the Gateway owns it. See Talk mode.
  • Talk-capable iOS nodes advertise the talk capability and may declare talk.ptt.start, talk.ptt.stop, talk.ptt.cancel, and talk.ptt.once; for trusted Talk-capable nodes the Gateway permits those push-to-talk commands by default.
  • iOS may suspend background audio, so treat voice features as best-effort whenever the app is not active.

Start live voice with Siri or Shortcuts

The Start Live Voice App Shortcut brings OpenClaw to the current chat and starts the same Talk path used by the inline Talk control.

  1. First open OpenClaw and pair and connect to your Gateway. Live voice relies on your existing Talk mode voice provider configuration; no provider is configured by the shortcut, and pairing is not bypassed.
  2. Under Shortcuts → Apps → OpenClaw, select Start Live Voice. Siri also works: "Start live voice with OpenClaw".
  3. Grant microphone access at the iOS prompt. Unlock your iPhone if prompted, and keep OpenClaw in the foreground while Talk starts. iOS unlock and foreground restrictions are not bypassed by the shortcut.

For faster access, save a shortcut that contains Start Live Voice, then map it under Settings → Action Button → Shortcut on a supported iPhone, or pick Add to Home Screen in Shortcuts. Voice running in the background is still subject to the same iOS limits as Talk started inside the app.

Common errors

  • NODE_BACKGROUND_UNAVAILABLE: bring the iOS app to the foreground (camera/screen commands require it).
  • Pairing prompt never appears: run openclaw devices list and approve manually.
  • Gateway setup incomplete: the Gateway did not provide both node and operator credentials. Generate a new iPhone setup code from Devices -> Pair device in the Control UI or openclaw qr, then scan it in Settings -> Gateway. Automatic reconnect stays paused until you retry setup; this is not a device-storage error.
  • If setup cannot safely replace the Gateway's offline data, it stops before applying the replacement credentials. The setup code and manual endpoint stay available. Resolve the device-storage problem, then retry.
  • Watch shows no iPhone state: confirm the iPhone reports watchPaired: true and watchAppInstalled: true in watch.status. If pairing is false, pair the Watch in Apple's Watch app. If installation is false, install the companion from My Watch -> Available Apps. After either change, open OpenClaw on the Watch once; immediate reachability still requires both apps to be running, while queued updates can arrive later in the background.
  • Reconnect fails after reinstall: the Keychain pairing token was cleared; re-pair the node.
8,166 words · updated Oct 26, 2026