Code copied successfuly

Silent Authentication API

Version: v1.0.0

Specification Release Notes Other versions

Silent Authentication API provides OAuth2-based authentication that verifies whether an authentication request originates from the same subscriber by resolving network session information.

Typical flow:

  1. Client initiates OAuth2 authorization with /oauth2/authorize using login_hint containing the MSISDN.
  2. The service extracts MSISDN, client IP/port and timestamp, then resolves network session data.
  3. Check if the provided MSISDN matches the one associated with the resolved network session.
  4. Client exchanges the code for access/ID tokens via /oauth2/token.
  5. The ID token contains a mobile_id claim when verification succeeds.

Base URLs

OAuth2

OAuth2 endpoints for silent authentication flow. Supports authorization code grant type with network-based subscriber verification.

OAuth2 authorization

Code samples

# You can also use wget
curl -X GET https://api.tyntec.com/silent-auth/v1/oauth2/authorize?response_type=code&client_id=client&state=xyz12345&scope=openid%20tt%3Aphone_verify&redirect_uri=https%3A%2F%2Fclient.example.com%2Fcallback&login_hint=301234567890

GET https://api.tyntec.com/silent-auth/v1/oauth2/authorize?response_type=code&client_id=client&state=xyz12345&scope=openid%20tt%3Aphone_verify&redirect_uri=https%3A%2F%2Fclient.example.com%2Fcallback&login_hint=301234567890 HTTP/1.1
Host: api.tyntec.com


fetch('https://api.tyntec.com/silent-auth/v1/oauth2/authorize?response_type=code&client_id=client&state=xyz12345&scope=openid%20tt%3Aphone_verify&redirect_uri=https%3A%2F%2Fclient.example.com%2Fcallback&login_hint=301234567890',
{
  method: 'GET'

})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

result = RestClient.get 'https://api.tyntec.com/silent-auth/v1/oauth2/authorize',
  params: {
  'response_type' => 'string',
'client_id' => 'string',
'state' => 'string',
'scope' => 'string',
'redirect_uri' => 'string(uri)',
'login_hint' => 'string'
}

p JSON.parse(result)

import requests

r = requests.get('https://api.tyntec.com/silent-auth/v1/oauth2/authorize', params={
  'response_type': 'code',  'client_id': 'client',  'state': 'xyz12345',  'scope': 'openid tt:phone_verify',  'redirect_uri': 'https://client.example.com/callback',  'login_hint': '301234567890'
)

print(r.json())

<?php

require 'vendor/autoload.php';

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://api.tyntec.com/silent-auth/v1/oauth2/authorize', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://api.tyntec.com/silent-auth/v1/oauth2/authorize?response_type=code&client_id=client&state=xyz12345&scope=openid%20tt%3Aphone_verify&redirect_uri=https%3A%2F%2Fclient.example.com%2Fcallback&login_hint=301234567890");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");

int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://api.tyntec.com/silent-auth/v1/oauth2/authorize", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /oauth2/authorize

Initiates the OAuth2 authorization code flow with silent authentication. The client provides the subscriber's MSISDN in the login_hint parameter. The service resolves the network session and verifies the MSISDN, then returns:

  • an authorization code and the user ID as a sub claim, if the MSISDN matches the one associated with the network session, or
  • an authorization code and anonymous sub claim, if the MSISDN does not match.

Parameters

Name In Type Required Description
response_type query string true OAuth2 response type (must be 'code')
client_id query string true Client identifier
state query string true Opaque value used by the client to maintain state between request and callback
scope query string true Space-delimited scope values (e.g., 'openid tt:phone_verify')
redirect_uri query string(uri) true Client callback URI where the authorization code will be sent
login_hint query string true Subscriber MSISDN (without leading plus, e.g., 301234567890)
Enumerated values
Parameter Value
response_type code

Responses

Status Meaning Description Schema
302 Found Redirects the user-agent to the client-provided callback URI with OAuth 2.0 parameters.

Success case: Returns authorization code and state in query parameters.

Error cases: Returns error, error_description, and state in query parameters. Query parameter values are URL-encoded (spaces may appear as "+" in application/x-www-form-urlencoded encoding).

Error parameter names follow OAuth 2.0 specification:

  • error: Error code (e.g., invalid_request, invalid_scope, no_data_session)
  • error_description: Human-readable error explanation
  • state: Opaque value from the authorization request|None|

Response Headers

Status Header Type Format Description
302 Location string uri Redirect URI with query parameters. For success: code and state.

For errors: error, error_description, and state. |

OAuth2 token

Code samples

# You can also use wget
curl -X POST https://api.tyntec.com/silent-auth/v1/oauth2/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'Accept: application/json'

POST https://api.tyntec.com/silent-auth/v1/oauth2/token HTTP/1.1
Host: api.tyntec.com
Content-Type: application/x-www-form-urlencoded
Accept: application/json

const inputBody = '{
  "grant_type": "authorization_code",
  "code": "kgoV1pFxi1EIlocesrMcia6AhNyw6...",
  "redirect_uri": "https://client.example.com/callback",
  "client_id": "client",
  "client_secret": "12345"
}';
const headers = {
  'Content-Type':'application/x-www-form-urlencoded',
  'Accept':'application/json'

};

fetch('https://api.tyntec.com/silent-auth/v1/oauth2/token',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/x-www-form-urlencoded',
  'Accept' => 'application/json'
}

