Phonebox / Docs
API reference

Terminal setup

The two requests a terminal or an agent makes to get an API key without the console, after a person confirms a short code in the browser.

View as Markdown

Terminal setup gives a terminal or an agent its first API key. The terminal starts a setup request, a person opens a link, signs in and confirms the code they see in their terminal, and the terminal then receives a new key. phonebox setup in the CLI runs these requests for you.

These are the only endpoints that take no API key. Everything else in Conventions applies: JSON bodies are checked strictly, errors use the envelope, and a request that carries an Origin header fails with 403 browser_requests_not_allowed.

Start terminal setup

POST /v1/setup needs no API key.

Starts a setup request. The body is optional.

FieldTypeDefaultRules
clientstringNoneA name for the terminal, from 1 to 60 printable ASCII characters, such as Claude Code on tals-mbp. The person sees it when they confirm, and the key is named after it.
POST /v1/setup
{
  "client": "Claude Code on tals-mbp"
}
curl https://phonebox.dev/v1/setup \
  -H "Content-Type: application/json" \
  -d '{"client": "Claude Code on tals-mbp"}'

It answers 201 Created:

Response: setup
{
  "setup_token": "pbs_Rk3vQ8bN2xLm5TyW9pZc4HdJ7aGf6sEu1oVi0XqBnKw",
  "user_code": "K7QM-2XHD",
  "verification_url": "https://phonebox.dev/connect?code=K7QM-2XHD",
  "expires_in": 900,
  "interval": 3
}
FieldTypeMeaning
setup_tokenstringThe terminal's secret, pbs_ followed by 43 characters. Only it can collect the key, so never show it or send it anywhere but the poll.
user_codestringThe code the person checks against their terminal. On its own it gives no access.
verification_urlstringWhere the person signs up or signs in and confirms the code. Show it, or open it in their browser.
expires_inintegerThe seconds the person has to confirm: 900, which is 15 minutes.
intervalintegerThe seconds to wait between polls: 3.
ErrorWhen
400 validation_failedclient is empty, longer than 60 characters or not printable ASCII, or the body has another field.
429 rate_limitedMore than 10 requests in a minute from one IP address.

Poll terminal setup

POST /v1/setup/token needs no API key.

Asks whether the person has confirmed the request. Send it every interval seconds until it answers approved or fails.

FieldTypeRules
setup_tokenstringRequired. The setup_token that starting setup returned.
POST /v1/setup/token
{
  "setup_token": "pbs_Rk3vQ8bN2xLm5TyW9pZc4HdJ7aGf6sEu1oVi0XqBnKw"
}

While the person hasn't answered, it returns 200 OK with:

Response: setup status
{
  "status": "pending"
}

Once they have confirmed, it returns the key, exactly once:

Response: setup status
{
  "status": "approved",
  "api_key": "pbx_Hq2sT7vYc4Kd9mLx3NbW6pZr8Jf1GaEu5oVi0XqBnRk",
  "project": "My project"
}
FieldTypeMeaning
statusstringpending or approved.
api_keystringWith approved: the new key. Store it now, because no later request returns it.
projectstringWith approved: the name of the project the key belongs to. A new account gets a first project named My project.

The key is an Agent key with no expiry, named after client, such as Claude Code on tals-mbp (terminal setup), or Terminal setup without one. It is listed on the console's API keys page, where it can be revoked. Authentication and keys says what an Agent key can do.

ErrorWhen
400 validation_failedsetup_token is missing or isn't a setup token, or the body has another field.
403 setup_deniedThe person declined the request in the browser.
404 not_foundNo setup request has this token.
409 setup_expiredThe code wasn't confirmed, or the key wasn't collected, within 15 minutes.
409 setup_usedThe request already delivered its key.
409 key_limitThe project the person chose already has 50 active keys.
429 rate_limitedMore than 60 polls in a minute for one token.

After setup_denied, setup_expired or setup_used, start a new request. The key is never sent twice, so a poll whose answer was lost ends in setup_used: start again, and revoke the lost key in the console.

Next, the account needs credit before it can run a phone: create a checkout link with the new key.

On this page