Begin a device-authorization (browser-login) flow.
Unauthenticated — the client calls this before it has any credentials. Returns a high-entropy `deviceCode` the client keeps secret and echoes back on every poll, a short human-readable `userCode`, and the URL it should open in the user's browser (the URL carries the `userCode`, never the device code). Grant expires in 10 minutes.
The preset the client wants the minted key scoped to
(REQUIRED — there is no server-side default), plus optional client
identity (clientType / clientName) and device identity
(deviceId / deviceLabel) so a re-login from the same
machine rotates its credential in place.
What kind of client is running the browser-login flow (!:ClientAuthGrant).
The flow itself is the OAuth 2.0 Device Authorization Grant (RFC 8628):
nothing about start → poll → approve cares whether the caller is a CLI,
an IDE extension, a desktop app, or an MCP client. This enum is the one
place that distinction is captured — carried from :start onto the
grant so the approval page can name the requester ("Authorize VS Code")
and the minted token's display name reflects its origin.
Deliberately NOT mapped onto a per-client Fruxon.Model.Tokens.TokenType:
every browser-login key is the same kind of credential (same scope model,
same lifecycle), so the origin tag stays a single TokenType.Device and
the granular identity lives here on the grant — mirroring the rationale
in Fruxon.Model.Tokens.TokenType.System's docstring for why the old
per-feature system-key values were collapsed.
Wire form is UPPER_SNAKE per project convention; Fruxon.Model.DeviceAuth.ClientType.Unspecified is the AIP-126 zero sentinel so "older client sent no type" is distinguishable from a meaningful value.
"UNSPECIFIED" | "CLI" | "IDE" | "DESKTOP" | "MCP" | "OTHER"Optional human-readable client name (e.g. "Fruxon CLI 0.4.1",
"VS Code"). Display/attribution only. Null when not provided.
Stable per-install device id (a UUID the client generates once and persists). Null when the client doesn't send it.
Human-readable device label (e.g. hostname), best-effort. Attribution only — never gates anything. Null when not provided.
Named preset the client wants the minted key scoped to — one of
observer, operator, developer, maintainer,
admin. REQUIRED: the client knows what access it needs and must
say so — there is no server-side default. The user's role at the
approval page is to see it and approve/deny, not to choose (the
GitHub device-flow model).
Response Body
curl -X POST "https://api.fruxon.com/v1/deviceAuthorizations" \ -H "Content-Type: application/json" \ -d '{}'{
"deviceCode": "string",
"userCode": "string",
"verificationUri": "string",
"verificationUriComplete": "string",
"expiresInSeconds": 0,
"pollIntervalSeconds": 0
}{
"type": "string",
"title": "string",
"status": 0,
"detail": "string",
"instance": "string",
"property1": null,
"property2": null
}{
"type": "string",
"title": "string",
"status": 0,
"detail": "string",
"instance": "string",
"property1": null,
"property2": null
}