Every Roku device — including the Roku TVs built by TCL, Hisense, and Sharp — exposes a small local HTTP API on port 8060 called ECP (External Control Protocol). It's Roku's own developer-facing interface: officially documented at developer.roku.com, used by their first-party mobile app, and enabled by default on every retail unit. There's no cloud dependency, no API key, no OAuth dance — just an HTTP endpoint on your LAN.
It doesn't get much attention outside the Roku channel-developer community, which is a shame — it's a five-endpoint API that turns any Roku TV into a scriptable device. Here's the tour.
Finding your TV on the network
If you already know the TV's IP (Settings → Network → About on the TV itself), skip ahead. Otherwise, Roku devices respond to SSDP discovery — the same protocol Chromecast, printers, and most smart-home gear use:
# Broadcast an M-SEARCH and print any ECP responses
printf 'M-SEARCH * HTTP/1.1\r\nHost: 239.255.255.250:1900\r\nMan: "ssdp:discover"\r\nST: roku:ecp\r\n\r\n' \
| nc -u -w 2 239.255.255.250 1900
Each response carries a LOCATION: http://192.168.x.x:8060/ header. That's your base URL.
The API in five endpoints
TV=http://192.168.1.42:8060
# Device info — model, serial, network config
curl $TV/query/device-info
# List every installed channel with its numeric id
curl $TV/query/apps
# Press a button (POST with an empty body)
curl -d '' $TV/keypress/Home
curl -d '' $TV/keypress/VolumeUp
curl -d '' $TV/keypress/PowerOff
# Launch Netflix (id 12) directly
curl -d '' $TV/launch/12
# Type text into a search field, one character at a time
curl -d '' "$TV/keypress/Lit_h"
curl -d '' "$TV/keypress/Lit_e"
curl -d '' "$TV/keypress/Lit_l"
curl -d '' "$TV/keypress/Lit_l"
curl -d '' "$TV/keypress/Lit_o"
keypress accepts the full physical-remote vocabulary: Up, Down, Left, Right, Select, Back, Play, Rev, Fwd, InstantReplay, Info, plus TV-only additions such as VolumeUp/Down/Mute and InputHDMI1/2/3. The complete key table is in Roku's ECP reference docs.
The browser catch: CORS + mixed content
The obvious next move is a web page with a button grid that fetch()es those endpoints. Two gotchas:
1. ECP responses carry no CORS headers. A cross-origin fetch from a normal page gets blocked — unless you don't need to read the response. Button presses are fire-and-forget, so no-cors mode works fine:
const tv = "http://192.168.1.42:8060";
async function press(key) {
await fetch(`${tv}/keypress/${key}`, { method: "POST", mode: "no-cors" });
}
document.querySelectorAll("[data-key]").forEach((btn) =>
btn.addEventListener("click", () => press(btn.dataset.key))
);
The response comes back opaque, but the TV reacts instantly. Wire that to a grid of <button data-key="VolumeUp"> elements and you have a working remote in ~30 lines. Reading state (/query/apps, /query/device-info) from the browser is where you'll need a tiny local proxy or a native shell, since those responses you actually need to parse.
2. Mixed-content blocking. Pages served over HTTPS can't call plain-HTTP LAN addresses. Either serve your remote page over HTTP locally (fine on the same LAN), or route commands through a native layer. This is the main engineering reason most polished implementations — like this browser-based Roku TV remote for Hisense — pair the web UI with a native transport for HTTPS-served production rather than raw browser fetches.
What ECP is (and isn't) good for
Great for:
-
Home automation — an ECP
PowerOffinside a "goodnight" scene is one HTTP call. Home Assistant, Homebridge, and Node-RED all have Roku integrations that use ECP under the hood. - Accessibility — a phone-sized web page with large buttons beats a 40-button plastic remote for a lot of people. Same for high-contrast or dwell-click variants.
-
Debugging smart-TV apps —
curlscripts can drive reproducible UI walkthroughs, which is useful when you're figuring out why a Hisense Roku TV suddenly stops responding to its physical remote. -
Kiosk-style setups — spin up a bare
<div>of buttons on an old phone and mount it on the wall as a permanent remote.
Not designed for:
- First-time TV setup. ECP requires the TV to be on your network — you can't use it to complete out-of-box Wi-Fi setup.
- Cross-network control. ECP is LAN-only by design. If you want to control the TV from outside your home, you're building a proxy.
- Content protection surfaces. DRM-gated content (Disney+, Prime) works fine when launched via ECP, but ECP itself only speaks the remote-key vocabulary.
Why it's stable
ECP has been part of the Roku OS since roughly 2011 and hasn't had a breaking change I've seen in the last five years. It's the transport Roku's own mobile apps rely on — meaning Roku has a strong incentive to keep the surface stable across firmware updates.
If you build something fun with it, drop it in the comments. And if you have a Hisense Roku TV specifically, our team maintains a free browser Roku remote for Hisense models built on top of this exact protocol — try it side-by-side with your own implementation.
Top comments (0)