---
title: Token exchange grant type
description: Token exchange enables an application to present a subject token and optionally an actor token and receive an access token for a custom resource. The application must be configured with a grantTypes value of token_exchange, and an tokenEndpointAuthMethod value of CLIENT_SECRET_BASIC, CLIENT_SECRET_POST, PRIVATE_KEY_JWT, or CLIENT_SECRET_JWT. Learn more in Applications OIDC settings data model.
component: pingone-api
page_id: pingone-api:foundations:authentication-concepts/authorization-flow-by-grant-type/token-exchange-grant-type
canonical_url: https://developer.pingidentity.com/pingone-api/foundations/authentication-concepts/authorization-flow-by-grant-type/token-exchange-grant-type.html
---

# Token exchange grant type

Token exchange enables an application to present a subject token and optionally an actor token and receive an access token for a custom resource. The application must be configured with a `grantTypes` value of `token_exchange`, and an `tokenEndpointAuthMethod` value of `CLIENT_SECRET_BASIC`, `CLIENT_SECRET_POST`, `PRIVATE_KEY_JWT`, or `CLIENT_SECRET_JWT`. Learn more in [Applications OIDC settings data model](../../../platform/applications/applications-1.html#applications-oidc-settings-data-model).

**Step 1:** Send a request to the `POST /{{envID}}/as/token` endpoint based on the application's token endpoint authentication method. Learn more in [Token (token\_exchange)](../../../auth/openid-connect-oauth-2/token-token_exchange.html).

```bash
curl --location --request POST '{{authPath}}/{{envID}}/as/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic e3thcHBJRH19Ont7YXBwU2VjcmV0fX0=' \
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:token-exchange' \
--data-urlencode 'subject_token={{subjectToken}}' \
--data-urlencode 'subject_token_type=urn:ietf:params:oauth:token-type:access_token' \
--data-urlencode 'requested_token_type=urn:ietf:params:oauth:token-type:access_token' \
--data-urlencode 'scope={{requestedScopes}}'
```

The request requires the following parameters in the request URL:

* `grant_type=urn:ietf:params:oauth:grant-type:token-exchange`

* `subject_token={{subjectToken}}`

* `subject_token_type={{type}}`, where `{{type}}` is either `urn:ietf:params:oauth:token-type:access_token` or `urn:ietf:params:oauth:token-type:id_token`

* Optional: `actor_token={{actorToken}}`

  * Required with `actor_token`: `actor_token_type={{type}}`, where type is either `urn:ietf:params:oauth:token-type:access_token` or `urn:ietf:params:oauth:token-type:id_token`

  |   |                                                                                   |
  | - | --------------------------------------------------------------------------------- |
  |   | `subject_token` and `actor_token` must be issued by the same PingOne environment. |

* Optional: `requested_token_type=urn:ietf:params:oauth:token-type:access_token`

* `scope={{requestedScopes}}`

**Step 2:** PingOne validates the `subject_token` and the `actor_token`, if provided. Based on the `scope` parameter value found in the token request and the scopes configured in the application, PingOne returns an access token in the token response; for example:

```
{
"access_token": "eyJ…", # the access token as a result of the token exchange token request
"token_type": "Bearer",
"expires_in": 3600,
"scope": "exampleScope",
"issued_token_type": "urn:ietf:params:oauth:token-type:access_token"
}
```
