curl --request POST \
--url https://api.tassyir.io/developer/cli/device-code \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data client_id=tassyir-cli \
--data 'client_version=<string>' \
--data 'device_name=<string>' \
--data locale=enconst options = {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: new URLSearchParams({
client_id: 'tassyir-cli',
client_version: '<string>',
device_name: '<string>',
locale: 'en'
})
};
fetch('https://api.tassyir.io/developer/cli/device-code', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"device_code": "<string>",
"user_code": "<string>",
"verification_uri": "<string>",
"verification_uri_complete": "<string>",
"expires_in": 4503599627370496,
"interval": 4503599627370496
}{
"error": "invalid_client",
"error_description": "<string>"
}{
"error": "invalid_request",
"error_description": "<string>"
}{
"error": "slow_down",
"error_description": "<string>"
}{
"statusCode": 123,
"message": "<string>",
"path": "<string>",
"requestId": "<string>"
}{
"statusCode": 123,
"message": "<string>",
"path": "<string>",
"requestId": "<string>"
}Start a CLI sign-in (RFC 8628 §3.1)
Print user_code, open verification_uri_complete (it only pre-fills the code: the developer approves on the page, signed in to the dashboard), then poll POST /developer/cli/token every interval seconds. 10 sign-ins per IP every 10 minutes. Errors are OAuth’s { error, error_description }.
Public: the CLI holds nothing yet.
curl --request POST \
--url https://api.tassyir.io/developer/cli/device-code \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data client_id=tassyir-cli \
--data 'client_version=<string>' \
--data 'device_name=<string>' \
--data locale=enconst options = {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: new URLSearchParams({
client_id: 'tassyir-cli',
client_version: '<string>',
device_name: '<string>',
locale: 'en'
})
};
fetch('https://api.tassyir.io/developer/cli/device-code', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"device_code": "<string>",
"user_code": "<string>",
"verification_uri": "<string>",
"verification_uri_complete": "<string>",
"expires_in": 4503599627370496,
"interval": 4503599627370496
}{
"error": "invalid_client",
"error_description": "<string>"
}{
"error": "invalid_request",
"error_description": "<string>"
}{
"error": "slow_down",
"error_description": "<string>"
}{
"statusCode": 123,
"message": "<string>",
"path": "<string>",
"requestId": "<string>"
}{
"statusCode": 123,
"message": "<string>",
"path": "<string>",
"requestId": "<string>"
}Body
Form-encoded (application/x-www-form-urlencoded, parsed flat) or a flat JSON object: at most 8 KB and 20 parameters, every value one string of at most 4,096 characters, a parameter sent twice refused (invalid_request).
The client starting the sign-in; another is invalid_client.
tassyir-cli Your version, shown on the approval page.
^[0-9A-Za-z][0-9A-Za-z.+-]{0,31}$The machine's name, shown on the approval page and in the token list: letters and digits of any script, spaces and ._-'()@, at most 64 characters after trimming.
64The approval page's language.
ar, en Response
The codes.
RFC 8628 §3.2: the device authorization response.
Poll POST /developer/cli/token with it. Never show it.
^tsy_dc_[0-9A-Za-z]{43}$The code the terminal shows, XXXX-XXXX.
^[BCDFGHJKLMNPQRSTVWXZ]{4}-[BCDFGHJKLMNPQRSTVWXZ]{4}$The approval page: <dashboard>/{locale}/developers/cli.
The same page with ?code=XXXX-XXXX: it pre-fills the code, never approves.
Seconds the codes live (600).
1 <= x <= 9007199254740991Seconds between two polls (5).
1 <= x <= 9007199254740991