Skip to main content
Exchange an approved device code for an access token.
This endpoint accepts one grant type only: urn:ietf:params:oauth:grant-type:device_code. refresh_token and client_credentials are rejected.

Request

The field is named code, not device_code. The device-authorize response calls it device_code; the field you send it back in is code. A request with an empty code is rejected as a malformed request.

Response

The token response is returned bare. Unlike the /v1 endpoints, it is not wrapped in a data envelope — read the fields off the top level of the body.
The access token’s claims carry iss (the management API host), sub (your user id), aud (a one-element array [client_id], not a bare string), account_id, scope, token_type (always "access_token"), iat, and exp. A successful exchange consumes the device session — the device code is single-use.
There is no refresh flow on this host. api.noorle.com accepts the device-code grant and nothing else, so there is no way to exchange a token for a fresh one. When the hour is up, run the device flow again — or use an API key, which does not expire on a fixed clock.

Polling responses

Poll on the interval returned by /oauth/device/authorize. Five outcomes — still pending, polling too fast, denied, expired, or an unusable code — all come back as the same HTTP 400; only the JSON body’s error field tells them apart.
Branch on the error field, not the status code. authorization_pending and slow_down are the only outcomes that mean “keep polling” — every other error on a 400 is terminal, including access_denied. A loop that treats every 400 as “still pending” never terminates on a declined or expired code.

Status codes

There is no rate limit on this endpoint.

Using the token

Store it with restrictive permissions — it is a bearer credential with your account authority for the next hour.