External SDK / API
Middle Control exposes a TCP API that lets any external device or software send commands to Middle Control — and read back live camera and gimbal data.
This is useful if you want to:
- Trigger presets, start/stop recording, or control a gimbal from a custom device or script
- Integrate Middle Control into a broadcast automation workflow
- Build a custom control panel (hardware or software) that talks directly to Middle Control
This API used to be documented on port 11581. That port is shared with the Middle Remote (Glue) connection and is refused when Middle Remote is in Direct mode — which is the default on macOS. If your integration was built on 11581, simply change the port to 11584: the commands and the feedback frame are identical. (This External API is a macOS feature. On Windows, use the Companion port 11580 and the Glue / Remote port 11581.)
There is no SDK that communicates directly with APC-R units. All commands go through the Middle Control app running on your computer.
🔌 Connection
Your device or software sends plain-text TCP commands to the computer running Middle Control. Each command is a short string (e.g. CAM3, PRESET1, P500) terminated by a newline character — one command per line.
Host : IP address of the computer running Middle Control
(use 127.0.0.1 if your software runs on the same machine)
Port : 11584
End character : \n (LF or CRLF)
Good to know:
- Commands are case-sensitive — send them exactly as written on this page.
- The API is fire-and-forget: a malformed or unknown command is silently ignored (there is no error reply). Use the live feedback to confirm state.
- When your integration is connected, an External API entry appears in the left sidebar of Middle Control, under Controllers — it stays visible as long as the connection is open.
Quick test from a terminal — select camera 1 and trigger its preset 1:
printf 'CAM1\nPRESET1\n' | nc <MIDDLE_CONTROL_IP> 11584
🎯 Selecting & targeting cameras
Every command on this page acts on a camera ID (1–99). There are two ways to say which one:
- Select a camera with
CAMx— the following commands act on it, and the feedback frame reports it. This changes the selected camera in Middle Control, like clicking it in the sidebar. - Target one command by appending
@Cxat the end — the command goes to cameraxwithout changing the selection.
| Command | Description |
|---|---|
CAM3 | Select camera/gimbal 3 — the commands that follow act on it |
REC_START@C2 | Start recording on camera 2, selection unchanged |
AUTOFOCUS@C5 | Trigger autofocus on camera 5, selection unchanged |
P500@C1 | Send a pan command to camera 1, selection unchanged |
Targeted commands make multi-camera actions easy — send REC_START@C1, REC_START@C2 and REC_START@C3 in rapid succession to start recording on cameras 1, 2 and 3 simultaneously.
🕹️ Gimbal & PTZ control
Variable speed
Drive an axis at a given speed — the axis keeps moving until you send 0 on it:
| Command | Description |
|---|---|
Pxx | Pan speed, xx between -2048 and +2048 (INT16) |
Txx | Tilt speed, xx between -2048 and +2048 (INT16) |
Rxx | Roll speed, xx between -2048 and +2048 (INT16) |
Zxx | Zoom speed, xx between -2048 and +2048 (INT16) |
P500 starts panning and P0 stops it. Safety net: if your TCP connection drops while an axis is still moving, Middle Control stops that axis automatically.
Speed settings used by the button commands and presets:
| Command | Description |
|---|---|
PTSxx | Pan/Tilt speed setting, xx between 1 and 100 (INT8) |
ZSxx | Zoom speed setting, xx between 1 and 100 (INT8) |
Absolute position
Send the gimbal to a precise position in a single command, with this frame format:
aGLOB;aPxx;aTxx;aRxx;aZxx;ss
| Part | Description |
|---|---|
aGLOB | Must be at the start of the frame |
aPxx | Absolute Pan position, in 1/10th of a degree (INT16) |
aTxx | Absolute Tilt position, in 1/10th of a degree (INT16) |
aRxx | Absolute Roll position, in 1/10th of a degree (INT16) |
aZxx | Absolute Zoom position, between 0 and 4096 (INT16) |
ss | Transition duration in seconds |
Example: move to Pan 20°, Roll 2°, Tilt 7.5°, Zoom mid-range, over 5 seconds:
aGLOB;aP200;aR20;aT75;aZ2500;5
You can also send a single axis on its own, using the current transition speed:
| Command | Description |
|---|---|
aPxx / aTxx / aRxx | Move one axis to xx, in 1/10th of a degree |
aZxx | Move the zoom to xx, between 0 and 4096 |
Buttons & utilities
These work like button presses:
| Command | Description |
|---|---|
PAN_L / PAN_R | Pan the gimbal left / right |
TILT_U / TILT_D | Tilt the gimbal up / down |
ROLL_L / ROLL_R | Roll the gimbal left / right |
After each movement command above, you must send the matching stop command after a delay of at least 70ms:
| Movement | Stop command |
|---|---|
PAN_L / PAN_R | PAN_IDLE |
TILT_U / TILT_D | TILT_IDLE |
ROLL_L / ROLL_R | ROLL_IDLE |
If the connection drops before the stop command, Middle Control stops the movement automatically.
| Command | Description |
|---|---|
ZOOM+ / ZOOM- | Zoom in / out by a step |
SPEED+ / SPEED- | Increase / decrease the pan/tilt speed |
ZSPEED+ / ZSPEED- | Increase / decrease the zoom speed |
Gimbal utilities:
| Command | Description |
|---|---|
RECENTER | Recenter the gimbal |
ACTIVETRACK | Active Track Enable / Disable |
GIMBALSLEEP / GIMBALWAKE | Sleep / wake the gimbal |
GIMBALAUTOCALIB | Start Gimbal Autocalibration (Autotune) |
MOTORAUTOCALIB | Start Focus Motor Autocalibration |
🎥 Camera control
Availability depends on the camera brand and how it is connected (some commands are Sony-only, some need an ATEM link).
Absolute values
Set a camera value directly:
| Command | Description |
|---|---|
aFxx | Focus, xx between 0.0 and 1.0 (FLOAT) |
aIxx | Iris, xx = f-number (FLOAT) — snapped to the nearest supported f-stop (roughly f/1.2 to f/22) |
aWBxx | White Balance, xx between 2500 and 10000 Kelvin (INT16 — whole numbers only) |
aTINTxx | Tint, xx between -100 and +100 (INT8) |
aISOxx | ISO / Gain in dB, xx between -12 and +36 (INT8) |
aSHUTxx | Shutter, xx = denominator (INT16 — e.g. aSHUT50 for 1/50s) |
For cameras controlled through an ATEM switcher (color corrector values):
| Command | Description |
|---|---|
aSATxx | Saturation, xx between 0 and 100 |
aCONTxx | Contrast, xx between 0 and 100 |
aBLACKLEVxx | Black level (lift luma), xx between -2.0 and +2.0 |
aMIDLEVxx | Mid level (gamma luma), xx between -4.0 and +4.0 |
aWHITELEVxx | White level (gain luma), xx between 0 and 16.0 |
For VISCA cameras that use Red/Blue gain instead of Kelvin/Tint:
| Command | Description |
|---|---|
aRGAINxx | Red gain, xx between 0 and 255 |
aBGAINxx | Blue gain, xx between 0 and 255 |
Steps & toggles
One increment per command:
| Command | Description |
|---|---|
FOCUS+ / FOCUS- | Focus in / out by a step |
IRIS+ / IRIS- | Iris increase / decrease |
WB+ / WB- | White balance increase / decrease |
ISO+ / ISO- | ISO increase / decrease |
TINT+ / TINT- | Tint increase / decrease |
SHUTTER+ / SHUTTER- | Shutter increase / decrease |
ND+ / ND- | ND Filter increase / decrease |
SHARP+ / SHARP- | Sharpness increase / decrease |
CONT+ / CONT- | Contrast increase / decrease (ATEM) |
SAT+ / SAT- | Saturation increase / decrease (ATEM) |
BLEV+ / BLEV- | Black level increase / decrease (ATEM) |
Auto modes and monitoring toggles:
| Command | Description |
|---|---|
AUTOFOCUS | Triggers autofocus |
AUTOIRIS | Triggers auto iris |
AUTOSHUTTER | Toggles auto shutter |
AUTOGAIN | Toggles auto gain / ISO |
AUTOWB | Toggles auto white balance |
COLORBARS | Show Color Bars |
ZEBRA | Show Zebra Guide |
FALSECOLORS | Show False Color Guide |
FOCUSPEAKING | Toggle Focus Peaking |
STATUSVIEW | Show the status view on the HDMI out of the camera |
DIGITAL_ZOOM | Toggle Digital Zoom (Sony) |
RESETCCU | Reset the CCU / color corrector values |
Menu navigation (Sony)
| Command | Description |
|---|---|
BTN_MENU | Press Menu Button |
BTN_OK | Press OK Button |
BTN_LEFT / BTN_RIGHT / BTN_UP / BTN_DOWN | Press the arrow buttons |
MULTISEL_LEFT / MULTISEL_RIGHT / MULTISEL_UP / MULTISEL_DOWN | Move the MultiSelector |
MULTISEL_PRESS | Press the MultiSelector |
CUSTOM_C1 … CUSTOM_C6 | Trigger Custom function C1 … C6 |
Recording
| Command | Description |
|---|---|
REC_START | Start recording (currently selected camera) |
REC_STOP | Stop recording (currently selected camera) |
REC_START_ALL | Start recording on all cameras |
REC_STOP_ALL | Stop recording on all cameras |
The feedback frame lists the cameras currently recording in REC_LIST[…].
📌 Presets
| Command | Description |
|---|---|
PRESET1 … PRESET12 | Trigger preset 1 … 12 of the currently selected camera |
PRESET1@C5 … PRESET12@C5 | Trigger preset 1 … 12 of camera 5 (presets 5.1 – 5.12 in Middle Control) |
SPRESET1@C5 … SPRESET12@C5 | Save preset 1 … 12 of camera 5 (presets 5.1 – 5.12 in Middle Control) |
Control preset playback:
| Command | Description |
|---|---|
STOPPRESET | Stop the preset move in progress (add @Cx to stop a specific camera) |
PRES_Dxx | Set the preset transition duration, xx in seconds |
PRES_Exx | Set the preset transition easing, xx between 0 (linear) and 100 — one value for all cameras, like PRES_D (APC-R firmware 2.0 or later) |
🔁 Automations
Start, stop and tune the Automations of the Automations page. All commands accept @Cx targeting.
Camera Shake
| Command | Description |
|---|---|
SHAKE-START / SHAKE-STOP | Start / stop the camera shake |
SHAKE-SPEEDxx | Shake speed, xx between 1 and 100 |
SHAKE-AMPLxx | Shake amplitude, xx between 1 and 100 |
Zoom Loop
| Command | Description |
|---|---|
ZLOOP-START / ZLOOP-STOP | Start / stop the zoom loop |
ZLOOP-SPEEDxx | Zoom speed, xx between 1 and 100 |
ZLOOP-DURATIONxx | Zoom travel time, xx in seconds (0.1 – 60) |
ZLOOP-RESTDURATIONxx | Pause between loops, xx in seconds (0.1 – 15) |
Presets Sequence
| Command | Description |
|---|---|
PRESETSEQ-START / PRESETSEQ-STOP | Start / stop the presets sequence |
PRESETSEQ-BANKx | Select the active sequence bank, x between 1 and 7 |
PRESETSEQ-SPEEDxx | Transition speed of the sequence, xx in seconds (0.1 – 15) |
PRESETSEQ-RESTDURATIONxx | Rest time on each preset, xx in seconds (0.1 – 15) |
The feedback frame reports the live state of each automation for the selected camera: SHAKE_RUN, ZLOOP_RUN, PRESETSEQ_RUN (1 while running) and PRESETSEQ_BANK (active bank).
🖥️ Live View & Multi View
Open and close the monitoring windows on the computer running Middle Control:
| Command | Description |
|---|---|
LIVEVIEW_OPEN / LIVEVIEW_CLOSE | Open / close the Live View window of the currently selected camera (select it first with CAMx) |
MULTIVIEW_OPEN / MULTIVIEW_CLOSE | Open / close the Multi View window (Middle Control Pro — ignored without it) |
📡 Live feedback
Middle Control pushes a live status frame over the same TCP connection, about 4 times per second. The frame reflects the currently selected camera. This lets you read the current state of the gimbal and camera — useful for building feedback displays or reactive workflows.
Camera value feedback is available when Middle Control is connected to an ATEM Switcher or to a camera over Wired LAN. Gimbal angles are included when an APC-R is linked to the camera.
{CAM5;REC1;AF0;DZOOM0;aWB5600;aF0.45;aI6.5;aUI5.4;aTINT10;aISO12;aSHUT1/50;aSAT50;aCONT50;aBLACKLEV0.4;SHAKE_RUN0;ZLOOP_RUN0;PRESETSEQ_RUN1;BRANG_RUN0;PRESETSEQ_BANK1;aPAN523;aTILT124;aROLL890;aZOOM3992;PTS85;ZS24;PRES_D8.0;PRES_ACTIVE0;PRES_E50;REC_LIST[5];CAM_CON_LIST[1,2,5];APCR_CON_LIST[5]}
Each frame is a single line ending in \n: {CAM<id> followed by ;-separated tokens, closed by }. Tokens in order:
| Token | Meaning |
|---|---|
CAM | Selected camera ID |
REC / AF / DZOOM | Recording / Autofocus / Digital zoom on the selected camera (1 or 0) |
aWB | White balance in Kelvin |
aF | Focus position, 0.0 – 1.0 |
aI / aUI | Iris f-number (locked to stops / unlocked) |
aTINT | Tint (signed) |
aISO | Gain in dB |
aSHUT | Shutter (denominator, e.g. 50 or 1/50) |
aSAT / aCONT / aBLACKLEV | Saturation, contrast, black level (ATEM-linked cameras) |
SHAKE_RUN / ZLOOP_RUN / PRESETSEQ_RUN | 1 while that automation is running on the selected camera, else 0 (BRANG_RUN is reserved, always 0) |
PRESETSEQ_BANK | Active presets-sequence bank, 1 – 7 |
aPAN / aTILT / aROLL | Gimbal angles in 1/10th of a degree (APC-R linked) |
aZOOM | Zoom motor position, 0 – 4096 (APC-R linked) |
PTS / ZS | Current pan/tilt speed and zoom speed settings |
PRES_D | Preset transition duration in seconds |
PRES_ACTIVE | 1 while a preset move is running, else 0 |
PRES_E | Preset transition easing, 0 – 100 (- when the camera has no APC-R with firmware 2.0 or later) |
REC_LIST[…] | Camera IDs currently recording |
CAM_CON_LIST[…] | Camera IDs currently connected |
APCR_CON_LIST[…] | Camera IDs with an APC-R gimbal connected |
Depending on the camera brand and how it is connected, some tokens may be absent from the frame, and a value that is not available is sent as - (a dash) — make sure your parser handles both instead of assuming every token is always present and numeric.