Agent-readable docs index: /llms.txt. Full docs in one file: /llms-full.txt. Download /docs.zip to grep all markdown files locally.

Mute or unmute all iPhone sound

/v1/leases/{lease}/mutePOST
Presses the Bluetooth keyboard Mute key (consumer 0xE2), which toggles iOS full mute: all output, media in every app too. The ringer switch is separate. Each press is confirmed by SpringBoard's system log line over USB. If the first press toggled the wrong way (the iPhone was already in the asked state), it presses once more. Without a confirmation it fails with mute-unconfirmed and never presses again.
Authorizationoptional
bearerAuth?Bearer <token>
Required on the tunnel. An API token of the account, from ghosthand tunnel url --new-token. The unix socket needs no token
Request Bodyapplication/jsonrequired
muted *boolean
true mutes all sound, false unmutes
Response
200 · Input sent. JSON by default, server-sent events with `Accept text/event-stream`.
message *string
What was sent, e.g. tapped 207,448
logs *string[]
Progress lines written while the operation ran
screenshot?object
The screen after the input, present when screenshot was asked
Show properties
format *"png" | "jpeg"
width *integer
Image width in the request's scale space
height *integer
Image height in the request's scale space
data *string
Base64 image bytes
screen?object
The screen text after the input, present when screentext was asked
Show properties
width *integer
Screenshot width in the request's scale space
height *integer
Screenshot height in the request's scale space
lines *object[]
Recognized lines, top to bottom
Show item properties
text *string
x *integer
Left edge, in the request's scale space
y *integer
Top edge, in the request's scale space
width *integer
height *integer
confidence *number
OCR confidence, 0...1
Min: 0Max: 1
Default · Error (RFC 9457 problem details). `code` is stable; switch on it, not on `title` or `detail`.
code *"invalid-request" | "unauthorized" | "not-found" | "device-not-found" | "no-device" | "multiple-devices" | "permission-denied" | "bluetooth-unavailable" | "bluetooth-disconnected" | "no-frame" | "device-locked" | "lock-failed" | "pairing-timeout" | "pointer-not-found" | "lock-state-unavailable" | "lockdown-unavailable" | "unlock-failed" | "mute-unconfirmed" | "text-not-found" | "wait-text-timeout" | "cancelled" | "lease-invalid" | "device-leased" | "recording-active" | "no-recording" | "recording-failed" | "daemon-busy" | "tunnel-offline" | "login-required" | "subscription-required" | "unsupported-in-mode" | "xctest-unavailable" | "task-failed" | "internal-error"
Stable error code. Switch on it; title and detail are for people.
title *string
Short summary of the code, the same for every error with this code
status *integer
HTTP status of the error. In stream mode the response status stays 200.
detail *string
What happened and what to do next. Agents should read it.
Request example
curl -X POST "https://ghosthand.dev/macs/studio/v1/leases/42/mute" \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "muted": true }'
Response example
{ "message": "tapped 98,443", "logs": [ "found \"General\" at 98,443" ], "screen": { "width": 414, "height": 896, "lines": [ { "text": "General", "x": 158, "y": 56, "width": 98, "height": 22, "confidence": 1 }, { "text": "About", "x": 66, "y": 145, "width": 50, "height": 20, "confidence": 1 } ] } }