Treeship
Hub API

GET /v1/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

{
  "device_code": "a1b2c3d4e5f60718",
  "nonce": "7f8e9d0a1b2c3d4e5f60718293a4b5c6",
  "expires_at": "1711494000"
}
FieldTypeDescription
device_codestringRandom device code (16 hex chars), displayed to the user
noncestringCryptographic nonce (32 hex chars) for internal binding
expires_atstringUnix 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

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