Hub API
GET /v1/dock/challenge
Start the device flow login by requesting a challenge nonce and device code.
Request
GET /v1/dock/challengeNo authentication required. No request body.
Response
{
"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
- CLI calls
GET /v1/dock/challenge - CLI displays the
device_codeand points the user attreeship.dev/hub/activate - User enters the code in the browser and approves
- CLI polls
GET /v1/dock/authorized?device_code=XXXuntil approved or expired - CLI calls
POST /v1/dock/authorizewith its public keys and thenonceto complete registration
This follows the RFC 8628 device authorization grant pattern.
Example
curl https://api.treeship.dev/v1/dock/challenge{
"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