Code-Based Linking (CBL) for Other Devices and Platforms
To access the Alexa Voice Service (AVS), your Alexa Built-in product needs to obtain a Login with Amazon (LWA) access token that is sent with each request to AVS. This document describes code-based linking (CBL), an authorization method optimal for products with limited or no access to character input, such as a television or smart watch.
During product registration, the user is provided with a short alphanumeric code, and a URL. On a separate device with access to a browser, the user visits the URL, logs in with their Amazon credentials, and enters the short code to link the product with their Amazon account. Once linked, the product notifies the user with a splash screen and provides access to AVS.
- Auth flow
- Step 1: Enable CBL
- Step 2: Device Authorization Request
- Step 3: Direct the user to log in
- Step 4: Device Token Request
- Step 5: Exchange the refresh token for a new access token
- Resources
Auth flow
This diagram illustrates the exchanges between your Alexa Built-in product and LWA to obtain an access_token
and refresh_token
for use with AVS:

Step 1: Enable CBL
- Log in to Your Alexa Dashboards, select Alexa Voice Service, then
- Click Manage to enable CBL for an existing product -or-
- Click Create Product to create a new product
- Locate and click on the Security Profiles tab, then select Other devices and platforms.
- Enter a Client ID name, then click Generate ID.
- Save the Client ID, you'll need this later.

Step 2: Device Authorization Request
First, your Alexa Built-in product must make a POST
request to obtain the user code and URL from LWA. If a valid response is returned, it must display the user_code
and verification_uri
to the customer.
Request
Endpoint: https://api.amazon.com/auth/O2/create/codepair
The request must include these parameters:
response_type
: The expected value isdevice_code
. This informs the service that this is a CBL request.client_id
: The Client ID you created in step 1.scope
: The expected value isalexa:all
. This specifies permissions for your product.scope_data
: Additional JSON that includes product-specific information, such asproductID
anddeviceSerialNumber
. Sample JSON is provided below.productID
: The Device Type ID for your product. To access this information, navigate to Amazon's Developer Console. After you've logged in, click Alexa, then Get Started > under Alexa Voice Service. Click Edit next to a registered product (or create a new one). This page contains both Client ID and Client Secret for your product.productInstanceAttributes
: an object containing thedeviceSerialNumber
.deviceSerialNumber
: A key that uniquely identifies this instance of your product. For example, this could be a serial number or MAC address.
Note: This is a sample scope object before it is URL-encoded.{ "alexa:all": { "productID": "{{productId}}", "productInstanceAttributes": { "deviceSerialNumber": "{{deviceSerialNumber}}" } } }
Optional: Include the Accept-Language
header in your request to select the language the login and registration language for your user.
- Accepted values:
en-US
,de-DE
,es-ES
,en-GB
,fr-FR
,it-IT
,pt-BR
,ja-JP
,zh-CN
.
Sample Request
This is a sample curl request:
curl -k -d 'response_type=device_code&client_id={{client_id}}&scope=alexa%3Aall&scope_data=%7B%22alexa%3Aall%22%3A%7B%22productID%22%3A%22Speaker%22,%22productInstanceAttributes%22%3A%7B%22deviceSerialNumber%22%3A%2212345%22%7D%7D%7D' -H "Content-Type: application/x-www-form-urlencoded" -X POST https://api.amazon.com/auth/O2/create/codepair
Response
The response is formatted according to section 3.4 of the OAuth specification. If the input is valid, the response will be structured as follows:
Sample Response
{ "user_code": "{{STRING}}", "device_code": "{{STRING}}", "verification_uri": "{{STRING}}", "expires_in": {{INTEGER}}, "interval": {{INTEGER}} }
Parameter | Description | Type |
---|---|---|
user_code | The code displayed to the user. This code is entered by the user during registration. | string |
device_code | The code required to make a Device Token Request. This value should be kept secret. | string |
verification_uri | The URL that you present to the user. | string |
expires_in | The length of time in seconds that the codes are valid. | integer |
interval | The interval in seconds for time between Device Token Requests. | integer |
Errors
HTTP 400: MissingValue
HTTP 500: ServiceError
HTTP 503: ServiceUnavailable
Step 3: Direct the user to log in
When your product receives a response to the Device Authorization Request, it must display the user_code
and verification_uri
to the user. Use the design guidance and example screens provided in Setup and Authentication.
When the user navigates to the verification_uri
, they are instructed to login with their Amazon developer credentials and enter the provided user_code
. The Code Registration Page implements the User Instruction component of the OAuth specification.

After entering the user_code
the user is directed to a page indicating a successful or failed authentication. If authentication fails, the page will provide the reason for failure (code already authorized, unrecognized, code, etc.).
Step 4: Device Token Request
After you've instructed the user to log in, your product begins polling for an access_token
and refresh_token
.
Request
Endpoint: https://api.amazon.com/auth/O2/token
The request must include the following headers:
POST /auth/o2/token Host: api.amazon.com Content-Type: application/x-www-form-urlencoded
The request must include these parameters:
grant_type
: The expected value isdevice_code
. This informs the service of the grant type.device_code
: The code returned in Device Authorization Request.user_code
: The code displayed to the user. This code is entered by the user during registration.
Response
After the user has completed the registration flow, the response will match this structure:
{ "access_token": "{{STRING}}", "refresh_token": "{{STRING}}", "token_type": "bearer", "expires_in": {{INTEGER}} }
access_token
: The access token.refresh_token
: The refresh token.token_type
: bearerexpires_in
: The number of seconds the access token is valid.
authorization_pending
, slow_down
, invalid_code_pair
, invalid_client
, unauthorized_client
. On invalid_code_pair
, restart the registration flow.Step 5: Exchange the refresh token for a new access token
When the access token expires (or is about to expire), the refresh token is exchanged for a new access token. If the token exchange fails, your client is expected to retry with an exponential back-off. A new connection with AVS should only be made with the tokens are successfully received and updated. Make a POST
to https://api.amazon.com/auth/O2/token
with these parameters in the constructed URL:
grant_type
:refresh_token
refresh_token
: The refresh token.client_id
: The client ID.
The response includes the following values:
access_token
: The access token.refresh_token
: The refresh token.token_type
:bearer
expires_in
: The number of seconds for which the access token is still valid.