Authlete Device Flow API
API endpoints for implementing OAuth 2.0 Device Flow
API endpoints for implementing OAuth 2.0 Device Flow
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/authlete-device-flow-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
openapi: 3.2.0
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:
grant_scope:
type: object
properties:
scope:
type: string
description: 'Space-delimited scopes.
'
resource:
type: array
items:
type: string
description: 'List of resource indicators.
'
grant:
type: object
properties:
scopes:
type: array
items:
$ref: '#/components/schemas/grant_scope'
claims:
type: array
items:
type: string
description: 'The claims associated with the Grant.
'
authorizationDetails:
$ref: '#/components/schemas/authz_details'
grant_management_action:
type: string
description: 'The grant management action of the device authorization request.
The `grant_management_action` request parameter is defined in
[Grant Management for OAuth 2.0](https://openid.net/specs/fapi-grant-management.html).
'
enum:
- CREATE
- QUERY
- REPLACE
- REVOKE
- MERGE
authz_details:
type: object
description: 'The authorization details. This represents the value of the `authorization_details`
request parameter in the preceding device authorization request which is defined in
"OAuth 2.0 Rich Authorization Requests".
'
properties:
elements:
type: array
items:
$ref: '#/components/schemas/authorization_details_element'
description: 'Elements of this authorization details.
'
device_verification_request:
type: object
required:
- userCode
properties:
userCode:
type: string
description: 'A user code.
'
tagged_value:
type: object
properties:
tag:
type: string
description: The language tag part.
value:
type: string
description: The value part.
device_authorization_request:
type: object
required:
- parameters
properties:
parameters:
type: string
description: 'Parameters of a device authorization request which are the request parameters that the device
authorization endpoint of the authorization server implementation received from the client application.
The value of `parameters` is the entire entity body (which is formatted in `application/x-www-form-urlencoded`)
of the request from the client application.
'
clientId:
type: string
description: 'The client ID extracted from Authorization header of the device authorization request from the
client application.
If the device authorization endpoint of the authorization server implementation supports Basic
`Authentication` as a means of client authentication, and the request from the client application
contained its client ID in `Authorization` header, the value should be extracted and set to this
parameter.
'
clientSecret:
type: string
description: 'The client secret extracted from `Authorization` header of the device authorization request from
the client application.
If the device authorization endpoint of the authorization server implementation supports Basic
Authentication as a means of client authentication, and the request from the client application
contained its client secret in `Authorization` header, the value should be extracted and set to
this parameter.
'
clientCertificate:
type: string
description: 'The client certificate used in the TLS connection between the client application and the device
authorization endpoint of the authorization server.
'
clientCertificatePath:
type: array
items:
type: string
description: 'The client certificate path presented by the client during client authentication. Each element
is a string in PEM format.
'
oauthClientAttestation:
type: string
description: 'The value of the `OAuth-Client-Attestation` HTTP header, which is defined in the specification
of [OAuth 2.0 Attestation-Based Client Authentication](https://datatracker.ietf.org/doc/draft-ietf-oauth-attestation-based-client-auth/).
'
oauthClientAttestationPop:
type: string
description: 'The value of the `OAuth-Client-Attestation-PoP` HTTP header, which is defined in the specification
of [OAuth 2.0 Attestation-Based Client Authentication](https://datatracker.ietf.org/doc/draft-ietf-oauth-attestation-based-client-auth/).
'
cimdOptions:
$ref: '#/components/schemas/cimd_options'
description: 'Options for [OAuth Client ID Metadata Document](https://datatracker.ietf.org/doc/draft-ietf-oauth-client-id-metadata-document/) (CIMD).
These options allow per-request control over CIMD behavior, taking precedence over service-level configuration when provided.
'
result:
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.
dynamic_scope:
type: object
properties:
name:
type: string
description: The scope name.
value:
type: string
description: The scope value.
pair:
type: object
properties:
key:
type: string
description: The key part.
value:
type: string
description: The value part.
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 descrip
# --- 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