result = RestClient.post 'https://api.tyntec.com/silent-auth/v1/oauth2/token',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/x-www-form-urlencoded',
  'Accept': 'application/json'
}

r = requests.post('https://api.tyntec.com/silent-auth/v1/oauth2/token', params={

}, headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/x-www-form-urlencoded',
    'Accept' => 'application/json',

    );

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','https://api.tyntec.com/silent-auth/v1/oauth2/token', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://api.tyntec.com/silent-auth/v1/oauth2/token");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
con.setRequestProperty("Accept", "application/json");

int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/x-www-form-urlencoded"},
        "Accept": []string{"application/json"},

    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://api.tyntec.com/silent-auth/v1/oauth2/token", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /oauth2/token

Exchange an authorization code for access token, ID token, and refresh token. The ID token includes a mobile_id claim when silent authentication verification succeeded.

Body parameter

grant_type: authorization_code
code: kgoV1pFxi1EIlocesrMcia6AhNyw6...
redirect_uri: https://client.example.com/callback
client_id: client
client_secret: "12345"

Parameters

Name In Type Required Description
body body object true none
» grant_type body string true OAuth2 grant type (must be 'authorization_code')
» code body string true Authorization code received from /oauth2/authorize
» redirect_uri body string(uri) true Redirect URI that was used in the authorization request
» client_id body string true Client identifier
» client_secret body string true Client secret
Enumerated values
Parameter Value
» grant_type authorization_code

Example responses

Successful token response

{
  "access_token": "eyJraWQiOiIyYzc5NDNmMy00YzIyLTQ5...",
  "refresh_token": "DawkDPIXqUDqyjHfzcifAsc8gvL1jBys...",
  "scope": "tt:mobile_id openid",
  "id_token": "eyJraWQiOiIyYzc5NDNmMy00YzIyLTQ5MzUtO...",
  "token_type": "Bearer",
  "expires_in": 86399
}

400 Response

{
  "status": 400,
  "code": "INVALID_ARGUMENT",
  "message": "Client specified an invalid argument, request body or query param."
}

Responses

Status Meaning Description Schema
200 OK Successful token response TokenResponse
400 Bad Request Bad Request - Invalid request parameters InvalidArgumentError
401 Unauthorized Unauthorized - Invalid client credentials or authorization code UnauthenticatedError
403 Forbidden Forbidden PermissionDeniedError
404 Not Found Not Found NotFoundError
500 Internal Server Error Internal Server Error InternalServerError

Schemas

TokenResponse

{
  "access_token": "eyJraWQiOiIyYzc5NDNmMy00YzIyLTQ5MzUtOTBmZi1kOWVkNTVmYTYxN2QiLCJhbGciOiJSUzI1NiJ9...",
  "refresh_token": "DawkDPIXqUDqyjHfzcifAsc8gvL1jBysWTe4vgXy1PbJGk51Ec6mRIZnCJh7nzRBG1MnE7C...",
  "scope": "tt:mobile_id openid",
  "id_token": "eyJraWQiOiIyYzc5NDNmMy00YzIyLTQ5MzUtOTBmZi1kOWVkNTVmYTYxN2QiLCJhbGciOiJSUzI1NiJ9...",
  "token_type": "Bearer",
  "expires_in": 86399
}

Properties

Name Type Required Restrictions Description
access_token string false none OAuth2 access token (JWT format)
refresh_token string false none OAuth2 refresh token
scope string false none Space-delimited scope values granted
id_token string false none OpenID Connect ID token (JWT format) containing mobile_id claim when verification succeeded
token_type string false none Token type (always 'Bearer')
expires_in integer false none Access token lifetime in seconds

InvalidArgumentError

{
  "status": 400,
  "code": "INVALID_ARGUMENT",
  "message": "Client specified an invalid argument, request body or query param."
}

Properties

Name Type Required Restrictions Description
status integer true none HTTP status code
code string true none Error code
message string true none Error message

OutOfRangeError

{
  "status": 400,
  "code": "OUT_OF_RANGE",
  "message": "Client specified an invalid range."
}

Properties

Name Type Required Restrictions Description
status integer true none HTTP status code
code string true none Error code
message string true none Error message

UnauthenticatedError

{
  "status": 401,
  "code": "UNAUTHENTICATED",
  "message": "Request not authenticated due to missing, invalid, or expired credentials. A new authentication is required."
}

Properties

Name Type Required Restrictions Description
status integer true none HTTP status code
code string true none Error code
message string true none Error message

PermissionDeniedError

{
  "status": 403,
  "code": "PERMISSION_DENIED",
  "message": "Client does not have sufficient permissions to perform this action."
}

Properties

Name Type Required Restrictions Description
status integer true none HTTP status code
code string true none Error code
message string true none Error message

NotFoundError

{
  "status": 404,
  "code": "NOT_FOUND",
  "message": "The specified resource is not found."
}

Properties

Name Type Required Restrictions Description
status integer true none HTTP status code
code string true none Error code
message string true none Error message

InternalServerError

{
  "status": 500,
  "code": "INTERNAL_SERVER_ERROR",
  "message": "Request could not be processed"
}

Properties

Name Type Required Restrictions Description
status integer true none HTTP status code
code string true none Error code
message string true none Error message