Skip to Content
DocsTouch API

Touch API

The Touch API is an out-of-process interface that lets third-party apps consume touch and gesture data directly — and ask Gatecaster to mute system input for kiosk-style experiences. It ships with every edition, including Free.

Connection

A Unix-domain socket, owner-only (0600):

~/Library/Application Support/Gatecaster/api.sock

The protocol is NDJSON — newline-delimited JSON, both directions. Every message carries a v field; clients must ignore unknown fields and unknown gesture kinds for forward compatibility. Up to 16 concurrent clients are supported, each with independent subscription and suppression state.

Subscribing

Send a subscribe command listing the channels you want:

{ "subscribe": ["fingers", "gestures"] }
ChannelDelivers
fingersPost-palm-rejection contacts — what the pointer sees.
rawFingersEvery contact, each flagged with its palm-rejection verdict.
gesturesRecognized gestures, after the engine’s intent latch.

Finger frames

{ "v": 1, "type": "fingers", "t": 1717000000.123, "dropped": 0, "fingers": [ { "id": 3, "x": 0.412, "y": 0.875, "sx": 791.0, "sy": 945.0, "phase": "moved", "palm": false } ] }
  • x / y — normalized 0–1 in calibrated panel space.
  • sx / sy — screen pixels, already mapped through calibration and the active display.
  • phasebegan · moved · ended · cancelled.
  • dropped — frames discarded since the last delivery for a slow consumer.

Gesture frames

{ "v": 1, "type": "gesture", "gesture": "pinch", "value": 0.034, "phase": "changed" } { "v": 1, "type": "gesture", "gesture": "rotate", "value": -1.2, "phase": "changed" } { "v": 1, "type": "gesture", "gesture": "scroll", "dx": 0.0, "dy": -13.5, "phase": "changed" } { "v": 1, "type": "gesture", "gesture": "swipe", "direction": "left", "fingers": 3 }

Suppression

Ask Gatecaster to stop driving the system so your app can own the panel:

{ "suppress": ["input", "gestures", "edges"] } { "suppress": true } { "suppress": false }
CategoryMutes
inputPointer move / click / drag / scroll / keystroke injection.
gesturesSynthesized pinch / rotate trackpad events.
edgesEdge-pull triggers (Notification Center, and the on-screen keyboard). Accepted and honoured, but a no-op in the beta — edge gestures aren’t armed yet, so there is nothing to mute. Request it anyway: your app keeps working unchanged when they ship.

Suppression is a connection-scoped lease with union semantics: a mute stays on while any client requests it, and is released automatically when the socket closes. There’s no TTL or heartbeat to manage — and a crashed client can never leave touch wedged off.

Backpressure

The panel reports at roughly 120 fps with up to 10 contacts per frame. The server never blocks on a slow client: it drops frames and reports the count in the next delivered frame’s dropped field (≈256 KB buffer cap). If you fall behind, coalesce.

Reference clients

Dependency-free clients live in the gatecaster-examples repo under touch-api/ (see Examples):

import json, socket, os path = os.path.expanduser( "~/Library/Application Support/Gatecaster/api.sock") s = socket.socket(socket.AF_UNIX) s.connect(path) s.sendall(b'{"subscribe":["fingers","gestures"]}\n') for line in s.makefile(): msg = json.loads(line) if msg["type"] == "gesture": print(msg["gesture"], msg.get("value"), msg["phase"])

Versioning

The v field bumps only on breaking changes — a field removal or a semantics change. Additive fields don’t bump it, so always ignore unknown fields and unknown gesture kinds.