Skip to main content
Start the OAuth 2.0 device flow. This is how a terminal client authenticates a human without handling their credentials.

Request

Response

Returned bare — unlike the /v1 endpoints, it is not wrapped in a data envelope.
verification_uri is served by the Portal, not by the management API, and its host is built from the environment the API runs in. Show the human the value that came back in the response — do not hard-code a host.

Flow

  1. Request a device code. The response carries both codes, the verification URL, and the poll interval.
  2. Show the human verification_uri and user_code. Or open verification_uri_complete directly.
  3. Poll /oauth/token every interval seconds until it returns a token or a terminal answer.

Polling

Poll no faster than interval5 seconds.
Branch on the error field in the body, not on the status code. Five different outcomes all return HTTP 400, and only two of them mean “keep waiting”. A loop that treats 400 as “still pending” never terminates on a declined or expired code.
Note that a decline is access_denied on HTTP 400, not a 403. Once a device code stops being usable, the answer is terminal: request a new device code and start over rather than continuing to poll the old one. Bound the number of attempts regardless.
On approval, the exchange consumes the session — the device code is single-use. A second poll after a successful exchange finds no session.

Status codes

A rejected body comes back as 422, not 400: validation failures travel the normal management-API carrier, where Validation maps to 422. The 400s on this endpoint family are the RFC 8628 device-flow errors. There is no rate limit on this endpoint.