Skip to main content
You need an account (sign-up is open; new accounts start with $5 of credit), an API key from Dashboard → API keys, and sufficient trial credits. These examples use curl and jq.
1

Set your API key

Keep your key out of source control. Set it as an environment variable in your terminal or secret manager.
Confirm the account:
2

Create a 15-minute session

Choose a new idempotency key for this logical session. Keep that same key and request body if you need to retry an ambiguous creation response.
Successful admission returns HTTP 202 with an id, a state, and an absolute expires_at timestamp. Keep the ID to operate on this session.If the request times out or the connection drops, recover the create receipt before starting another phone.
3

Wait for ready

Poll the session until state is ready. Treat error, closing, or a 404 as a reason to stop waiting and inspect the result. A two-second polling interval is a client example, not a promised startup time.
ready means the API can use the phone. The browser viewer connects separately.
4

Connect with ADB

The ready session carries its ADB address and unlock code:
Response
Connect stock adb and unlock once. This is the only step that needs to run where the phone is used; it needs no API key.
5

Drive it with phone-harness

phone-harness (pip install phone-harness) gives you and your agents screenshots, taps, typing and text reading over that connection:
Plain adb works too: adb install app.apk, adb shell input tap 540 1200, adb exec-out screencap -p > screen.png.
6

End the session

HTTP 200 with released: true confirms cleanup. HTTP 202 with cleanup_pending: true means closure is accepted and cleanup is still running. Your capacity is released after cleanup completes.
The 900-second duration includes provisioning. There is no separate full 15-minute usage period after readiness. Ending a session deletes its temporary phone and app data.

Connect a coding agent

Give Claude Code, Codex or your own agent fleet a phone each.

Connect with ADB

Sharing, reset, off/on, Appium, reconnects.

The same flow in Python

The steps above, as one program using Python’s standard library. It gives creation a stable idempotency key, waits for readiness within its own budget, connects ADB for a screenshot, and requests cleanup in finally, recovering the create receipt if the POST’s response was lost.
This is a real API example. Running it with a valid account key creates a metered session. It contains no credentials.
If closure returns cleanup_pending: true, poll the create receipt until cleanup_complete: true. A failed receipt lookup is not proof that no phone was created: keep the request key and recover it. In a production integration, store request keys durably and recover unfinished requests when your process restarts.