---
title: Token (device_code) (NONE)
description: "The token endpoint is used by the client to obtain an access token by presenting its authorization grant. Note that authentication requirements to this endpoint are configured by the application's tokenEndpointAuthMethod property. For device_code`grants, the application calls the `POST /{{envID}}/as/token endpoint to acquire the access token. The grant_type property in the token request body uses the following syntax to identify the device code type: urn:ietf:params:oauth:grant-type:device_code."
component: pingone-api
page_id: pingone-api:auth:openid-connect-oauth-2/device-authorization-grant/token-device_code-none
canonical_url: https://developer.pingidentity.com/pingone-api/auth/openid-connect-oauth-2/device-authorization-grant/token-device_code-none.html
section_ids:
  headers: Headers
  body: Body
  example-request: Example Request
---

# Token (device\_code) (NONE)

##

```none
POST {{authPath}}/{{envID}}/as/token
```

The token endpoint is used by the client to obtain an access token by presenting its authorization grant. Note that authentication requirements to this endpoint are configured by the application's `tokenEndpointAuthMethod` property. For ``device_code`grants, the application calls the `POST /{{envID}}/as/token`` endpoint to acquire the access token. The `grant_type` property in the token request body uses the following syntax to identify the device code type: `urn:ietf:params:oauth:grant-type:device_code`.

For a `device_code` grant type in which the application's `tokenEndpointAuthMethod` is set to `NONE`, the request requires the `client_id` property value (the application ID) and does not require an `Authorization` header.

