The tap someone had to make at 3am
A cross-border e-commerce team had an alert in their support system for problem orders. When one appeared, someone had to open the phone app and resubmit that order.
The alert came from a system. The phone action needed a person. A notification at three in the morning meant someone getting up to tap a button.
What they wanted was for the support system to do the tapping.
That is what the open API is for. The central control does not know when work is due; the external system does. Turning device operations into HTTP calls means any program that can send a request can drive a phone — and iPhone automation stops being about sitting at the central control and becomes one request.
1. Decide whether you need this at all
The API is not the default choice. Check the situation first.
Three cases that suit the API:
- The trigger lives outside the central control — an order system, an alerting system, your own back end. They know when to act; the central control does not
- You want to own the scheduling — your own scheduler, your own retry policy, rather than the central control timer
- Results need to land in your system — execution state written back to your database rather than sitting in the execution history
Where you do not need it:
A script that simply runs on a schedule is served by the central control own scheduler. Adding an API layer for the sake of it raises maintenance rather than lowering it.
The test in one line: if the central control can decide when to do the work, skip the API; if that decision comes from another system, you need it.
2. What the API looks like
Three things settle it; everything else is filling in blanks. There is no SDK and none is needed — these are ordinary HTTP calls, which is why a team already writing iOS automation scripts can adopt them with a request library.
Address: the central control machine plus port 8019. Locally that is http://127.0.0.1:8019; from another machine, use that machine’s LAN address.
Method: HTTP POST, Content-Type: application/json, parameters in the body.
Return convention: JSON, with a code field — 0 means success, anything else means failure, and the reason is in msg.
Wrap that once at the start:
import requests
BASE = "http://127.0.0.1:8019"
def openapi_post(path, body=None):
r = requests.post(f"{BASE}{path}", json=body or {}, timeout=30)
r.raise_for_status()
data = r.json()
if data.get("code") != 0:
raise RuntimeError(data.get("msg") or data)
return data
Every call afterwards goes through it. Python needs only requests; Node.js 18+ has fetch built in with nothing to install.
3. Step one: get a deviceId
Every device-level endpoint needs a deviceId, so the first call is always the device list:
devices = openapi_post("/openapi/deviceList", {"deviceId": "", "groupId": ""})
print(devices)
Two parameters worth understanding. An empty deviceId means “do not filter by device”; an empty groupId means “do not filter by group”. To take one group only, fill in groupId.
One thing that catches people out: deviceId and the alias are not the same. An alias is a name you set in the central control for people to read; API calls must use the deviceId. Take it from the device list response rather than trying the alias.
4. Step two: the three-call USB HID sequence
This is the most practically useful part of the article. The USB HID endpoints cannot start with a tap; the order matters:
DEVICE_ID = "90e2f3834c0977205e441aa664916a9bdde81e8d" # from the device list
# 1) Open the session
openapi_post("/openapi/usbhidSessionStart", {"deviceId": DEVICE_ID, "gate": True})
# 2) Set the screen resolution (coordinate conversion depends on it)
openapi_post("/openapi/usbhidSetScreenSize", {"deviceId": DEVICE_ID, "w": 1170, "h": 2532})
# 3) Only now can you tap
openapi_post("/openapi/usbhidClickPoint", {"deviceId": DEVICE_ID, "x": 200, "y": 400})
Why each of the three exists:
Opening the session — the gate parameter means “try enhanced compatibility”, which older systems ignore, so true is the usual value. An existing session is reused, so there is no need to reopen it each time.
Setting the screen size — this is the step most often skipped, after which every tap lands in the wrong place. HID sends absolute pixel coordinates, so without knowing how large the screen is, it cannot convert them. The w and h values must match the resolution you see in the mirroring view or screenshots.
Tapping — x and y are pixel coordinates. If devices have different resolutions, compute these per device rather than hard-coding them.
The order only matters when establishing the session. Once the session is open and the size is right, the next few hundred taps are just the third call repeated.
Node.js follows the same structure with fetch:
const BASE = "http://127.0.0.1:8019";
async function openapiPost(path, body = {}) {
const res = await fetch(`${BASE}${path}`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
const data = await res.json();
if (data.code !== 0) {
throw new Error(data.msg || JSON.stringify(data));
}
return data;
}
5. What the eleven modules cover
The endpoints are grouped into eleven sets. This table finds them faster than paging through documentation.
| Module | What it covers |
|---|---|
| Central control | Device list, starting and stopping scripts |
| Automation · Actions | Taps, swipes, input, opening and closing apps |
| Automation · Screenshot | Screenshots and image streams |
| Automation · Start/stop | Starting and releasing automation, tunnels, battery |
| Automation · Album | Uploading images and videos, clearing the album |
| Automation · Files | Pushing and pulling device files |
| Automation · IME | Custom keyboard, clipboard forwarding |
| Automation · Bluetooth BLE | HID actions over a Bluetooth board |
| Automation · USB HID | No hardware — drive the phone over a cable |
| Helper assistant | Assistant clipboard, album, port forwarding |
| Shortcuts assistant | Requires the shortcuts assistant program |
Actions is the group you will use most : tap, double tap, long press, swipe, multi-touch, text input, keyboard simulation, open/close/install/uninstall apps, home, restart, lock and unlock, screen orientation, coordinate calibration, and node capture. That covers nearly every step a script takes.
Worth noting separately: USB HID is the only hardware route that needs no Bluetooth or OTG board. One data cable simulates taps and typing, which suits setups already running cables.
6. Central control endpoints: devices and script control
So far this has been about operating one device. The central control endpoints handle management.
They include the device list and starting/stopping scripts. The typical pattern is two stages:
- Call the device list to get
deviceIdfor the batch - For each device, start the script running your compiled logic
That combination suits “an external policy decides which devices run” — by order ownership, or by rotating through groups.
With many devices, do the grouping in the central control first. The API is per deviceId, so your code loops; grouping gives that loop a definite source instead of pulling every device each time. For iOS cluster control at any real scale, this step is standard.
7. Connecting to an AI system
If the goal is to let an AI assistant schedule the phones, there is a lighter route: register the endpoints as MCP tools.
The difference: calling the open API directly means writing the logic that decides which endpoint and which parameters. Registering as MCP lets the assistant pick the tool and assemble the arguments itself, which suits “let the model decide the next step”.
The two coexist well. Fixed, predictable operations go direct; anything needing judgement on the spot goes through MCP.
8. Practical points that come up in production
Error handling. Failures fall into two kinds: transport or service problems (central control down, port unreachable) and business problems (device offline, licence expired, coordinate out of range). The first is worth retrying; the second is not. Split them on msg rather than retrying everything.
Timeouts. The documentation example uses 30 seconds. Action endpoints usually return in a few hundred milliseconds, so a long timeout only slows down failure detection — but screenshots and uploads move large files and need headroom. Set these per group rather than one global value.
Coordinate maintenance. This is where an API-driven setup breaks first. With mixed device models, never hard-code coordinates — convert per resolution, or better, use the node capture endpoint to get an element coordinate and tap that. The second is far more durable.
What to log. Five things: device ID, endpoint, request parameters, returned code and msg, and a timestamp. With those on hand, a problem can be traced directly instead of reconstructed from memory.
The split with scripts. A common mistake is rewriting the whole flow as API calls. The cheaper arrangement is to keep the flow inside the on-device script and let the API trigger it and collect results. Fewer calls, fewer round trips, fewer places to fail.
9. Which approach to use, by need
The sections above cover how to call the API. This one covers when to use which approach. Four needs cover most situations, and they can coexist on the same set of devices.
| Your need | Recommendation | Why |
|---|---|---|
| Run a fixed flow on a schedule | EasyClick central control scheduler | No API layer needed; the central control can decide timing itself |
| An external system decides when to trigger | EasyClick open API, called directly | Port 8019, HTTP plus JSON, wired straight into your existing system |
| Let an AI decide the next step | Register EasyClick as MCP tools | The assistant picks tools and arguments; you do not write the dispatch logic |
| Precise element targeting plus a full on-device flow | EasyClick proxy mode with scripts, API for triggering only | The flow stays on the device: fewer round trips, fewer places to fail |
All four use the same central control and the same device licences. Real projects mix them: fixed work on a schedule, external triggers over the API, judgement calls through MCP, and the on-device actions always handled by a script.
A common mistake is rewriting the entire flow as API calls. The recommended split is: the script owns what happens on the device, while the API tells it to start and collects the result. Fewer calls, a shorter chain, and easier troubleshooting.
10. Common questions
Does it only work on the local network?
By default, yes. Port 8019 belongs to the central control machine, so anything that can reach that machine can call it. Across networks you need a tunnel, or the cloud control product line.
Can I command many devices at once?
The API is per deviceId, so concurrency is your code’s job — a thread pool, for instance. Note that one device runs one task at a time, so the parallelism is across devices, not within one.
What licence does it need?
Running scripts requires a USB device licence; mirroring requires a USB mirroring licence. They are not the same. There are endpoints to query licence state, so check before starting a batch rather than discovering it halfway.
The code is non-zero and msg is unclear. What then?
Check the device-level causes first — offline, unlicensed, session not open — which cover most of it. Otherwise look up the endpoint name in the relevant documentation module; every endpoint documents its parameters and response.
That team ended up wiring it like this: the alerting system spots a problem order, calls the device list to find the right machine, runs the resubmit script once, and writes the outcome back to its own ticket table. The three-in-the-morning tap went from waking a person to sending a request.
To see how the scripts themselves are written, read how to write iOS no-jailbreak scripts; for USB HID internals and the full API, see USB HID explained; for connecting the API to AI systems, read cloud control API with MCP.
About EasyClick: A phone automation AI-agent platform covering Android no-root, iOS no-jailbreak (proxy / Bluetooth HID / OTG HID) and HarmonyOS Next, offering script development, Apple cluster control, local central control & mirroring, and cloud control systems. → Explore all products
Ready to build it for real?
Every approach in this article can be built on the EasyClick phone automation platform — full documentation, developer tools and cluster/cloud-control products, free to try.