> ## Documentation Index
> Fetch the complete documentation index at: https://docs.beta.b3os.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Start a device login

RFC 8628 device authorization request, used by `b3os login`. Show the user `user_code` and send them to `verification_uri` (or `verification_uri_complete`), then poll the token endpoint every `interval` seconds. `scope` is a space-separated list of the scopes the token should have (default `*`, limited at approval to the approver's). Too many device logins from one address get `429` with `error: rate_limited`. 

` POST /v1/auth/device/code `

Start a device login

RFC 8628 device authorization request, used by `b3os login`. Show the user `user_code` and send them to
`verification_uri` (or `verification_uri_complete`), then poll the token endpoint every `interval` seconds.
`scope` is a space-separated list of the scopes the token should have (default `*`, limited at approval to
the approver's). Too many device logins from one address get `429` with `error: rate_limited`.


## Servers

- ` https://beta-api.b3os.org ` — API (API keys and CLI tokens)

- ` https://beta.b3os.org ` — Dashboard (session cookie and CSRF header; same paths)

## Request body (required)

Content type: ` application/json `

- ` value `: type ` object `

  - Required fields: ` client_id `

  - ` client_id `: type ` string `

    - enum: ` ["b3os-cli","b3os-mcp","b3os-sdk"] `

  - ` scope `: type ` string ` — Space-separated scopes.

    - default: ` "*" `

    - maxLength: ` 2048 `

Example:

```json
{
  "client_id": "b3os-cli"
}
```

## Responses

### ` 200 ` — The device and user codes.

Content type: ` application/json `

- ` value `: type ` object ` — RFC 8628 §3.2.

  - Required fields: ` device_code `, ` user_code `, ` verification_uri `, ` verification_uri_complete `, ` expires_in `, ` interval `

  - ` device_code `: type ` string `

  - ` user_code `: type ` string `

  - ` verification_uri `: type ` string `; format ` uri `

  - ` verification_uri_complete `: type ` string `; format ` uri `

  - ` expires_in `: type ` integer `

  - ` interval `: type ` integer `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "device_code": "GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS",
  "user_code": "WDJB-MJHT",
  "verification_uri": "https://beta.b3os.org/app/device",
  "verification_uri_complete": "https://beta.b3os.org/app/device?user_code=WDJB-MJHT",
  "expires_in": 900,
  "interval": 5
}
```

### ` 400 ` — The device request is invalid (OAuth `invalid_request`).

Content type: ` application/json `

- ` value `: type ` object ` — RFC 6749 §5.2 error response. `error` is an errors.yaml code: the RFC 6749 and RFC 8628 codes, plus `rate_limited` (429) for too many device logins from one address. 

  - Required fields: ` error `

  - ` error `: type ` string `

    - enum: ` ["invalid_request","invalid_client","invalid_grant","unsupported_grant_type","authorization_pending","slow_down","access_denied","expired_token","rate_limited"] `

  - ` error_description `: type ` string `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "error": "invalid_request",
  "error_description": "client_id is required"
}
```

### ` 401 ` — Unknown client (`invalid_client`).

Content type: ` application/json `

- ` value `: type ` object ` — RFC 6749 §5.2 error response. `error` is an errors.yaml code: the RFC 6749 and RFC 8628 codes, plus `rate_limited` (429) for too many device logins from one address. 

  - Required fields: ` error `

  - ` error `: type ` string `

    - enum: ` ["invalid_request","invalid_client","invalid_grant","unsupported_grant_type","authorization_pending","slow_down","access_denied","expired_token","rate_limited"] `

  - ` error_description `: type ` string `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "error": "invalid_client",
  "error_description": "Unknown client_id b3os-cli2"
}
```

### ` 429 ` — Too many device logins from this address (`rate_limited`, in the OAuth error shape). Wait `Retry-After`
seconds. Polling the token endpoint faster than `interval` is `slow_down` (400), not this.


Content type: ` application/json `

- ` value `: type ` object ` — RFC 6749 §5.2 error response. `error` is an errors.yaml code: the RFC 6749 and RFC 8628 codes, plus `rate_limited` (429) for too many device logins from one address. 

  - Required fields: ` error `

  - ` error `: type ` string `

    - enum: ` ["invalid_request","invalid_client","invalid_grant","unsupported_grant_type","authorization_pending","slow_down","access_denied","expired_token","rate_limited"] `

  - ` error_description `: type ` string `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Response header ` Retry-After ` — Seconds to wait before retrying or polling again.

- ` value `: type ` integer `

  - minimum: ` 0 `

Example:

```json
{
  "error": "rate_limited",
  "error_description": "Too many device logins from this address; retry after 30 seconds"
}
```

## Request examples

### cURL

```curl
curl -X POST 'https://beta-api.b3os.org/v1/auth/device/code' \
  -H 'Authorization: Bearer YOUR_API_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
  "client_id": "b3os-cli"
}'
```

### JavaScript

```javascript
const response = await fetch('https://beta-api.b3os.org/v1/auth/device/code', {
  method: 'POST',
  headers: {
      "Authorization": "Bearer YOUR_API_TOKEN",
      "Content-Type": "application/json"
  },
  body: JSON.stringify({
    "client_id": "b3os-cli"
  })
});

const data = await response.json();
console.log(data);
```

### Python

```python
import requests

headers = {
    'Authorization': 'Bearer YOUR_API_TOKEN'
}

response = requests.post('https://beta-api.b3os.org/v1/auth/device/code', headers=headers, json={
  "client_id": "b3os-cli"
})
print(response.json())
```