---
title: Token Revocation
description: The POST /{{envID}}/as/revoke endpoint revokes the token specified in the request body. The revocation endpoint applies to access_token and refresh_token tokens, and the tokens to be revoked must be for a custom resource. Tokens issued for the PingOne API resource may not be revoked because the PingOne APIs do not use the introspection endpoint. Also, custom resource tokens that do not have a sid (session) claim, such as tokens issued for the client_credentials grant type, cannot be revoked.
component: pingone-api
page_id: pingone-api:auth:openid-connect-oauth-2/token-revocation
canonical_url: https://developer.pingidentity.com/pingone-api/auth/openid-connect-oauth-2/token-revocation.html
section_ids:
  prerequisites: Prerequisites
  headers: Headers
  body: Body
  example-request: Example Request
---

# Token Revocation

##

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

The `POST /{{envID}}/as/revoke` endpoint revokes the token specified in the request body. The revocation endpoint applies to `access_token` and `refresh_token` tokens, and the tokens to be revoked must be for a custom resource. Tokens issued for the PingOne API resource may not be revoked because the PingOne APIs do not use the introspection endpoint. Also, custom resource tokens that do not have a `sid` (session) claim, such as tokens issued for the `client_credentials` grant type, cannot be revoked.

For more information about the token revocation request, refer to section 2.1 of [OAuth 2.0 Token Revocation](https://www.rfc-editor.org/rfc/rfc7009#section-2.1). For more information about custom resources, custom scopes, and how the PingOne OAuth 2 authorization service manages requests for custom scopes, refer to [Custom scopes](../../foundations/pingone-roles-scopes-and-permissions/access-services-through-scopes-and-roles/custom-scopes.html) in *- Foundations*.

The `POST /{{envID}}/as/revoke` endpoint uses the same authentication method as the `POST /{{envID}}/as/token` endpoint, and uses the value from the application's `tokenEndpointAuthMethod` to determine the configuration. If the `tokenEndpointAuthMethod` is set to `CLIENT_SECRET_BASIC`, the `Authorization: Basic <headerValue>` represents a Base64-encoded representation of `"username:password"`, in which the username is the `client_id` and the password is the `client_secret`.

If the application's `tokenEndpointAuthMethod` value is `CLIENT_SECRET_POST`, the request does not need an `Authorization` header, and the `client_id` and `client_secret` property values are submitted in the request body.

If the application's `tokenEndpointAuthMethod` value is `NONE`, the request requires the `client_id` property value in the request body and does not require an `Authorization` header.

If the application's `tokenEndpointAuthMethod` value is `CLIENT_SECRET_JWT`, the token endpoint uses a JWT signed by the application's client secret to authenticate the request. For information about creating the JWT and the claims in the JWT, refer to [Create a client secret JWT](../auth-config-options/create-a-client-secret-jwt.html).

If the application's `tokenEndpointAuthMethod` value is `PRIVATE_KEY_JWT`, the token endpoint uses a JWT signed by an external private key file to authenticate the request. For information about creating the JWT and the claims in the JWT, refer to [Create a private key JWT](../auth-config-options/create-a-private-key-jwt.html).

|   |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| - | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|   | This endpoint does not support individual one-by-one access token revocation. This operation revokes all access tokens for the session and application combination. A token must have an associated session (`sid`) claim to be revoked. If you revoke a refresh token, it also revokes all associated access tokens to that specific session and application combination. Revocation applies to tokens issued up to the current time of the revocation call and has no relation to the `iat` (issued at) claim of the token being revoked, nor does it affect tokens issued after the time of the revoke call even if for the same session and application combination. |

If the authentication method is accepted, and the token contains the necessary custom resource `aud` and `sid` claims, the response returns a 200 code with an empty body.

If the token is invalid or if the token does not include the `sid` claim, an `unsupported_token_type` error is returned as directed in [OAuth 2.0 Token Revocation RFC7009 (section 2.2.1)](https://tools.ietf.org/html/rfc7009#section-2.2.1). If the `aud` claim identifies a platform token, an `unsupported_token_type` error response is returned.

|   |                                                                                                                                                                                                  |
| - | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|   | For more information about PingOne SSO sessions and token revocation, refer to [OIDC session management](../../foundations/authentication-concepts/oidc-session-management.html) in the *Guide*. |

### Prerequisites

* Refer to [OpenID Connect/OAuth 2](../openid-connect-oauth-2.html) and [Token](token-intro.html) for important overview information.

> **Collapse: Request Model**
>
> | Property | Type   | Required? |
> | -------- | ------ | --------- |
> | `token`  | String | Required  |
>
> Refer to the [OpenID Connect/OAuth2 data model](../openid-connect-oauth-2.html) for full property descriptions.

### Headers

Authorization

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

### Body

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

| Key   | Value          |
| ----- | -------------- |
| token | {{oauthToken}} |

##

### Example Request

* cURL

* C#

* Go

* HTTP

* Java

* jQuery

* NodeJS

* Python

* PHP

* Ruby

* Swift

```shell
curl --location --globoff '{{authPath}}/{{envID}}/as/revoke' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic e3thcHBJRH19Ont7YXBwU2VjcmV0fX0=' \
--data-urlencode 'token={{oauthToken}}'
```

```csharp
var options = new RestClientOptions("{{authPath}}/{{envID}}/as/revoke")
{
  MaxTimeout = -1,
};
var client = new RestClient(options);
var request = new RestRequest("", Method.Post);
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddHeader("Authorization", "Basic e3thcHBJRH19Ont7YXBwU2VjcmV0fX0=");
request.AddParameter("token", "{{oauthToken}}");
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/revoke"
  method := "POST"

  payload := strings.NewReader("token=%7B%7BoauthToken%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")
  req.Header.Add("Authorization", "Basic e3thcHBJRH19Ont7YXBwU2VjcmV0fX0=")

  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/revoke HTTP/1.1
Host: {{authPath}}
Content-Type: application/x-www-form-urlencoded
Authorization: Basic e3thcHBJRH19Ont7YXBwU2VjcmV0fX0=

token=%7B%7BoauthToken%7D%7D
```

```java
OkHttpClient client = new OkHttpClient().newBuilder()
  .build();
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
RequestBody body = RequestBody.create(mediaType, "token={{oauthToken}}");
Request request = new Request.Builder()
  .url("{{authPath}}/{{envID}}/as/revoke")
  .method("POST", body)
  .addHeader("Content-Type", "application/x-www-form-urlencoded")
  .addHeader("Authorization", "Basic e3thcHBJRH19Ont7YXBwU2VjcmV0fX0=")
  .build();
Response response = client.newCall(request).execute();
```

```javascript
var settings = {
  "url": "{{authPath}}/{{envID}}/as/revoke",
  "method": "POST",
  "timeout": 0,
  "headers": {
    "Content-Type": "application/x-www-form-urlencoded",
    "Authorization": "Basic e3thcHBJRH19Ont7YXBwU2VjcmV0fX0="
  },
  "data": {
    "token": "{{oauthToken}}"
  }
};

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

```javascript
var request = require('request');
var options = {
  'method': 'POST',
  'url': '{{authPath}}/{{envID}}/as/revoke',
  'headers': {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Authorization': 'Basic e3thcHBJRH19Ont7YXBwU2VjcmV0fX0='
  },
  form: {
    'token': '{{oauthToken}}'
  }
};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
```

```python
import requests

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

payload = 'token=%7B%7BoauthToken%7D%7D'
headers = {
  'Content-Type': 'application/x-www-form-urlencoded',
  'Authorization': 'Basic e3thcHBJRH19Ont7YXBwU2VjcmV0fX0='
}

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/revoke');
$request->setMethod(HTTP_Request2::METHOD_POST);
$request->setConfig(array(
  'follow_redirects' => TRUE
));
$request->setHeader(array(
  'Content-Type' => 'application/x-www-form-urlencoded',
  'Authorization' => 'Basic e3thcHBJRH19Ont7YXBwU2VjcmV0fX0='
));
$request->addPostParameter(array(
  'token' => '{{oauthToken}}'
));
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/revoke")

http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/x-www-form-urlencoded"
request["Authorization"] = "Basic e3thcHBJRH19Ont7YXBwU2VjcmV0fX0="
request.body = "token=%7B%7BoauthToken%7D%7D"

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

```swift
let parameters = "token=%7B%7BoauthToken%7D%7D"
let postData =  parameters.data(using: .utf8)

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

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()
```
