# Devices

> What a AkaPhone device is, its lifecycle from queued to terminated, profiles, idle stop, and what counts toward your concurrency limit.

Source: https://akaphone-docs.pages.dev/concepts/devices/

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](https://akaphone-docs.pages.dev/concepts/snapshots/).

## Lifecycle

```text
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](https://akaphone-docs.pages.dev/concepts/streaming/) 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](https://akaphone-docs.pages.dev/concepts/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

```json
{
  "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](https://akaphone-docs.pages.dev/concepts/snapshots/), which stay on the host that took them.

Full endpoint reference: [Devices API](https://akaphone-docs.pages.dev/api/devices/).
