API ReferenceOAuth 2.1 / OIDC
Device Authorization
Initiate the OAuth 2.1 device authorization flow (RFC 8628) for CLI tools, IoT devices, and smart TVs.
Endpoint
POST /oauth2/device/authBase URL: https://api-id.avnology.net
Content-Type: application/x-www-form-urlencoded
Initiates the device authorization flow for devices that lack a browser or have limited input capabilities (CLI tools, smart TVs, IoT devices, AI agents). The device displays a user code and verification URL, and the user completes authentication on a separate device.
Step 1: Request Device Code
Response (200 OK)
{
"device_code": "dc_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"user_code": "WDJB-MJHT",
"verification_uri": "https://id.avnology.net/device",
"verification_uri_complete": "https://id.avnology.net/device?user_code=WDJB-MJHT",
"expires_in": 900,
"interval": 5
}| Field | Description |
|---|---|
device_code | Used by the device to poll for completion |
user_code | Displayed to the user (short, easy to type) |
verification_uri | URL where the user enters the code |
verification_uri_complete | URL with code pre-filled (for QR codes) |
expires_in | Seconds before the device code expires |
interval | Minimum seconds between polling attempts |
Step 2: Display to User
Show the user:
To sign in, visit: https://id.avnology.net/device
Enter code: WDJB-MJHTOr display a QR code linking to verification_uri_complete.
Step 3: Poll for Token
The device polls the token endpoint until the user completes authentication:
curl -X POST https://api-id.avnology.net/oauth2/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=urn:ietf:params:oauth:grant-type:device_code" \
-d "device_code=dc_a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
-d "client_id=cli_device_app_123"Pending (400)
{ "error": "authorization_pending", "error_description": "The user has not yet authorized the device" }Slow Down (400)
{ "error": "slow_down", "error_description": "Polling too frequently. Increase interval." }Success (200 OK)
{
"access_token": "eyJhbGciOiJSUzI1NiI...",
"token_type": "Bearer",
"expires_in": 900,
"refresh_token": "rt_device_...",
"id_token": "eyJhbGciOiJSUzI1NiI...",
"scope": "openid profile email"
}Expired (400)
{ "error": "expired_token", "error_description": "The device code has expired" }Complete Example
JavaScript (CLI Tool)
async function deviceLogin(clientId) {
// Step 1: Request device code
const deviceRes = await fetch('https://api-id.avnology.net/oauth2/device/auth', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({ client_id: clientId, scope:
Python (httpx)
import httpx
import time
def device_login(client_id: str) -> dict:
# Request device code
device = httpx.post("https://api-id.avnology.net/oauth2/device/auth", data={
Go (net/http)
func deviceLogin(ctx context.Context, clientID string) (*TokenResponse, error) {
// Request device code
data := url
Related
- Token Endpoint -- other grant types
- Authorization Endpoint -- browser-based OAuth flow
- SDK:
client.oauth.deviceLogin()(TypeScript)