curl --request POST \
--url https://api.tassyir.io/apps/oauth/token \
--header 'Authorization: Basic <encoded-value>' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data grant_type=urn:ietf:params:oauth:grant-type:token-exchange \
--data 'subject_token=<string>' \
--data subject_token_type=urn:ietf:params:oauth:token-type:id_token \
--data requested_token_type=urn:tassyir:params:oauth:token-type:offline-access-token \
--data 'client_id=<string>'const options = {
method: 'POST',
headers: {
Authorization: 'Basic <encoded-value>',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
grant_type: 'urn:ietf:params:oauth:grant-type:token-exchange',
subject_token: '<string>',
subject_token_type: 'urn:ietf:params:oauth:token-type:id_token',
requested_token_type: 'urn:tassyir:params:oauth:token-type:offline-access-token',
client_id: '<string>'
})
};
fetch('https://api.tassyir.io/apps/oauth/token', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"access_token": "<string>",
"token_type": "Bearer",
"expires_in": 123,
"scope": "<string>",
"installation_id": "<string>",
"business_id": "<string>",
"refresh_token": "<string>",
"refresh_token_expires_in": 123,
"issued_token_type": "urn:tassyir:params:oauth:token-type:offline-access-token",
"user_id": "<string>"
}{
"error": "invalid_grant",
"error_description": "<string>"
}{
"error": "invalid_client",
"error_description": "<string>"
}{
"error": "invalid_request",
"error_description": "<string>"
}{
"error": "slow_down",
"error_description": "<string>"
}{
"statusCode": 123,
"message": "<string>",
"requestId": "<string>"
}{
"error": "temporarily_unavailable",
"error_description": "<string>"
}Get an access token
Three grants: the token exchange of an embedded page’s ID token (an offline token, or an online one bound to the dashboard user), an install code, and a refresh token (rotated on every use; a spent one presented after 60 seconds revokes its whole family).
Client authentication is HTTP Basic only. Errors are OAuth’s { error, error_description }, not problem+json. Limits: 300 requests a minute per client id, 30 failed authentications a minute per IP (429 slow_down).
curl --request POST \
--url https://api.tassyir.io/apps/oauth/token \
--header 'Authorization: Basic <encoded-value>' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data grant_type=urn:ietf:params:oauth:grant-type:token-exchange \
--data 'subject_token=<string>' \
--data subject_token_type=urn:ietf:params:oauth:token-type:id_token \
--data requested_token_type=urn:tassyir:params:oauth:token-type:offline-access-token \
--data 'client_id=<string>'const options = {
method: 'POST',
headers: {
Authorization: 'Basic <encoded-value>',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
grant_type: 'urn:ietf:params:oauth:grant-type:token-exchange',
subject_token: '<string>',
subject_token_type: 'urn:ietf:params:oauth:token-type:id_token',
requested_token_type: 'urn:tassyir:params:oauth:token-type:offline-access-token',
client_id: '<string>'
})
};
fetch('https://api.tassyir.io/apps/oauth/token', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"access_token": "<string>",
"token_type": "Bearer",
"expires_in": 123,
"scope": "<string>",
"installation_id": "<string>",
"business_id": "<string>",
"refresh_token": "<string>",
"refresh_token_expires_in": 123,
"issued_token_type": "urn:tassyir:params:oauth:token-type:offline-access-token",
"user_id": "<string>"
}{
"error": "invalid_grant",
"error_description": "<string>"
}{
"error": "invalid_client",
"error_description": "<string>"
}{
"error": "invalid_request",
"error_description": "<string>"
}{
"error": "slow_down",
"error_description": "<string>"
}{
"statusCode": 123,
"message": "<string>",
"requestId": "<string>"
}{
"error": "temporarily_unavailable",
"error_description": "<string>"
}Authorizations
The app's client id (app_…) as the user name and a live client secret (tsy_cs_…) as the password.
Body
- Token exchange (embedded page)
- Install code (external app without an embedded page)
- Refresh
Form-encoded (application/x-www-form-urlencoded, parsed flat) or a flat JSON object; at most 8 KB. Every value is one string; a repeated parameter is refused. Unknown parameters and scope are ignored. Never send client_secret in the body (invalid_client).
"urn:ietf:params:oauth:grant-type:token-exchange"The 60-second ID token the dashboard handed the page. Single use.
1 - 4096"urn:ietf:params:oauth:token-type:id_token"urn:tassyir:params:oauth:token-type:offline-access-token, urn:tassyir:params:oauth:token-type:online-access-token Optional; must equal the client id of the Basic credentials.
1 - 4096Response
The tokens.
Send as Authorization: Bearer <access_token>.
^tsy_at_[0-9A-Za-z]{43}$"Bearer"Seconds the access token lives (3600).
The installation's granted scopes, space-separated.
Offline tokens only. Rotated on every use; the one used is spent.
^tsy_rt_[0-9A-Za-z]{43}$Seconds the refresh token lives (90 days).
Token exchanges only (RFC 8693).
urn:tassyir:params:oauth:token-type:offline-access-token, urn:tassyir:params:oauth:token-type:online-access-token Online tokens only: the user the token acts for.