# Concepts

Source: https://phonebox.dev/docs/getting-started/concepts

> Phones, sessions, statuses, parking, timers, billing and limits.



## Phones [#phones]

A phone is a persistent Android device in the cloud. Its ID starts with `ph_`, as in `ph_7kx2m6q4v3ta`. A phone keeps its installed apps, files and signed-in accounts for as long as it exists, whether it is running or parked. It is gone only when you delete it, or when it fails, because a failed phone can't be started again.

You can give a phone a `name` and up to 20 `metadata` pairs of your own, such as a customer ID, and find phones by them later. A phone can also ask for a `country` when you create it: where it appears to be, from the list that `GET /v1/account` returns.

## Sessions [#sessions]

A session is one billed period on one phone, from the moment it starts until it parks. Its ID starts with `ses_`. Creating a phone opens its first session, and each start after a park opens a new one. While a session is open, the phone's `session` field shows when it started, its timers and when it will park. `GET /v1/phones/{id}/sessions` lists a phone's sessions with what each one cost.

## Statuses [#statuses]

| Status        | Meaning                                                                                                                                                                                                  | Billed                                           |
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ |
| `creating`    | The phone is being set up for the first time. This often takes about a minute.                                                                                                                           | Yes                                              |
| `starting`    | The phone is resuming after a park, or restarting after a reboot.                                                                                                                                        | Yes                                              |
| `ready`       | The phone's screen and a screenshot have both answered, so you can use it.                                                                                                                               | Yes                                              |
| `parking`     | A park was requested and the device is stopping.                                                                                                                                                         | No: billing stopped when the park was requested. |
| `parked`      | The phone is stopped. Its apps, files and sign-ins are kept.                                                                                                                                             | No                                               |
| `unavailable` | The phone is under maintenance, or its state is unknown. Its session was closed, and you can start it again later.                                                                                       | No                                               |
| `failed`      | Setting up the phone failed, or its device was lost. The phone's `failure` field says why. It can't be used again, so create a new phone, with a new idempotency key if you created this one with a key. | No                                               |
| `deleted`     | You deleted the phone. This can't be undone.                                                                                                                                                             | No                                               |

Only a `ready` phone accepts screen, action, app, file and device requests. Any other status answers with an error whose `next` field names the way forward, such as starting the phone.

## Parking and timers [#parking-and-timers]

Parking stops a phone and its billing while keeping everything on it. Park a phone yourself whenever you're done with it. Phonebox also parks it for you:

* A phone parks when its `idle_timeout` has passed since its `last_active_at`: the moment it became ready, or the last time a request addressed it since. The default is 300 seconds, and you can choose from 60 to 3600.
* A phone parks when its session reaches its `max_duration`, however busy it is. The default is up to 900 seconds, shortened automatically to available credit and the monthly spending limit, and you can choose from 60 to 10800, which is three hours.

Any API or MCP request that addresses a ready phone counts as activity, including reads, and so does a live view that is open on it. Three kinds of request don't count: a long poll that waits for the phone to park, a request refused with `401` or `403`, and any request made with a key that is revoked or expired. `last_active_at` moves to the time of a request at most once every 15 seconds, so a phone can park up to about 15 seconds sooner than `idle_timeout` after your last request. The phone's `session.parks_at` field says when it will park, which is `last_active_at` plus `idle_timeout` or the session's deadline, whichever comes first, and `park_reason` says which rule will park it: `idle` or `max_duration`.

You set both timers when you create or start a phone. Starting a phone that is already running renews it: its deadline moves to `max_duration` from now. Phonebox also parks running phones when a project is frozen or during maintenance.

## Billing [#billing]

A phone costs $0.06 a minute, which is $0.001 a second, while it is `creating`, `starting` or `ready`. Billing is per second, with a 60-second minimum for each session. A parked phone costs nothing.

