API

Control API

Drive every visible bar feature from a Unix socket, URL scheme, or CLI.

The Control API is the keyboard-friendly automation surface. Three transports speak the same verbs:

  • Unix domain socket at ~/Library/Application Support/ApexDock/api/control.sock — line-delimited JSON, request/response. Connection stays open across requests.
  • apexdock:// URL scheme — fire-and-forget triggers from Shortcuts.app, Raycast, browsers.
  • apexdock CLIApexDock.app/Contents/Resources/bin/apexdock, install via Settings → Integrations.

All control verbs require an active ApexDock license grant except settings.open, which remains available while locked so you can reach licensing and account settings.

Wire format

Requests are NDJSON, one per line:

json
{"v":1,"id":"opt-correlation-id","cmd":"workspace.switch","args":{"name":"Work"}}

Responses are NDJSON, one per line:

json
{"v":1,"id":"opt-correlation-id","ok":true,"data":{"id":"","name":"Work"}}
FieldNotes
vSchema version. Currently 1.
idOptional correlation ID echoed in the response.
cmdThe verb.
argsObject of string/bool/number values.

Errors:

json
{"v":1,"id":"opt-correlation-id","ok":false,"error":"no workspace matches: foo"}

Verbs

cmdArgsReturnsNotes
workspace.listarray of {id, name, accent?, folder?}
workspace.switch{id} or {name}{id, name}Name match: case-insensitive, exact > prefix > contains
workspace.current{id, name} or {}Empty when no workspace is active
app.focus{bundleId}{bundleId, launched}Activates if running, otherwise launches via NSWorkspace
app.list-pinnedarray of {bundleId, name}Reads the global pinned list
bar.toggle-visibleHides if visible, shows if hidden
bar.set-visible{visible: Bool}Forces a state
action.toggle-dock-suppressorMirrors Settings → Bar → Hide macOS Dock
action.toggle-window-minderMirrors Settings → Bar → Adjust Windows Around Bar
settings.open{tab}{tab}Tabs: bar, permissions, agents, assistant, commandPalette, workspaces, about
palette.showOpens the command palette
palette.run{query}{name, kind}Local fuzzy match; runs the top hit

URL scheme

apexdock://<resource>/<verb>?<args>. Args are URL query parameters.

apexdock://workspace/list
apexdock://workspace/switch?name=Work
apexdock://workspace/switch?id=01234567-89AB-CDEF-0123-456789ABCDEF
apexdock://workspace/current
apexdock://app/focus?bundleId=com.apple.Safari
apexdock://app/list-pinned
apexdock://action/toggle-dock-suppressor
apexdock://action/toggle-window-minder
apexdock://bar/toggle
apexdock://bar/set?visible=false
apexdock://settings?tab=agents
apexdock://palette/show
apexdock://palette/run?q=switch%20to%20Work

q is sugar for query. Responses from URL invocations aren't surfaced — use the socket or CLI when you need the result.

Smoke tests

bash
SOCK="$HOME/Library/Application Support/ApexDock/api/control.sock"

# socat — interactive, keeps connection open
printf '{"v":1,"cmd":"workspace.list"}\n' | socat - UNIX:"$SOCK"

# nc — one-shot
printf '{"v":1,"cmd":"workspace.current"}\n' | nc -U "$SOCK"

# CLI — same effect
apexdock workspace current --text

# URL scheme — fire-and-forget
open 'apexdock://workspace/switch?name=Work'

Recipes

Raycast

bash
#!/bin/bash
# @raycast.title Switch ApexDock Workspace
# @raycast.argument1 { "type": "text", "placeholder": "name" }
apexdock workspace switch "$1" --text

Alfred

bash
/usr/local/bin/apexdock workspace switch "{query}"

Shortcuts.app

Add an Open URL action with apexdock://workspace/switch?name=Work. Combine with Ask for Input to parameterise. Or use a Run Shell Script action with the CLI.

Keyboard Maestro

Use Execute Shell Script:

bash
/usr/local/bin/apexdock action toggle-dock-suppressor

Bind to whatever keystroke. The CLI exits non-zero on failures, so KM's "If last action failed" branch can show a notification.

Status line

bash
while sleep 5; do
  apexdock workspace current --text
done

Limitations (v1)

  • palette.run runs the local fuzzy matcher only — it doesn't invoke the LLM router. Use palette.show and type if you need AI routing.
  • bar.toggle-visible flips every bar panel together; per-display control isn't exposed.
  • Schema is v: 1. Future breaking changes will bump to v: 2.