Authlete Device Flow API
API endpoints for implementing OAuth 2.0 Device Flow
API endpoints for implementing OAuth 2.0 Device Flow
openapi: 3.0.3
info:
title: Authlete Authorization Endpoint Device Flow API
description: "Welcome to the **Authlete API documentation**. Authlete is an **API-first service** where every aspect of the \nplatform is configurable via API. This documentation will help you authenticate and integrate with Authlete to \nbuild powerful OAuth 2.0 and OpenID Connect servers.\n\nAt a high level, the Authlete API is grouped into two categories:\n\n- **Management APIs**: Enable you to manage services and clients.\n- **Runtime APIs**: Allow you to build your own Authorization Servers or Verifiable Credential (VC) issuers.\n\n## \U0001F310 API Servers\n\nAuthlete is a global service with clusters available in multiple regions across the world:\n\n- \U0001F1FA\U0001F1F8 **US**: `https://us.authlete.com`\n- \U0001F1EF\U0001F1F5 **Japan**: `https://jp.authlete.com`\n- \U0001F1EA\U0001F1FA **Europe**: `https://eu.authlete.com`\n- \U0001F1E7\U0001F1F7 **Brazil**: `https://br.authlete.com`\n\nOur customers can host their data in the region that best meets their requirements.\n\n## \U0001F511 Authentication\n\nAll API endpoints are secured using **Bearer token authentication**. You must include an access token in every request:\n\n```\nAuthorization: Bearer YOUR_ACCESS_TOKEN\n```\n\n### Getting Your Access Token\n\nAuthlete supports two types of access tokens:\n\n**Service Access Token** - Scoped to a single service (authorization server instance)\n\n1. Log in to [Authlete Console](https://console.authlete.com)\n2. Navigate to your service → **Settings** → **Access Tokens**\n3. Click **Create Token** and select permissions (e.g., `service.read`, `client.write`)\n4. Copy the generated token\n\n**Organization Token** - Scoped to your entire organization\n\n1. Log in to [Authlete Console](https://console.authlete.com)\n2. Navigate to **Organization Settings** → **Access Tokens**\n3. Click **Create Token** and select org-level permissions\n4. Copy the generated token\n\n> ⚠️ **Important Note**: Tokens inherit the permissions of the account that creates them. Service tokens can only \n> access their specific service, while organization tokens can access all services within your org.\n\n### Token Security Best Practices\n\n- **Never commit tokens to version control** - Store in environment variables or secure secret managers\n- **Rotate regularly** - Generate new tokens periodically and revoke old ones\n- **Scope appropriately** - Request only the permissions your application needs\n- **Revoke unused tokens** - Delete tokens you're no longer using from the console\n\n### Quick Test\n\nVerify your token works with a simple API call:\n\n```bash\ncurl -X GET https://us.authlete.com/api/service/get/list \\\n -H \"Authorization: Bearer YOUR_ACCESS_TOKEN\"\n```\n\n## \U0001F393 Tutorials\n\nIf you're new to Authlete or want to see sample implementations, these resources will help you get started:\n\n- [Getting Started with Authlete](https://www.authlete.com/developers/getting_started/)\n- [From Sign-Up to the First API Request](https://www.authlete.com/developers/tutorial/signup/)\n\n## \U0001F6E0 Contact Us\n\nIf you have any questions or need assistance, our team is here to help:\n\n- [Contact Page](https://www.authlete.com/contact/)\n"
version: 3.0.16
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0.html
servers:
- description: 🇺🇸 US Cluster
url: https://us.authlete.com
- description: 🇯🇵 Japan Cluster
url: https://jp.authlete.com
- description: 🇪🇺 Europe Cluster
url: https://eu.authlete.com
- description: 🇧🇷 Brazil Cluster
url: https://br.authlete.com
security:
- bearer: []
tags:
- name: Device Flow
description: API endpoints for implementing OAuth 2.0 Device Flow
x-tag-expanded: false
paths:
/api/{serviceId}/device/authorization:
post:
summary: Process Device Authorization Request
description: 'This API parses request parameters of a [device authorization request](https://datatracker.ietf.org/doc/html/rfc8628#section-3.1)
and returns necessary data for the authorization server implementation to process the device authorization
request further.
'
x-mint:
metadata:
description: This API parses request parameters of a [device authorization request](https://datatracker.ietf.org/doc/html/rfc8628#section-3.1) and returns necessary data for the authorization server implementation to process the device authorization request further.
content: '<Accordion title="Full description" defaultOpen={false}>
This API is supposed to be called from the within the implementation of the device authorization
endpoint of the service. The service implementation should retrieve the value of `action` from the
response and take the following steps according to the value.
## INTERNAL_SERVER_ERROR
When the value of `action` is `INTERNAL_SERVER_ERROR`, it means that the API call from the authorization
server implementation was wrong or that an error occurred in Authlete.
In either case, from a viewpoint of the client application, it is an error on the server side.
Therefore, the authorization server implementation should generate a response to the client application
with "500 Internal Server Error"s and `application/json`.
The value of `responseContent` is a JSON string which describes t he error, so it can be
used as the entity body of the response.
---
The following illustrates the response which the authorization server implementation should generate
and return to the client application.
```
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{responseContent}
```
## BAD_REQUEST
When the value of `action` is `BAD_REQUEST`, it means that the request from the client application
is wrong.
The authorization server implementation should generate a response to the client application with
"400 Bad Request" and `application/json`.
The value of `responseContent` is a JSON string which describes the error, so it can be used as
the entity body of the response.
---
The following illustrates the response which the service implementation should generate and return
to the client application.
```
HTTP/1.1 400 Bad Request
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{responseContent}
```
## UNAUTHORIZED
When the value of `action` is `UNAUTHORIZED`, it means that client authentication of the device authorization
request failed.
The authorization server implementation should generate a response to the client application with
"401 Unauthorized" and `application/json`.
The value of `responseContent` is a JSON string which describes the error, so it can be used as
the entity body of the response.
---
The following illustrates the response which the service implementation must generate and return
to the client application.
```
HTTP/1.1 401 Unauthorized
WWW-Authenticate: (challenge)
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{responseContent}
```
## OK
When the value of `action` is `OK`, it means that the device authorization request from the client
application is valid.
The authorization server implementation should generate a response to the client application with
"200 OK" and `application/json`.
The `responseContent` is a JSON string which can be used as the entity body of the response.
---
The following illustrates the response which the authorization server implementation should generate
and return to the client application.
</Accordion>
'
parameters:
- in: path
name: serviceId
description: A service ID.
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/device_authorization_request'
example:
parameters: client_id=26888344961664&scope=history.read
clientId: '26888344961664'
clientSecret: SfnYOLkJdofrb_66mTd6q03_SDoDEUnpXtvqFaE4k6L6UcpZzbdVJi2GpBj48AvGeDDllwsTruC62WYqQ_LGog
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/device_authorization_request'
responses:
'200':
description: ''
content:
application/json:
schema:
$ref: '#/components/schemas/device_authorization_response'
example:
resultCode: A220001
resultMessage: '[A220001] The device authorization request was processed successfully.'
action: OK
clientId: 26888344961664
clientIdAliasUsed: false
clientName: My Device Flow Client
deviceCode: p0qzXeRav8u6lJY9omjzR47KK58VwYN7j8xGUD7sq5I
expiresIn: 3600
interval: 0
responseContent: '{"user_code":"XWWKPBWVXQ","device_code":"p0qzXeRav8u6lJY9omjzR47KK58VwYN7j8xGUD7sq5I","verification_uri_complete":"https://my-service.com/df/verification?XWWKPBWVXQ","verification_uri":"https://my-service.com/df/verification","expires_in":3600}'
scopes:
- defaultEntry: false
name: history.read
serviceAttributes:
- key: attribute1-key
value: attribute1-value
- key: attribute2-key
value: attribute2-value
userCode: XWWKPBWVXQ
verificationUri: https://my-service.com/df/verification
verificationUriComplete: https://my-service.com/df/verification?XWWKPBWVXQ
links:
device_verify:
$ref: '#/components/links/device_verification'
device_poll_token:
$ref: '#/components/links/device_complete'
'400':
$ref: '#/components/responses/400'
'401':
$ref: '#/components/responses/401'
'403':
$ref: '#/components/responses/403'
'500':
$ref: '#/components/responses/500'
operationId: device_authorization_api
x-code-samples:
- lang: shell
label: curl
source: 'curl -v -X POST https://us.authlete.com/api/21653835348762/device/authorization \
-H ''Content-Type: application/json'' \
-H ''Authorization: Bearer V5a40R6dWvw2gMkCOBFdZcM95q4HC0Z-T0YKD9-nR6F'' \
-d ''{ "parameters": "client_id=26888344961664&scope=history.read", "clientId": "26888344961664", "clientSecret":"SfnYOLkJdofrb_66mTd6q03_SDoDEUnpXtvqFaE4k6L6UcpZzbdVJi2GpBj48AvGeDDllwsTruC62WYqQ_LGog" }''
'
- lang: java
label: java
source: 'AuthleteConfiguration conf = ...;
AuthleteApi api = AuthleteApiFactory.create(conf);
DeviceAuthorizationRequest req = new DeviceAuthorizationRequest();
req.setParameters(...);
req.setClientId("26888344961664");
req.setClientSecret("SfnYOLkJdofrb_66mTd6q03_SDoDEUnpXtvqFaE4k6L6UcpZzbdVJi2GpBj48AvGeDDllwsTruC62WYqQ_LGog");
api.deviceAuthorization(req);
'
- lang: python
source: 'conf = ...
api = AuthleteApiImpl(conf)
req = DeviceAuthorizationRequest()
req.parameters = ...
req.clientId = ''26888344961664''
req.clientSecret = ''SfnYOLkJdofrb_66mTd6q03_SDoDEUnpXtvqFaE4k6L6UcpZzbdVJi2GpBj48AvGeDDllwsTruC62WYqQ_LGog''
api.deviceAuthorization(req)
'
tags:
- Device Flow
/api/{serviceId}/device/verification:
post:
summary: Process Device Verification Request
description: 'The API returns information associated with a user code.
'
x-mint:
metadata:
description: The API returns information associated with a user code.
content: '<Accordion title="Full description" defaultOpen={false}>
After receiving a response from the device authorization endpoint of the authorization server,
the client application shows the end-user the user code and the verification URI which are included
in the device authorization response. Then, the end-user will access the verification URI using
a web browser on another device (typically, a smart phone). In normal implementations, the verification
endpoint will return an HTML page with an input form where the end-user inputs a user code. The
authorization server will receive a user code from the form.
After receiving a user code, the authorization server should call Authlete''s `/device/verification`
API with the user code. And then, the authorization server implementation should retrieve the value
of `action` parameter from the API response and take the following steps according to the value.
## SERVER_ERROR
When the value of `action` is `SERVER_ERROR`, it means that an error occurred on Authlete side. The
authorization server implementation should tell the end-user that something wrong happened and
urge her to re-initiate a device flow.
## NOT_EXIST
When the value of `action` is `NOT_EXIST`, it means that the user code does not exist. The authorization
server implementation should tell the end-user that the user code is invalid and urge her to retry
to input a valid user code.
## EXPIRED
When the value of `action` is `EXPIRED`, it means that the user code has expired. The authorization
server implementation should tell the end-user that the user code has expired and urge her to
re-initiate a device flow.
## VALID
When the value of `action` is `VALID`, it means that the user code exists, has not expired, and
belongs to the service. The authorization server implementation should interact with the end-user
to ask whether she approves or rejects the authorization request from the device.
</Accordion>
'
parameters:
- in: path
name: serviceId
description: A service ID.
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/device_verification_request'
example:
userCode: XWWKPBWVXQ
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/device_verification_request'
responses:
'200':
description: Device verification completed successfully
content:
application/json:
schema:
$ref: '#/components/schemas/device_verification_response'
example:
resultCode: A224001
resultMessage: '[A224001] The user code is valid.'
action: VALID
clientId: 26888344961664
clientIdAliasUsed: false
clientName: My Device Flow Client
expiresAt: 1642001978000
scopes:
- defaultEntry: false
name: history.read
serviceAttributes:
- key: attribute1-key
value: attribute1-value
- key: attribute2-key
value: attribute2-value
'400':
$ref: '#/components/responses/400'
'401':
$ref: '#/components/responses/401'
'403':
$ref: '#/components/responses/403'
'500':
$ref: '#/components/responses/500'
operationId: device_verification_api
x-code-samples:
- lang: shell
label: curl
source: 'curl -v -X POST https://us.authlete.com/api/21653835348762/device/verification \
-H ''Content-Type: application/json'' \
-H ''Authorization: Bearer V5a40R6dWvw2gMkCOBFdZcM95q4HC0Z-T0YKD9-nR6F'' \
-d ''{ "userCode": "XWWKPBWVXQ" }''
'
- lang: java
label: java
source: 'AuthleteConfiguration conf = ...;
AuthleteApi api = AuthleteApiFactory.create(conf);
DeviceVerificationRequest req = new DeviceVerificationRequest();
req.setUserCode("XWWKPBWVXQ");
api.deviceVerification(req);
'
- lang: python
source: 'conf = ...
api = AuthleteApiImpl(conf)
req = DeviceVerificationRequest()
req.setUserCode(''XWWKPBWVXQ'')
api.deviceVerification(req)
'
tags:
- Device Flow
/api/{serviceId}/device/complete:
post:
summary: Complete Device Authorization
description: 'This API returns information about what action the authorization server should take after it receives
the result of end-user''s decision about whether the end-user has approved or rejected a client
application''s request.
'
x-mint:
metadata:
description: This API returns information about what action the authorization server should take after it receives the result of end-user's decision about whether the end-user has approved or rejected a client application's request.
content: '<Accordion title="Full description" defaultOpen={false}>
In the device flow, an end-user accesses the verification endpoint of the authorization server where
she interacts with the verification endpoint and inputs a user code. The verification endpoint checks
if the user code is valid and then asks the end-user whether she approves or rejects the authorization
request which the user code represents.
After the authorization server receives the decision of the end-user, it should call Authlete''s
`/device/complete` API to tell Authlete the decision.
When the end-user was authenticated and authorization was granted to the client by the end-user,
the authorization server should call the API with `result=AUTHORIZED`. In this successful case,
the subject request parameter is mandatory. The API will update the database record so that `/auth/token`
API can generate an access token later.
If the `scope` parameter of the device authorization request included the openid scope, an ID token
is generated. In this case, `sub`, `authTime`, `acr` and `claims` request parameters in the API
call to `/device/complete` affect the ID token.
When the authorization server receives the decision of the end-user and it indicates that she has
rejected to give authorization to the client, the authorization server should call the API with
`result=ACCESS_DENIED`. In this case, the API will update the database record so that the `/auth/token`
API can generate an error response later. If `errorDescription` and `errorUri` request parameters
are given to the `/device/complete` API, they will be used as the values of `error_description`
and `error_uri` response parameters in the error response from the token endpoint.
When the authorization server could not get decision from the end-user for some reasons, the authorization
server should call the API with `result=TRANSACTION_FAILED`. In this error case, the API will behave
in the same way as in the case of `ACCESS_DENIED`. The only difference is that `expired_token` is
used as the value of the `error` response parameter instead of `access_denied`.
After receiving a response from the `/device/complete` API, the implementation of the authorization
server should retrieve the value of `action` from the response and take the following steps according
to the value.
## SERVER_ERROR
When the value of `action` is `SERVER_ERROR`, it means that an error occurred on Authlete side. The
authorization server implementation should tell the end-user that something wrong happened and
urge her to re-initiate a device flow.
## USER_CODE_NOT_EXIST
When the value of `action` is `USER_CODE_NOT_EXIST`, it means that the user code included in the API
call does not exist. The authorization server implementation should tell the end-user that the user
code has been invalidated and urge her to re-initiate a device flow.
## USER_CODE_EXPIRED
When the value of `action` is `USER_CODE_EXPIRED`, it means that the user code included in the API
call has expired. The authorization server implementation should tell the end-user that the user
code has expired and urge her to re-initiate a device flow.
## INVALID_REQUEST
When the value of `action` is `INVALID_REQUEST`, it means that the API call is invalid. Probably,
the authorization server implementation has some bugs.
## SUCCESS
When the value of `action` is `SUCCESS`, it means that the API call has been processed successfully.
The authorization server should return a successful response to the web browser the end-user is
using.
</Accordion>
'
parameters:
- in: path
name: serviceId
description: A service ID.
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/device_complete_request'
example:
userCode: XWWKPBWVXQ
result: AUTHORIZED
subject: john
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/device_complete_request'
responses:
'200':
description: ''
content:
application/json:
schema:
$ref: '#/components/schemas/device_complete_response'
example:
resultCode: A241001
resultMessage: '[A241001] The API call was processed successfully.'
action: SUCCESS
'400':
$ref: '#/components/responses/400'
'401':
$ref: '#/components/responses/401'
'403':
$ref: '#/components/responses/403'
'500':
$ref: '#/components/responses/500'
operationId: device_complete_api
x-code-samples:
- lang: shell
label: curl
source: 'curl -v -X POST https://us.authlete.com/api/21653835348762/device/complete \
-H ''Content-Type: application/json'' \
-H ''Authorization: Bearer V5a40R6dWvw2gMkCOBFdZcM95q4HC0Z-T0YKD9-nR6F'' \
-d ''{ "userCode": "XWWKPBWVXQ", "result": "AUTHORIZED", "subject": "john" }''
'
- lang: java
label: java
source: 'AuthleteConfiguration conf = ...;
AuthleteApi api = AuthleteApiFactory.create(conf);
DeviceCompleteRequest req = new DeviceCompleteRequest();
req.setUserCode("XWWKPBWVXQ");
req.setResult(DeviceCompleteRequest.Result.AUTHORIZED);
req.setSubject("john");
api.deviceComplete(req);
'
- lang: python
source: 'conf = ...
api = AuthleteApiImpl(conf)
req = DeviceCompleteRequest()
req.setUserCode(''XWWKPBWVXQ'')
req.setResult(DeviceCompleteResult.AUTHORIZED)
req.setSubject(''john'')
api.deviceComplete(req)
'
tags:
- Device Flow
components:
links:
device_complete:
operationId: device_complete_api
parameters:
serviceId: $request.path.serviceId
device_verification:
operationId: device_verification_api
parameters:
serviceId: $request.path.serviceId
schemas:
device_complete_request:
type: object
required:
- userCode
- result
- subject
properties:
userCode:
type: string
description: 'A user code.
'
result:
type: string
enum:
- TRANSACTION_FAILED
- ACCESS_DENIED
- AUTHORIZED
description: 'The result of the end-user authentication and authorization. One of the following. Details are
described in the description.
'
subject:
type: string
description: 'The subject (= unique identifier) of the end-user.
'
sub:
type: string
description: 'The value of the sub claim that should be used in the ID token.
'
authTime:
type: integer
format: int64
description: 'The time at which the end-user was authenticated. Its value is the number of seconds from `1970-01-01`.
'
acr:
type: string
description: 'The reference of the authentication context class which the end-user authentication satisfied.
'
claims:
type: string
description: 'Additional claims which will be embedded in the ID token.
'
properties:
type: array
items:
$ref: '#/components/schemas/property'
description: 'The extra properties associated with the access token.
'
scopes:
type: array
items:
type: string
description: 'Scopes to replace the scopes specified in the original device authorization request with.
When nothing is specified for this parameter, replacement is not performed.
'
errorDescription:
type: string
description: 'The description of the error. If this optional request parameter is given, its value is used as
the value of the `error_description` property, but it is used only when the result is not `AUTHORIZED`.
To comply with the specification strictly, the description must not include characters outside
the set `%x20-21 / %x23-5B / %x5D-7E`.
'
errorUri:
type: string
description: 'The URI of a document which describes the error in detail. This corresponds to the `error_uri`
property in the response to the client.
'
idtHeaderParams:
type: string
description: 'JSON that represents additional JWS header parameters for ID tokens.
'
consentedClaims:
type: array
items:
type: string
description: 'the claims that the user has consented for the client application
to know.
'
jwtAtClaims:
type: string
description: 'Additional claims that are added to the payload part of the JWT access token.
'
accessTokenDuration:
type: integer
format: int64
description: 'The duration (in seconds) of the access token that may be issued as a result of the Authlete
API call.
When this request parameter holds a positive integer, it is used as the duration of the access
token in. In other cases, this request parameter is ignored.
'
refreshTokenDuration:
type: integer
format: int64
description: 'The duration (in seconds) of the refresh token that may be issued as a result of the Authlete
API call.
When this request parameter holds a positive integer, it is used as the duration of the refresh
token in. In other cases, this request parameter is ignored.
'
idTokenAudType:
type: string
description: 'The type of the `aud` claim of the ID token being issued. Valid values are as follows.
| Value | Description |
| ----- | ----------- |
| "array" | The type of the aud claim is always an array of strings. |
| "string" | The type of the aud claim is always a single string. |
| null | The type of the aud claim remains the same as before. |
This request parameter takes precedence over the `idTokenAudType` property of the service.
'
tagged_value:
type: object
properties:
tag:
type: string
description: The language tag part.
value:
type: string
description: The value part.
device_complete_response:
type: object
properties:
resultCode:
type: string
description: The code which represents the result of the API call.
resultMessage:
type: string
description: A short message which explains the result of the API call.
action:
type: string
enum:
- SERVER_ERROR
- USER_CODE_NOT_EXIST
- USER_CODE_EXPIRED
- INVALID_REQUEST
- SUCCESS
description: 'The next action that the authorization server implementation should take.
'
device_verification_response:
type: object
properties:
resultCode:
type: string
description: The code which represents the result of the API call.
resultMessage:
type: string
description: A short message which explains the result of the API call.
action:
type: string
enum:
- INTERNAL_SERVER_ERROR
- NOT_EXIST
- EXPIRED
- VALID
description: The next action that the authorization server implementation should take.
clientId:
type: integer
format: int64
description: 'The client ID of the client application to which the user code has been issued.
'
clientIdAlias:
type: string
description: 'The client ID alias of the client application to which the user code has been issued.
'
clientIdAliasUsed:
type: boolean
description: '`true` if the value of the `client_id` request parameter included in the device authorization
request is the client ID alias. `false` if the value is the original numeric client ID.
'
clientName:
type: string
description: 'The name of the client application to which the user code has been issued.
'
scopes:
type: array
items:
$ref: '#/components/schemas/scope'
description: 'The scopes requested by the device authorization request.
Note that `description` property and `descriptions` property of each scope object in
the array contained in this property is always null even if descriptions of the scopes
are registered.
'
claimNames:
type: array
items:
type: string
description: 'The names of the claims which were requested indirectly via some special scopes.
See [5.4. Requesting Claims using Scope Values](https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims)
in OpenID Connect Core 1.0 for details.
This property is always `null` if the `scope` request parameter of the device authorization
request does not include the `openid` scope even if special scopes (such as `profile`)
are included in the request (unless the openid scope is included in the default set
# --- truncated at 32 KB (60 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/authlete/refs/heads/main/openapi/authlete-device-flow-api-openapi.yml