> For the complete documentation index, see [llms.txt](https://docs.pulsoid.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.pulsoid.net/access-token-management/oauth-2-device-authorization-flow.md).

# OAuth 2 Device Authorization Flow

**Authorization Token Retrieval Method for Applications Without HTTP or Deep Link Callbacks**

This method is ideal for applications that can't process HTTP or deep link callbacks. It involves multiple stages:

1. Obtain the authorization URL for the user.
2. Open the browser for the user, or instruct them to open it using the provided link.
3. While the user is granting access, the application should poll for the token in the background.
4. After the user grants access, the application will receive the OAuth token.

This approach is effective for games, mods, and other applications that cannot handle deep link redirects.

#### Initiate Device Authorization Session

To get an access token, send an HTTP POST request to `https://pulsoid.net/oauth2/device_authorization`. Set the following `x-www-form-urlencoded` parameters:

* `client_id` equals to your application's client id
* `scope` equals to desired comma separate [scope](/access-token-management/list-of-supported-scopes.md).

Example request

```sh
curl --request POST \
  --url https://pulsoid.net/oauth2/device_authorization \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data client_id=ad9e3778-347f-4aec-9ec6-98b0d353f6f9 \
  --data 'scope=data:heart_rate:read'
```

Example response

```json
{
  "device_code": "2c169147-c761-4691-accd-00c702cf3b60",
  "user_code": "32761c50-bc77-422d-b1d8-dadae4b9ef37",
  "verification_uri": "https://pulsoid.net/oauth2/device_authorization_consent",
  "verification_uri_complete": "https://pulsoid.net/oauth2/device_authorization_consent?user_code=32761c50-bc77-422d-b1d8-dadae4b9ef37",
  "expires_in": 600,
  "interval": 3
}
```

Your application should open the URL located in `verification_uri_complete` or prompt the user to open this URL. On this page, the user will be able to grant or deny access.

Concurrently, the application should run a background process that attempts to obtain an access token using the `device_code` at the specified `interval`(in seconds), continuing until the `expires_in`(in seconds) duration has elapsed.

#### Obtain Token

To obtain an access token, the application should execute an HTTP POST request to `https://pulsoid.net/oauth2/token`. Set the following `x-www-form-urlencoded` parameters:

* `grant_type` equals `urn:ietf:params:oauth:grant-type:device_code`
* `device_code` equals the one from the previous step
* `client_id` equals your application's client ID

Example Request

```sh
curl --request POST \
  --url https://pulsoid.net/oauth2/token \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data 'grant_type="urn:ietf:params:oauth:grant-type:device_code"' \
  --data device_code=2c169147-c761-4691-accd-00c702cf3b60 \
  --data client_id=ad9e3778-347f-4aec-9ec6-98b0d353f6f9
```

Result to this request will describe what to do next

<mark style="color:$primary;">**200 OK response means that granting is successful**</mark>

Example of response

```json
{
  "access_token": "02a61b22-1c7e-477d-98ed-96f4aef7d5ad",
  "expires_in": 1261440000,
  "token_type": "bearer"
}
```

<mark style="color:orange;">400 Bad Request</mark>

The response in this case will be a json in the following format

```json
{
  "error": "some error",
  "error_description": null
}
```

The most important fields here are the `error` fields, which signal the next step. These fields can be one of the following:

* `authorization_pending`: This means your application should <mark style="color:$success;">**keep trying to obtain a token**</mark>.
* `invalid_grant` (with `error_description`: `user didn't grant access`): This indicates that the user didn't grant access to your application, and the polling <mark style="color:red;">**process should be stopped**</mark>.
* `invalid_grant` (with `error_description`: `access token already issued`): This means that a token was already obtained for the given `device_code`, and the <mark style="color:red;">**polling process should be stopped.**</mark>
* `expired_token`: This means the `device_code` has expired, and the <mark style="color:red;">**polling process should be stopped**</mark><mark style="color:red;">.</mark>
