Skip to main content
You can drive a phone without the SDK: allocate a phone, open its control_url, and send DCP frames. This is the same socket the SDK uses — here you speak to it directly. The examples use Python’s websockets library, but nothing is Python-specific. Any WebSocket client works.

Before you start

  • An API key — create one in API Keys. See Authentication.
  • A dedicated phone ID — choose an idle phone in Phones or run axilio phones list.
  • A WebSocket client. For the examples: pip install axilio websockets.

1. Get a phone and its control URL

Allocate a phone through the REST API or the SDK. The allocation returns a control_url — a WebSocket scoped to this one session:
The control_url is self-contained and embeds its credential, so you can connect without extra headers. Pass it directly to your WebSocket client. Never put it in logs, shell history, tickets, or chat, and do not cache it across sessions. It stops working when the session ends.

2. Open the socket and handshake

Send Protocol.handshake first. It returns the phone’s protocol version, device descriptor, and the exact set of methods it supports — gate your code on that instead of assuming:

3. Send a command

Commands are { "id", "method", "params" }; the phone replies with { "id", "result" } on success or { "id", "error" } on failure. Tap a pixel:

4. Read the screen

Screen.observe returns the on-screen text and icons with their bounding boxes — enough to decide where to tap next:

Correlating replies

Responses can arrive in any order, so match a reply to its command by id instead of assuming the next frame is the answer. A frame with no id is a notification, not a response. A small pattern: keep an outstanding-id map, increment a counter per command, and resolve each reply against it. The SDK does exactly this for you. The idempotencyKey is separate from the request id. Generate one UUID per logical Touch.* or Keyboard.* command. Reuse that key only if you must resend the same command after a dropped connection. See Reconnect and resume.

Next steps

Message reference

Every method, its params, its result, and the error shape.

Reconnect and resume

Handle close codes, cursors, replay, and safe resends.

Live telemetry

Stream the session’s Telemetry frames on a second socket.

Use the SDK instead

Selectors, waiting, and retries over DCP.