|   |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| - | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | In the PingOne admin UI, if the admin chooses the Device Authorization application type, the application is created with the grant type set to `DEVICE_CODE` and `REFRESH_TOKEN`, and the Token Endpoint Authentication Method set to `NONE`. These default application configuration options are based on [RFC8628-5.6. Non-Confidential Clients](https://www.rfc-editor.org/rfc/rfc8628#section-5.6). However, admins are free to select either the `CLIENT_SECRET_BASIC` or `CLIENT_SECRET_POST` Token Endpoint Authentication Method if needed, particularly when working with confidential clients. For more information about the token request, refer to [Token](../token-intro.html). |

To obtain a refresh token along with an access token, the application must be either:

* Configured with the `refresh_token` grant type and the `authorization_code` grant type.

* Configured with the `authorization_code` grant type, and include `offline_access` in the `scope` parameter.

A refresh token is then generated along with the access token. When obtaining the original access token, a refresh token is included in the response, which is tied to the client and the user session. As long as the session exists and it is not expired (30 days since the last sign on), the `/{{envID}}/as/token` endpoint can be used to exchange the refresh token for a new access token and refresh token.

When a new refresh token is issued, the previous refresh token is rotated to prevent token abuse. Refresh token rotations do not extend the duration of the session.

A refresh token can be revoked using the `/{{envID}}/as/revoke` endpoint, which revokes the token without deleting the current user session. You can also revoke the token by deleting the user session. Session termination is supported only by the resource owner using the `/{{envID}}/as/signoff` endpoint or by disabling the user.

> **Collapse: Request Model**
>
> | Property        | Type   | Required? |
> | --------------- | ------ | --------- |
> | `client_id`     | String | Required  |
> | `client_secret` | String | Optional  |
> | `device_code`   | String | Required  |
> | `grant_type`    | String | Required  |
>
> Refer to the [Device authentication grant data model](../device-authorization-grant.html#device-authorization-grant-data-model) for full property descriptions.

### Headers

Content-Type      application/x-www-form-urlencoded

### Body

urlencoded ( application/x-www-form-urlencoded )

| Key          | Value                                         |
| ------------ | --------------------------------------------- |
| grant\_type  | urn:ietf:params:oauth:grant-type:device\_code |
| device\_code | {{deviceCode}}                                |
| client\_id   | {{deviceAppID}}                               |

##

### Example Request

* cURL

* C#

* Go

* HTTP

* Java

* jQuery

* NodeJS

* Python

* PHP

* Ruby

* Swift

```shell
curl --location --globoff '{{authPath}}/{{envID}}/as/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:device_code' \
--data-urlencode 'device_code={{deviceCode}}' \
--data-urlencode 'client_id={{deviceAppID}}'
```

```csharp
var options = new RestClientOptions("{{authPath}}/{{envID}}/as/token")
{
  MaxTimeout = -1,
};
var client = new RestClient(options);
var request = new RestRequest("", Method.Post);
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddParameter("grant_type", "urn:ietf:params:oauth:grant-type:device_code");
request.AddParameter("device_code", "{{deviceCode}}");
request.AddParameter("client_id", "{{deviceAppID}}");
RestResponse response = await client.ExecuteAsync(request);
Console.WriteLine(response.Content);
```

```golang
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io"
)

func main() {

  url := "{{authPath}}/{{envID}}/as/token"
  method := "POST"

  payload := strings.NewReader("grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=%7B%7BdeviceCode%7D%7D&client_id=%7B%7BdeviceAppID%7D%7D")

  client := &http.Client {
  }
  req, err := http.NewRequest(method, url, payload)

  if err != nil {
    fmt.Println(err)
    return
  }
  req.Header.Add("Content-Type", "application/x-www-form-urlencoded")

  res, err := client.Do(req)
  if err != nil {
    fmt.Println(err)
    return
  }
  defer res.Body.Close()

  body, err := io.ReadAll(res.Body)
  if err != nil {
    fmt.Println(err)
    return
  }
  fmt.Println(string(body))
}
```

```http
POST /{{envID}}/as/token HTTP/1.1
Host: {{authPath}}
Content-Type: application/x-www-form-urlencoded

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=%7B%7BdeviceCode%7D%7D&client_id=%7B%7BdeviceAppID%7D%7D
```

```java
OkHttpClient client = new OkHttpClient().newBuilder()
  .build();
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
RequestBody body = RequestBody.create(mediaType, "grant_type=urn:ietf:params:oauth:grant-type:device_code&device_code={{deviceCode}}&client_id={{deviceAppID}}");
Request request = new Request.Builder()
  .url("{{authPath}}/{{envID}}/as/token")
  .method("POST", body)
  .addHeader("Content-Type", "application/x-www-form-urlencoded")
  .build();
Response response = client.newCall(request).execute();
```

```javascript
var settings = {
  "url": "{{authPath}}/{{envID}}/as/token",
  "method": "POST",
  "timeout": 0,
  "headers": {
    "Content-Type": "application/x-www-form-urlencoded"
  },
  "data": {
    "grant_type": "urn:ietf:params:oauth:grant-type:device_code",
    "device_code": "{{deviceCode}}",
    "client_id": "{{deviceAppID}}"
  }
};

$.ajax(settings).done(function (response) {
  console.log(response);
});
```

```javascript
var request = require('request');
var options = {
  'method': 'POST',
  'url': '{{authPath}}/{{envID}}/as/token',
  'headers': {
    'Content-Type': 'application/x-www-form-urlencoded'
  },
  form: {
    'grant_type': 'urn:ietf:params:oauth:grant-type:device_code',
    'device_code': '{{deviceCode}}',
    'client_id': '{{deviceAppID}}'
  }
};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
```

```python
import requests

url = "{{authPath}}/{{envID}}/as/token"

payload = 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=%7B%7BdeviceCode%7D%7D&client_id=%7B%7BdeviceAppID%7D%7D'
headers = {
  'Content-Type': 'application/x-www-form-urlencoded'
}

response = requests.request("POST", url, headers=headers, data=payload)

print(response.text)
```

```php
<?php
require_once 'HTTP/Request2.php';
$request = new HTTP_Request2();
$request->setUrl('{{authPath}}/{{envID}}/as/token');
$request->setMethod(HTTP_Request2::METHOD_POST);
$request->setConfig(array(
  'follow_redirects' => TRUE
));
$request->setHeader(array(
  'Content-Type' => 'application/x-www-form-urlencoded'
));
$request->addPostParameter(array(
  'grant_type' => 'urn:ietf:params:oauth:grant-type:device_code',
  'device_code' => '{{deviceCode}}',
  'client_id' => '{{deviceAppID}}'
));
try {
  $response = $request->send();
  if ($response->getStatus() == 200) {
    echo $response->getBody();
  }
  else {
    echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .
    $response->getReasonPhrase();
  }
}
catch(HTTP_Request2_Exception $e) {
  echo 'Error: ' . $e->getMessage();
}
```

```ruby
require "uri"
require "net/http"

url = URI("{{authPath}}/{{envID}}/as/token")

http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/x-www-form-urlencoded"
request.body = "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=%7B%7BdeviceCode%7D%7D&client_id=%7B%7BdeviceAppID%7D%7D"

response = http.request(request)
puts response.read_body
```

```swift
let parameters = "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=%7B%7BdeviceCode%7D%7D&client_id=%7B%7BdeviceAppID%7D%7D"
let postData =  parameters.data(using: .utf8)

var request = URLRequest(url: URL(string: "{{authPath}}/{{envID}}/as/token")!,timeoutInterval: Double.infinity)
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")

request.httpMethod = "POST"
request.httpBody = postData

let task = URLSession.shared.dataTask(with: request) { data, response, error in
  guard let data = data else {
    print(String(describing: error))
    return
  }
  print(String(data: data, encoding: .utf8)!)
}

task.resume()
```