The clock starts when Phonebox accepts your create or start request. It stops when you ask to park, when Phonebox decides to park the phone, or when the phone becomes unavailable or fails. Any time the device takes to stop after that is not billed.

A session that ends before the phone was ever ready costs nothing, unless you parked or deleted the phone yourself. In that case it is billed like any other session.

### Reservations [#reservations]

When a session starts, Phonebox reserves credit for its whole `max_duration`: $3.60 for the default hour. The session's `reserved_usd` field shows the amount. When the session ends, you're charged for the seconds it ran, never more than the reservation, and the rest is released. Renewing a running phone reserves only the extra time.

If your balance, minus what is already reserved, can't cover a new reservation, the request fails with `402 insufficient_credits`. Its `details.max_affordable_seconds` says the longest `max_duration` you can afford right now. Because of the reservation, your balance can never go below zero.

### Spending limit [#spending-limit]

Each project has a monthly spending limit, $100 by default, which you change in the console's Settings. A session whose reservation would take the month's spending past the limit fails with `402 spend_limit_reached`. A limit of $0 stops all spending.

You buy credits in [Billing](/app/billing), from $10 to $1,000 at a time. Credits don't expire, and there are no subscriptions or automatic top-ups. `GET /v1/account` shows your balance, what is reserved and what you spent this month:

```json title="Response: account"
{
  "project": "Checkout QA",
  "balance_usd": "21.400000",
  "reserved_usd": "3.600000",
  "spend_limit_usd": "100.000000",
  "spent_this_month_usd": "4.120000",
  "limits": { "phones": 10, "running": 2 },
  "running": 1,
  "phones": 3,
  "price": { "per_minute_usd": "0.060000", "minimum_seconds": 60 },
  "countries": [{ "code": "AR", "name": "Argentina" }, { "code": "US", "name": "United States" }]
}
```

The API writes money as a decimal string of US dollars with six places, so that no amount is rounded.

## Limits [#limits]

| Limit                                                    | Default                                   | When you exceed it                    |
| -------------------------------------------------------- | ----------------------------------------- | ------------------------------------- |
| Phones in a project, not counting deleted or failed ones | 10                                        | `409 phone_limit_reached`             |
| Phones running at once                                   | 2, which you can lower in Settings        | `409 running_limit_reached`           |
| Requests                                                 | 600 a minute for each API key             | `429 rate_limited` with `Retry-After` |
| Creates, starts, parks and deletes                       | 60 a minute for each project              | `429 rate_limited` with `Retry-After` |
| Actions in one batch                                     | 20, with at most 60 seconds of waiting    | `400 validation_failed`               |
| File uploads and downloads                               | 4 MB                                      | `413 payload_too_large`               |
| Live link lifetime                                       | 60 seconds to 24 hours, 1 hour by default | `400 validation_failed`               |
| Monthly spending                                         | $100                                      | `402 spend_limit_reached`             |
| Active API keys                                          | 50                                        | The console refuses a new key.        |

The running limit counts all of your projects together. To run more phones at once, email [team@phonebox.dev](mailto:team@phonebox.dev). A failed phone holds no device, so it doesn't count toward the phone limit. When Phonebox as a whole has no phones free, a create or a start fails with `503 capacity_unavailable`. Its `retryable` field says what that means. When it is `true`, nothing is lost: wait for `Retry-After`, about 30 seconds, and send the same request again, a few times at most. That covers a create that was refused, which made no phone, and a start whose phone parked again, which you start again with its apps and sign-ins. When it is `false`, a new phone could get no device and has failed, so its `status` is `failed`: create another phone with a new key. A phone is gone only when its `status` is `failed` or `deleted`, never because an error names it in `details.phone`.

## One agent per phone [#one-agent-per-phone]

Phonebox doesn't lock a phone to one caller. If two agents act on the same phone at once, each acts on screens the other changed. Give each agent its own phone, and each end user their own phone too, so that their apps and sign-ins stay apart.
