---
metadata:
  - name: generator
    content: Diplodoc Platform v5.44.0
alternate:
  - https://yandex.com.tr/dev/id/doc/en/codes/screen-code.md
  - https://yandex.com.tr/dev/id/doc/ru/codes/screen-code.md
---
> **Documentation Index:** Fetch the complete configuration index at https://yandex.com.tr/dev/id/doc/en/llms.txt

# Receiving a confirmation code from the user

Some apps (such as console apps) can't [get the confirmation code from the URL](https://yandex.com.tr/dev/id/doc/en/codes/code-url.md). In this case, the user should get the code from Yandex OAuth and enter it in the app.

1. Set redirection to the Yandex OAuth page in the app so that the user confirms access to their data. To do this, use the [code output request](#code).
  
   {% note tip %}

   If the browser isn't available on the device where the app is installed, the user will have to open the URL on their computer. To make it more user-friendly, provide a QR code or a short link.

   {% endnote %}

1. The confirmation code is [displayed in the browser](#code-response). To achieve that, specify the address `https://oauth.yandex.com/verification_code` in the **Redirect URI** field when [registering the app](https://yandex.com.tr/dev/id/doc/en/register-client.md#platforms).

1. To switch the confirmation code for the OAuth token, the app must send a [POST request](#token).

   <!-- source: en/_includes/oauth/security.md -->
   The received token can be saved in the app and used for requests until its [lifetime expires](https://yandex.com.tr/dev/id/doc/en/concepts/ya-oauth-intro.md#ttl). The token should only be available to your app, so we don't recommend saving it in the browser or open configuration files.
   <!-- endsource: en/_includes/oauth/security.md -->

## Confirmation code request {#code}

### Request format {#code-request}

<!-- source: en/_includes/oauth/code-request.md -->
```
https://oauth.yandex.com/authorize?response_type=code
 & client_id=<app ID>
[& device_id=<device ID>]
[& device_name=<device name>]
[& redirect_uri=<redirect URL>]
[& login_hint=<username or email address>]
[& scope=<requested required permissions>]
& optional_scope=<requested optional permissions>]
[& force_confirm=yes]
[& state=<arbitrary string>]
[& code_challenge=<transformed version of code_verifier>]
[& code_challenge_method=<transformation method>]
```

#### Required parameters {#required}

#|
|| **Parameter** | **Description** ||
|| `response_type` | Expected response. When you request the confirmation code, specify the <q>code</q> value. ||
|| `client_id` | Application ID. Available in the [app properties](https://yandex.com.tr/dev/id/doc/en/register-client.md#app-params). To open properties, go to [Yandex OAuth](https://oauth.yandex.com/) and click the app name.
 ||
|#

#### Advanced parameters {#optional}
#|
|| **Parameter** | **Description** ||
|| `device_id` | Unique ID of the device the token is requested for. To ensure uniqueness, just generate a [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier) once and use it every time a new token is requested from this device.

The ID must be from 6 to 50 characters long. Only printable [ASCII](https://en.wikipedia.org/wiki/ASCII) characters are allowed (with codes from 32 to 126).

Learn more about tokens for individual devices on the [Revoking a token for a specific device](https://yandex.com.tr/dev/id/doc/en/tokens/token-invalidate.md#device-token) page.

If the `device_id` parameter is sent without the `device_name` parameter, the token is marked as issued for an unknown device in the user interface.

<!-- source: en/_includes/oauth/concepts/device-token/id-device-token/limit.md -->
{% note alert %}

An app can have up to 30 tokens linked to a user's devices. If Yandex OAuth issues a new device token for the app, the oldest token stops working.

{% endnote %}
<!-- endsource: en/_includes/oauth/concepts/device-token/id-device-token/limit.md -->
||
|| `device_name` | The name of the device to show users. Up to 100 characters.

For mobile devices, we recommend passing the device name specified by the user. If a name is missing, the name can be taken from the device model, OS name and version, and so on.

If the `device_name` parameter is sent without the `device_id` parameter, it is ignored. Yandex OAuth can only issue a regular token that is not linked to a device.
 ||
|| `redirect_uri` | A URL to redirect the user to after they grant access to the app. By default, the first Redirect URI specified in the (**Platforms** → **Web services** → **Redirect URI**) app settings is used.

The parameter value can only contain URLs listed in the app settings. If the match isn't exact, this parameter is ignored. ||
|| `login_hint` | Explicit indication of the account the token is requested for. The Yandex account username and the Yandex Mail or Yandex Mail for Domain address can be passed in the parameter value.

This parameter allows you to help the user log in to Yandex with the account that the app needs access to. When Yandex OAuth receives this parameter, it checks the user's authorization:

* If the user is already logged in with the desired account, Yandex OAuth asks for access permission.
* If the user isn't logged in with the appropriate account, they see the Yandex login form where the login field is filled in with the parameter value. Remember that the token won't necessarily be requested for the specified account: the user can erase the pre-filled username and log in with any other.

If this parameter indicates a nonexistent account, Yandex OAuth will only be able to inform the user. The app will have to request the token again. ||
|| `scope` | List of the access rights the app requires. Values in the list are separated by commas.

Rights must be requested from the list defined when [registering the app](https://yandex.com.tr/dev/id/doc/en/register-client.md#access). To see the allowed permissions, open the link [https://oauth.yandex.com/client/<client_id>/info](https://oauth.yandex.com/client/<client_id>/info), replacing <client_id> with your app's ID.

If the `scope` and `optional_scope` parameters aren't passed, the token will be issued with the rights specified when registering the application.
||
|| `optional_scope` | Optional permissions are requested in addition to those specified in the `scope` parameter.  

Rights must be requested from the list defined when [registering the app](https://yandex.com.tr/dev/id/doc/en/register-client.md#access). To see the allowed permissions, open the link [https://oauth.yandex.com/client/<client_id>/info](https://oauth.yandex.com/client/<client_id>/info), replacing <client_id> with your app's ID.

The user decides which requested optional rights to grant. The token will be issued with the rights specified in the `scope` parameter, and the rights selected by the user from the list specified in the `optional_scope` parameter.

This parameter can be used, for example, if the app needs an email to register the user, and access to the portrait is preferred, but not required.

{% note info %}

All access rights requested at once via the `scope` and `optional_scope` parameters are considered optional.

{% endnote %}
 ||
|| `force_confirm` | Indicates that the user must request permission to access the account (even if the user already allowed access to this app). After receiving this parameter, Yandex OAuth will prompt the user to allow access to the app and choose the Yandex account.

This parameter is needed, for example, if the user logged in to the website under one Yandex account, and wants to switch to another one. If the parameter isn't used, the user will explicitly have to switch accounts in a Yandex service or revoke the token issued to the website.

The parameter is processed if its value is `yes`, `true`, or `1`. In case of any other value, the parameter is ignored. ||
|| `state` | The status bar that Yandex OAuth returns without changes. The maximum allowed string length is 1024 characters. Can be used, for example, to protect against [CSRF attacks](https://en.wikipedia.org/wiki/Cross-site_request_forgery) or identify the user the token is requested for.
||
|| `code_challenge` | The `code_verifier` version transformed using the `code_challenge_method`. It's meant for cases when working with the PKCE extension for protecting transmitted data. The code challenge is generated by the app so that later it can be verified that the request for a token is coming from the same app as the request for an authorization code. ||
|| `code_challenge_method` | The method of transforming the `code_verifier` into a `code_challenge`. Possible values: `S256` (preferred) and `plain` (for cases where S256 can't be used). ||
|#
<!-- endsource: en/_includes/oauth/code-request.md -->

### Response format {#code-response}

When a user allows access to their data, Yandex OAuth shows a confirmation code.

![image](../_assets/code.png =500x)

<!-- source: en/_includes/oauth/code-time.md -->
The lifetime of this code is 10 minutes. After this time, the code must be requested again.
<!-- endsource: en/_includes/oauth/code-time.md -->

## Exchanging a confirmation code for an OAuth token {#token}

### Request format {#token-request}

<!-- source: en/_includes/oauth/token-code-request.md -->
```
POST /token HTTP/1.1
Host: https://oauth.yandex.com/
Content-type: application/x-www-form-urlencoded
Content-Length: <request body length>
[Authorization: Basic <Base64-encoded string `client_id:client_secret`>]

   grant_type=authorization_code
 & code=<confirmation code>
[& client_id=<app ID>]
[& client_secret=<secret key>]
[& device_id=<device ID>]
[& device_name=<device name>]
[& code_verifier=<verifier>]
```

#### Required parameters

#|
|| **Parameter** | **Description** ||
|| `grant_type` | The method used to request the OAuth token.

If you use a confirmation code, specify the `authorization_code` value. ||
|| `code` | Confirmation code from Yandex OAuth.

The lifetime of this code is 10 minutes. After this time, the code must be requested again.
 ||
|#

#### Advanced parameters

#|
|| **Parameter** | **Description** ||
|| `client_id` | Application ID. Available in the [app properties](https://yandex.com.tr/dev/id/doc/en/register-client.md#app-params). To open properties, go to [Yandex OAuth](https://oauth.yandex.com/) and click the app name.

The secret key and app ID can also be passed in the [`Authorization` header](#auth-header).
||
|| `client_secret` | Secret key. Available in the [app properties](https://yandex.com.tr/dev/id/doc/en/register-client.md#app-params). To open properties, go to [Yandex OAuth](https://oauth.yandex.com/) and click the app name.

The secret key and app ID can also be passed in the [`Authorization` header](#auth-header).

If the PKCE extension is used for data protection and the `code_verifier` parameter is passed in the request, you don't need to pass the secret key.||
|| `device_id` | Unique ID of the device the token is requested for. To ensure uniqueness, just generate a [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier) once and use it every time a new token is requested from this device.

The ID must be from 6 to 50 characters long. Only printable [ASCII](https://en.wikipedia.org/wiki/ASCII) characters are allowed (with codes from 32 to 126).

Learn more about tokens for individual devices on the [Revoking a token for a specific device](https://yandex.com.tr/dev/id/doc/en/tokens/token-invalidate.md#device-token) page.

If the `device_id` parameter is sent without the `device_name` parameter, the token is marked as issued for an unknown device in the user interface.

<!-- source: en/_includes/oauth/concepts/device-token/id-device-token/limit.md -->
{% note alert %}

An app can have up to 30 tokens linked to a user's devices. If Yandex OAuth issues a new device token for the app, the oldest token stops working.

{% endnote %}
<!-- endsource: en/_includes/oauth/concepts/device-token/id-device-token/limit.md -->

||
|| `device_name` | The name of the device to show users. Up to 100 characters.

For mobile devices, we recommend passing the device name specified by the user. If a name is missing, the name can be taken from the device model, OS name and version, and so on.

If the `device_name` parameter is sent without the `device_id` parameter, it is ignored. Yandex OAuth can only issue a regular token that is not linked to a device.
 ||
|| `code_verifier` | The verifier ensuring that transmitted data is protected. This parameter is used when working with the PKCE protocol extension. It's an arbitrary string generated by the app. `code_challenge` is formed based on this string. The server transforms the `code_verifier` using the `code_challenge_method` received in the [request for a confirmation code](https://yandex.com.tr/dev/id/doc/en/codes/code-url.md#code) and compares the result with the `code_challenge` from the same request.||
|#

<!-- source: en/_includes/oauth/reference/auto-code-client/id-auto-code-client/auth-header.md -->
Request parameters must be passed in the request body and must be URL-encoded.

{% note info %}

To pass the ID and the secret key in the `Authorization` header, encode the `<client_id>:<client_secret>` string using the base64 method. 

If Yandex OAuth receives the `Authorization` header, while the `client_id` and `client_secret` parameters in the request body are ignored. {#auth-header}

{% endnote %}
<!-- endsource: en/_includes/oauth/reference/auto-code-client/id-auto-code-client/auth-header.md -->
<!-- endsource: en/_includes/oauth/token-code-request.md -->

### Response format {#token-response}

<!-- source: en/_includes/oauth/token-code-response.md -->
{% list tabs %}

- Request successfully completed

   Yandex OAuth returns the OAuth token, refresh token, and their lifetime in JSON format:

   ```json
   200 OK
   Content-type: application/json{
     "token_type": "bearer",
     "access_token": "AQAAAACy1C6ZAAAAfa6vDLuItEy8pg-iIpnDxIs",
     "expires_in": 124234123534,
     "refresh_token": "1:GN686QVt0mmakDd9:A4pYuW9LGk0_UnlrMIWklkAuJkUWbq27loFekJVmSYrdfzdePBy7:A-2dHOmBxiXgajnD-kYOwQ",
     "scope": "login:info login:email login:avatar"
   }
   ```

  Response parameters:

   #|
   || **Property** | **Description** ||
   || `token_type` | Type of token issued. Always takes the `bearer` value.
 ||
   || `access_token` | An OAuth token with the permissions you requested or specified when [registering your app](https://yandex.com.tr/dev/id/doc/en/register-client.md#access).
 ||
   || `expires_in` | [Token lifetime](https://yandex.com.tr/dev/id/doc/en/concepts/ya-oauth-intro.md#ttl) in seconds. 
 ||
   || `refresh_token` | A token that can be used to [extend the lifetime](https://yandex.com.tr/dev/id/doc/en/tokens/refresh-client.md) of the corresponding OAuth token. [The lifetime](https://yandex.com.tr/dev/id/doc/en/concepts/ya-oauth-intro.md#ttl) of the refresh token is the same as the OAuth token lifetime.||
   || `scope` | Rights requested by the developer or specified when [registering the app](https://yandex.com.tr/dev/id/doc/en/register-client.md#access). The `scope` field is optional and is returned if OAuth provided a token with a smaller set of rights than requested. ||
   |#

- Request completed with an error

   If a token couldn't be issued, the response contains a description of the error:

   ```json
   {
      "error_description": "<error message>",
      "error": "<error code>"
   }
   ```

   Error codes:

   * `authorization_pending`: The user didn't enter the confirmation code yet.
   
   * `bad_verification_code`: The passed `code` parameter value isn't a 7-digit number.
   
   * <!-- source: en/_includes/oauth/errors/invalid-client.md -->
     `invalid_client`: The app with the specified ID (the `client_id` parameter) wasn't found or is blocked. This code is also returned if the `client_secret` parameter passed an invalid app password.
     <!-- endsource: en/_includes/oauth/errors/invalid-client.md -->
   
   * `invalid_grant` — Invalid or expired confirmation code.
   
   * <!-- source: en/_includes/oauth/errors/invalid-request.md -->
     `invalid_request`: Invalid request format (one of the parameters isn't specified, specified twice, or isn't passed in the request body).
     <!-- endsource: en/_includes/oauth/errors/invalid-request.md -->
   
   * `invalid_scope`: The app rights changed after the confirmation code was generated.
   
   * <!-- source: en/_includes/oauth/errors/unauthorized-client.md -->
     `unauthorized_client`: The app was rejected during moderation or is awaiting moderation. Also returned if the app is blocked.
     <!-- endsource: en/_includes/oauth/errors/unauthorized-client.md -->
   
   * <!-- source: en/_includes/oauth/errors/grant-type.md -->
     `unsupported_grant_type`: Invalid `grant_type` parameter value.
     <!-- endsource: en/_includes/oauth/errors/grant-type.md -->
   
   * <!-- source: en/_includes/oauth/errors/basic-auth.md -->
     `Basic auth required`: The authorization type specified in the `Authorization` header is not <q>Basic</q>.
     <!-- endsource: en/_includes/oauth/errors/basic-auth.md -->
   
   * <!-- source: en/_includes/oauth/errors/mailformed.md -->
     `Malformed Authorization header`: The `Authorization` header isn't in `<client_id>:<client_secret>` format, or this string isn't Base64-encoded.
     <!-- endsource: en/_includes/oauth/errors/mailformed.md -->

{% endlist %}
<!-- endsource: en/_includes/oauth/token-code-response.md -->
