Phonebox / Docs
Getting started

Authentication and keys

Project API keys, the Agent, Admin and Read-only presets, scopes, keys limited to certain phones, and expiry.

View as Markdown

Every request to the API, the CLI, the SDK and the MCP server authenticates with a project API key, sent as a bearer token:

Authorization: Bearer pbx_…

A key belongs to exactly one project, and it selects that project: you never send a project ID. Your console session is separate. Signing in to the console doesn't let a browser call the API.

Create a key

Open API keys in the console and create a key. Give it a name that says where it runs, choose its preset, and choose when it expires.

phonebox setup creates a key too: an Agent key without an expiry, named after the terminal that asked for it, and saved on that machine. It is created only after you sign in and confirm the terminal's code in your browser. No API call creates a key without that confirmation, and Admin, Read-only and phone-limited keys are created only in the console.

The console shows the full key once, right after you create it. Copy it into your server's environment or your secret manager before you close the dialog. Phonebox stores only a SHA-256 hash of the key, so it can't show the key again. Later, the console identifies the key by its name and a short prefix such as pbx_AbCd…wXyZ. If you lose a key, create a new one.

A key is pbx_ followed by 43 characters. A project can have up to 50 active keys.

Presets and scopes

A key's preset decides its scopes:

PresetScopesWhat it can do
Agent, the defaultphones:read, phones:control, phones:createCreate, start, use and park phones. It can't delete them.
AdminThe Agent scopes plus phones:deleteEverything an agent key can do, and permanently deleting phones with their data.
Read-onlyphones:readSee phones, their screens, apps and files, and the account. It can't create, start, use or park phones, and its requests don't keep a phone awake.

The console shows all three presets side by side, with Agent preselected. Admin is never preselected: choosing it asks you to confirm that you understand the key can permanently delete phones, including their apps and signed-in accounts. Give agents Agent keys, dashboards and monitors Read-only keys, and keep Admin keys for the scripts that clean up.

Each scope allows these requests:

ScopeRequests
phones:readListing and reading phones and their sessions, observing the screen, screenshots, listing apps and installs, listing and downloading files, and the account.
phones:controlStarting, parking, renaming and heartbeats, actions, installing and uninstalling apps, uploading and deleting files, the clipboard, location, locale, timezone, reboots, live links and credit checkout links.
phones:createCreating phones.
phones:deleteDeleting phones.

A request without the scope it needs fails with 403 insufficient_scope, and details.required names the missing scope.

Keys limited to certain phones

When you create a key, you can limit it to between 1 and 20 phones. Such a key sees only those phones, in lists and in the account's counts, and it can use only them. A request for any other phone fails with 403 phone_not_allowed. Of the project's uploads, it sees and uses only the ones it created; any other answers 404 upload_not_found.

A limited key can never create phones, whatever its preset. Creating one fails like this:

Response: error
{
  "error": {
    "type": "permission_error",
    "code": "insufficient_scope",
    "message": "This key doesn't have permission for this action.",
    "retryable": false,
    "next": "Use a key that isn't limited to specific phones.",
    "request_id": "req_k4m2n7p3q5r6",
    "details": { "required": "phones:create" }
  }
}

Limited keys suit products that serve several customers: a worker that acts for one customer holds a key that reaches only that customer's phones. See Concepts for how to organize phones.

Expiry and revocation

A key expires after 30 days, 90 days (the default) or a year, or never. An expired key fails with 401 key_expired. A key you revoke in the console fails with 401 key_revoked from then on. A missing or malformed key fails with 401 invalid_api_key.

To rotate a key, create the new key, deploy it where the old one ran, check a request such as GET /v1/account, and then revoke the old key.

Call the API from a server

Phonebox refuses any request that carries an Origin header, which every browser adds, so a key can't be used from a web page:

Response: error
{
  "error": {
    "type": "permission_error",
    "code": "browser_requests_not_allowed",
    "message": "Call the API from a server, not a browser.",
    "retryable": false,
    "next": null,
    "request_id": "req_5f7a2c4d6e3b",
    "details": {}
  }
}

The same rule applies to the MCP server. If your product has a web front end, call Phonebox from your backend and pass on only what your user needs. For a person who has to see or control a phone, create a live view link instead of exposing a key.

Keep keys secret

  • Keep keys in environment variables or a secret manager, never in code, commits or logs.
  • Don't paste a key into an agent's prompt. Agents read it from PHONEBOX_API_KEY.
  • Revoke a key as soon as you think it leaked, and check the console's activity for calls you don't recognize.

On this page