user_code, the human operator approves it in a browser, and the agent polls the token endpoint until it receives an access token. For a full comparison of all supported authentication methods, see Authentication.
Flow overview
Request device and user codes
The agent sends
POST /v1/oauth/device_authorization and receives a device_code, user_code, verification_uri, expires_in, and interval.Display the code to the operator
The agent displays the
user_code and verification_uri to the human operator — log them to a console, embed in a CLI prompt, or generate a QR code from verification_uri_complete.Operator approves in a browser
The operator opens
verification_uri, enters the user_code, and approves access. No action is required from the agent during this step.Device-authorization request
| Field | Type | Description |
|---|---|---|
device_code | string | Opaque code the agent presents when polling the token endpoint. Keep this secret. |
user_code | string | Short, human-typeable code the operator enters at verification_uri. Display this to your operator. |
verification_uri | string | URL the operator must visit to approve the request. |
verification_uri_complete | string | verification_uri with user_code pre-filled as a query parameter — use this for QR codes or one-click links where possible. |
expires_in | integer | Seconds until both codes expire. The agent must complete the poll loop before this window closes. |
interval | integer | Minimum seconds the agent must wait between poll attempts. Do not poll faster than this; the server enforces the limit. |
Poll loop
After the device-authorization request succeeds, pollPOST /v1/oauth/token at interval-second intervals. On each slow_down response, permanently increase the interval by 5 seconds for the remainder of the session. Stop when you receive an access token or a terminal error.
Error codes
The following error codes may be returned byPOST /v1/oauth/token during the poll loop:
error value | HTTP status | Meaning | Action |
|---|---|---|---|
authorization_pending | 400 | The operator has not yet approved the request. | Continue polling after interval seconds. |
slow_down | 400 | The agent is polling too fast. | Increase interval by 5 seconds permanently and continue polling. |
expired_token | 400 | The device_code has expired (expires_in elapsed). | Start over: request a new device_code and prompt the operator again. |
access_denied | 400 | The operator denied the request or cancelled it. | Abort. Do not retry with the same device_code. |
invalid_client | 401 | The client_id is unknown or invalid. | Check your client registration. |
Token response
A successful poll returns HTTP 200 with a token response:refresh_token grant at POST /v1/oauth/token before the access token expires.
TTLs at a glance
| Item | TTL |
|---|---|
device_code / user_code | expires_in seconds from the device-authorization response (typically 900 s / 15 min) |
| Access token | 1800 s (30 minutes) |
| Refresh token | 30 days; single-use — each exchange rotates it. |
Client registration
If you do not yet have a
client_id, register your OAuth client with POST /v1/oauth/register (RFC 7591 dynamic client registration) before starting the device flow. Public clients (no client secret) are supported. See the OAuth register endpoint.See also
- Authentication — full auth method comparison (passkeys, MFA, SSO, API keys)
- API Keys — server-to-server auth without OAuth; simpler for non-delegated agent calls
- API reference overview — auth header formats and rate limits