API Reference

VQF Engine — WebSocket API

The VQF Engine is a compiled Adobe Premiere Pro ControlSurface plugin by Video Quick Fix®. It runs a WebSocket server that accepts plain-text commands and returns plain-text replies. Current engine version: 1.2.2download the installer. Available for Mac (macOS 13+) and Windows (10 / 11) — see the VQF Engine page for both installers.

Connection

Message conventions

Commands

get.version1.2.1+

Returns the engine's version string. Use this at connect time to detect an outdated engine and prompt the user to rerun the installer pkg (a new engine only takes effect after Premiere Pro restarts).

Reply: version:<semver>

Engines older than 1.2.1 don't recognize the command and send no reply — treat a timeout as "pre-1.2.1".

→ get.version
← version:1.2.1

get.angle:<startTicks>:<track>

Returns the currently selected camera angle of the multicam clip at the given position in the active sequence.

Reply: angle:<n> where <n> is the active camera number.

→ get.angle:12303360000:1
← angle:3

get.clipsize:<startTicks>:<endTicks>:<track>

Returns the frame dimensions of the clip at the given position in the active sequence.

Short form: get.clipsize:<startTicks>:<track>

Reply: clipsize:<width>:<height>

→ get.clipsize:12303360000:15240960000:1
← clipsize:3840:2160

get.clipsize.marker:<token>:<track> · get.angle.marker:<token>:<track>1.1.0+

Marker-rendezvous variants of get.clipsize / get.angle. Instead of matching a clip by raw ticks (ambiguous across open timelines), the client first creates a temporary sequence marker whose name is a unique token at the clip's start, then queries by that token. The engine locates the marker by name via the Premiere Pro Marker Suite, which pins both the correct timeline and the exact time — no timeline-ID guessing. The client removes the marker after the reply.

Reply: same as the positional commands — clipsize:<width>:<height> or angle:<n>. If the marker is not found (or the Marker Suite is unavailable), the engine replies with zeros (clipsize:0:0 / angle:0); treat this as failure and fall back to the positional query. Engines built before marker support don't recognize the command and send no reply — use a timeout.

→ get.clipsize.marker:VQF-mdq31x-1:1
← clipsize:3840:2160

Side effect: a marker-validated timeline seeds the engine's timeline cache, so subsequent positional commands also get faster and more reliable.

cmd.multicam.choosenocut.camera<N>

Switches the currently selected multicam clip to camera <N> without creating a cut. The clip must already be selected in the sequence before sending.

Reply: none. To confirm the switch landed, poll get.angle afterward.

→ cmd.multicam.choosenocut.camera2

multicam.angle:<n>

Sets the camera angle on the currently selected clip. Intended for nested-sequence multicam clips.

Reply:

ReplyMeaning
multicam.angle.ok:angle applied
multicam.angle.error:parse<n> was not a valid number
multicam.angle.error:range<n> is outside the clip's available angles
→ multicam.angle:2
← multicam.angle.ok:

vitals.subscribe1.1.0+ payload

Opts this connection into push telemetry. Costs nothing when unused: all polling work is skipped while no client is subscribed.

Reply: none directly; the engine then pushes two kinds of frames to subscribers:

1. vitals:<json> — once per second:

vitals:{"v":"1.2.1","playing":true,"idleSec":0,
        "paused":false,"recording":false,"rewind":false,"ffwd":false,
        "speed":1.98,"timecode":"00:01:23:12","displayMode":1,
        "cuts":142,"cutsChanged":false,"edited":true,"seqChanged":false,
        "markers":7,"tracks":9,"audioPeakDb":-6.2,"soloActive":false}
FieldMeaning
vengine version string (added 1.2.1 — absent on older engines; treat missing as "pre-1.2.1")
playing / paused / recording / rewind / ffwdlive transport state as Premiere Pro reports it
speedactual playback rate derived from timecode deltas: ~1.0 normal, ~2.0 double-tapped L, negative for J-key reverse, ~0 stopped
timecodecurrent playhead display string; displayMode is the host's display-mode enum
idleSecseconds since last keyboard/mouse input system-wide (AFK detection)
cutssegment count of the active timeline (−1 if no timeline known yet); cutsChanged true the tick it changes
editedtrue the tick the timeline's content hash changes — fires for trims, moves, and effect changes even when the cut count is unchanged
seqChangedtrue the tick the user switches to a different sequence
markerssequence marker count (−1 unavailable)
tracksmixer channel-strip count (audio tracks; −1 unavailable)
audioPeakDbloudest master-channel meter value; only sampled during playback, −999 otherwise
soloActiveThe Premiere Pro "rude solo" flag — some channel is soloed

