# GET /v1/dock/challenge
Source: https://docs.treeship.dev/api/dock-challenge

> Start the device flow login by requesting a challenge nonce and device code.

## Request

```
GET /v1/dock/challenge
```

No authentication required. No request body.

## Response

```json
{
  "device_code": "a1b2c3d4e5f60718",
  "nonce": "7f8e9d0a1b2c3d4e5f60718293a4b5c6",
  "expires_at": "1711494000"
}
```

| Field         | Type   | Description                                              |
| ------------- | ------ | -------------------------------------------------------- |
| `device_code` | string | Random device code (16 hex chars), displayed to the user |
| `nonce`       | string | Cryptographic nonce (32 hex chars) for internal binding  |
| `expires_at`  | string | Unix timestamp as a string, 5 minutes from creation      |

There is no `verify_url` field. The CLI knows the activation page (`treeship.dev/hub/activate`) and prints it alongside the device code.

## Flow

1. CLI calls `GET /v1/dock/challenge`
2. CLI displays the `device_code` and points the user at `treeship.dev/hub/activate`
3. User enters the code in the browser and approves
4. CLI polls `GET /v1/dock/authorized?device_code=XXX` until approved or expired
5. CLI calls `POST /v1/dock/authorize` with its public keys and the `nonce` to complete registration

This follows the RFC 8628 device authorization grant pattern.

## Example

```bash
curl https://api.treeship.dev/v1/dock/challenge
```

```json
{
  "device_code": "a1b2c3d4e5f60718",
  "nonce": "7f8e9d0a1b2c3d4e5f60718293a4b5c6",
  "expires_at": "1711494000"
}
```

## Notes

* Challenges expire after 5 minutes
* Each challenge can only be used once (it is atomically claimed on authorize)
* The nonce is used internally for cryptographic binding and is not displayed to the user
* Recently expired and recently attached codes stay queryable for about an hour so an in-flight activation page reports a precise state instead of `not found`