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

Stop the screen recording and finish the file

/v1/leases/{lease}/recording/stopPOST
Returns when the file is complete. After an automatic stop (max duration) it returns that recording's result once. no-recording when nothing was recorded since the last stop. recording-failed when the video writer failed (for example a full disk).
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
Response
200 · The finished recording
path *string
durationSeconds *number
Time from the first to the last video frame
bytes *integer
File size
width *integer
Video width in pixels (native screen pixels)
height *integer
Video height in pixels (native screen pixels)
frames *integer
Video frames written
droppedFrames *integer
Frames the encoder was not ready for. Frames removed by the fps cap are not counted.
audio *boolean
The file has a sound track
stoppedBy *"request" | "maxDuration" | "leaseEnded" | "daemonStopped" | "disconnected"
Why the recording stopped: request (record stop), maxDuration, leaseEnded (release, idle timeout or force), daemonStopped, or disconnected (the iPhone left USB).
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/recording/stop" \ -H "Authorization: Bearer <token>"
Response example
{ "path": "/tmp/demo.mp4", "durationSeconds": 12.4, "bytes": 4381022, "width": 828, "height": 1792, "frames": 372, "droppedFrames": 0, "audio": true, "stoppedBy": "request" }