Fields are additive over the v1 payload (playing, idleSec), so older clients keep working. Parse leniently: treat missing fields as unavailable.

2. event:transport:<json> — pushed immediately (not on the 1 Hz tick):

event:transport:{"type":"play","on":true}

type is one of play, pause, stop, record, rewind, ffwd. Use these for reactions that shouldn't lag up to a second; the next vitals: frame will agree with them.

dump.angle:<startTicks>[:<track>]

Diagnostic dump of the Premiere Pro video segment node tree at the given time — the raw data that get.angle / get.clipsize answers are derived from. Use it when a query returns zeros and you need to see what the engine actually sees. Documented as official as of engine 1.2.1 (present in earlier builds).

Reply: a stream of text frames, each prefixed [dump] , opened by [dump] === VIDEO SEGMENT NODE DUMP START === and terminated by [dump] === VIDEO SEGMENT NODE DUMP END ===. In between: one block per node (id, type, flags), selected segment properties (clip track ID, multicam selected track, stream frame width/height, nested-sequence hash), then its inputs and operators, indented by depth. The engine probes the cached last-good timeline, all known-good timelines, and ±5 IDs around the last good one, so the same tree can appear once per matching timeline (--- timeline <id> --- separators). If the VideoSegment suite is unavailable, a single [dump] ERROR: could not acquire VideoSegmentSuite line precedes END.

Output can run to hundreds of frames on complex sequences. The framing (START/END markers, [dump]  prefix) is stable API; the exact property lines may grow over time — parse leniently.

→ dump.angle:12303360000:1
← [dump] === VIDEO SEGMENT NODE DUMP START ===
← [dump] time=12303360000 track=1
← [dump] --- timeline 42 ---
← [dump] NODE id=101 type=Clip flags=0 currentTrack=-1
   ...
← [dump] === VIDEO SEGMENT NODE DUMP END ===

uif.window.<name>

Focuses the named Premiere Pro window/panel.

Reply: none.

→ uif.window.Program Monitors

exec:<contextID>:<commandID>1.2.0+

Executes a host command in an explicit UI context. The bare fall-through path (sending a raw command ID) always runs in the global context, which silently ignores context-scoped commands (e.g. anything registered under timeline, project, program.monitor). Use exec: for those.

Reply: exec.ok:<contextID>:<commandID> once dispatched (fire-and-forget — confirms the send, not the effect), or exec.error:parse / exec.error:nosuite / exec.error:alloc.

→ exec:timeline:cmd.timeline.setttransitionduration
← exec.ok:timeline:cmd.timeline.setttransitionduration

get.transitions:<startTicks>:<endTicks>:<track>1.2.0+

Reports the head and tail transitions of the clip at the given position, read from the video segment tree. Handles all three transition alignments (start at cut / centered / end at cut) by probing just inside and just outside each clip edge.

Reply: transitions:<headName>:<headDurTicks>:<tailName>:<tailDurTicks>

→ get.transitions:12303360000:15240960000:1
← transitions:ADBE Cross Dissolve New:25401600000:-:0

Read-only: the segment suite exposes no write path, so transition duration cannot be set through the engine — only via the UI command (exec:timeline:cmd.timeline.setttransitionduration, which opens a modal dialog in Premiere Pro).

get.commands1.2.1+

Dumps the full Premiere Pro control-surface command registry — the discovery tool for exec: targets. One frame per command:

command:<contextID>:<commandID>:<contextName>:<commandName>

terminated by commands.done:<count>. On failure: commands.error:<reason> (e.g. commands.error:nosuite). Any : inside free-text name fields is replaced with ; so the wire format stays parseable.

→ get.commands
← command:timeline:cmd.timeline.setttransitionduration:Timeline:Set Transition Duration
← ...
← commands.done:412

Caveats: the framing (one command: frame per entry, the commands.done terminator) is stable API. The registry contents belong to Adobe, vary by Premiere Pro version, and carry no compatibility promise — treat the dump as discovery, verify the commands you build on, and remember that anything you run via exec: executes at your own risk (some commands open modal dialogs).

Versioning & compatibility. Commands are additive across releases. An engine that doesn't recognize a command sends no reply — always use timeouts and fall back gracefully. Check get.version (or the v vitals field) to know what you're talking to. Questions or something missing? Email support@videoquickfix.com.