Devices
What a AkaPhone device is, its lifecycle from queued to terminated, profiles, idle stop, and what counts toward your concurrency limit.
A device is one Android 14 system running in its own container on a AkaPhone host. It behaves like a phone: it has a screen you can watch, it accepts taps and typing, it can install APKs, and an agent can drive it. Devices are created on demand and destroyed when you stop them. Nothing carries over between devices unless you use a snapshot.
Lifecycle#
queued ──▶ creating ──▶ running ──▶ stopping ──▶ terminated
│ │ │
│ └──▶ error └──▶ lost
└──▶ error (no_capacity after 10 min) / terminated (stopped while queued)| Status | Meaning | Billed |
|---|---|---|
queued |
Accepted, waiting for a free slot on a host. | No |
creating |
Booting on a host. | No |
running |
Ready. You can stream, send input, install apps and run tasks. | Yes, per started minute |
stopping |
A stop was requested; the host is shutting it down. | No |
terminated |
Gone. Final. | No |
error |
Could not be created. error says why, for example no_capacity. Final. |
No |
lost |
The host holding it stopped responding. Minutes after the host's last heartbeat are refunded. Final. | Refunded |
Most operations (input, screenshots, tasks, APK installs, snapshots) need the device to be running and return 409 conflict otherwise, with a message such as Device is creating, not running.
Waiting for a device#
POST /v1/devices returns as soon as the device is queued. Pass "wait": true (or ?wait=true) to hold the request until the device leaves queued/creating, for at most 90 seconds. If it is still starting when the wait ends, you get the device in its current status with 201 and the response header X-Wait-Timed-Out: 1; poll GET /v1/devices/:id from there.
A device that cannot be placed within 10 minutes moves to error with "error": "no_capacity". Queued time is never billed.
Stopping#
DELETE /v1/devices/:id stops a device and returns it as stopping (or terminated if it was still queued). It is safe to call twice. AkaPhone also stops a device for you when:
| Reason | When |
|---|---|
idle |
No activity for 30 minutes. Activity is any input, task, task step, APK install, or an open live-view connection. |
credits |
Your balance is below 1 credit when the next minute is due. |
user |
You (or a teammate with your key) stopped it, or the account was suspended. |
lost |
The host failed. |
Viewers of the live stream get a device.stopped event with the reason.
Profiles and Android version#
| Field | Default | Notes |
|---|---|---|
profile |
pixel_8 |
Screen geometry; see the table below. Any other value is 400 invalid_request. |
android |
"14" |
Android 14 is the image every host carries. |
region |
eu-central |
The only region today. |
name |
none | Up to 64 characters, for your own reference. |
| Profile | Name | Screen | dpi |
|---|---|---|---|
pixel_8 |
Pixel 8 | 720×1560 | 320 |
pixel_tablet |
Pixel Tablet | 1280×800 | 240 |
small_phone |
Small phone | 540×960 | 240 |
GET /v1/profiles returns the current list (no authentication needed), and the MCP tool profiles_list does the same for agents.
Devices are Android Open Source Project builds without Google Play Services, so apps that need the Play Store or Play Integrity will not work. Install your own APKs instead.
Concurrency#
Your plan limits how many devices you can have at once: 1 on Free, 3 on Dev, 5 on Team. Devices that are queued, creating or running count; stopping and finished devices do not. Creating one more returns 409 concurrency_limit. See Credits and plans.
The check is atomic, so parallel create requests cannot exceed the limit.
Billing#
Minutes are prepaid and charged one at a time: minute 1 when the device becomes running, minute 2 sixty seconds later, and so on. A device that runs for 4 minutes 10 seconds costs 5 credits. Creating a device needs a balance of at least 1 credit (402 insufficient_credits otherwise). Each device's charged minutes are in billed_minutes.
The device object#
{
"id": "dev_s6zr7mr4f2f1",
"name": "checkout-test",
"status": "running",
"profile": "pixel_8",
"android": "14",
"region": "eu-central",
"node_id": "nod_01m5vqsywg84jv64rmmqf9",
"snapshot_id": null,
"created_at": "2026-10-26T09:14:02.000Z",
"ready_at": "2026-10-26T09:14:09.000Z",
"terminated_at": null,
"last_activity_at": "2026-10-26T09:16:40.000Z",
"billed_minutes": 3,
"error": null
}Device ids are exactly 16 characters (dev_ and 12 lowercase base32 characters). node_id identifies the host; it matters only for snapshots, which stay on the host that took them.
Full endpoint reference: Devices API.