Authentication Flow
This document describes the complete lifecycle of a Telsmart integration activation, from initial activation through ongoing usage and token refresh, to eventual deactivation.
1. Activation Flow
The activation flow is initiated from your system and establishes trust between Telsmart and your integration for a specific user.
1.1 Activation Flow — Step by Step
sequenceDiagram
participant User
participant Integrator as Your System
participant MyTelsmart as MyTelsmart (Portal)
participant Telsmart as Telsmart Backend
User->>Integrator: Click "Connect to Telsmart"
Integrator->>MyTelsmart: Redirect with confirmation_key & redirect_url
Note over MyTelsmart: User logs in (if needed)
Note over MyTelsmart: User grants consent (Subscribe)
MyTelsmart->>Telsmart: Initiate Activation
Telsmart->>Integrator: POST Activation URL (tenant_id, user_extension, tokens, confirmation_key)
Integrator-->>Telsmart: 200 OK
Telsmart-->>MyTelsmart: Activation Finalized
MyTelsmart->>Integrator: Redirect to redirect_url
Integrator-->>User: Show Integration Dashboard
-
User Initiates Integration
From your application, the user clicks a button such as “Connect to Telsmart”, which redirects them to the Telsmart integration page (Link to Redirect Page).
-
Telsmart Authentication
If the user is not logged in to MyTelsmart, they are prompted to log in. After successful login, MyTelsmart displays a consent page requesting permission to integrate with your system.
-
User Grants Consent
When the user clicks Subscribe, Telsmart proceeds with activation validation.
-
Telsmart Validates with Your System
Telsmart sends an HTTP POST request to your system’s Activation URL to confirm that the activation request is legitimate.
Request Body
Field Type Required Description tenant_idstringYes Telsmart customer identifier to which the user being integrated belongs. This field is required because the extension is unique only at the tenant level, so a tenant marker is needed to ensure proper distinction. (Example: b11d749b-8eb7-4236-a068-3d94ba3860d6)user_extensionstringYes Internal number of the user (Example: 200)confirmation_keystringYes Token generated by you and originally passed in the redirect link access_tokenstringYes Expiring token used to call Telsmart APIs on behalf of the user refresh_tokenstringYes Non-expiring, single-use token used to obtain new access tokens Optional:
- Additional request headers (security or validation headers)
-
Your System Validates the Request
Your system verifies:
- The
confirmation_key - The user context
- Any additional validation rules
If valid, your system:
- Marks the user as integrated.
- Persists the received tokens securely.
- Responds with HTTP 200 OK.
- The
-
Telsmart Finalizes Activation
Upon receiving 200 OK, Telsmart stores the integration as active for the user and the user is redirected back to your system using the provided
redirect_url
1.2 Terminology
| Term | Description |
|---|---|
| Link to Redirect Page | MyTelsmart page used to activate or deactivate the integration |
| Activation URL | Your endpoint that validates and confirms activation |
| Deactivation URL | Your endpoint that validates and confirms deactivation |
1.3 Link to Redirect Page
This is the link you place in your marketplace or UI to start activation or deactivation.
https://{MyTelSmartHostName}/integrations/{slug}/activate?confirmation_key={your-generated-token}&tenant_{param1}={value1}&tenant_{paramN}={valueN}&redirect_url={absolute-url-back-to-your-system}
Parameters
| Parameter | Description |
|---|---|
| MyTelsmartHostName | portal.phoneserver.dev (test) or portal.telsmart.eu (production) |
| slug | Slugified integration identifier |
| confirmation_key | Token generated by you to identify the user |
| redirect_url | Absolute URL for post-activation redirect |
| tenant_{paramN} | Optional customer-specific metadata (stored only on first activation). If paramN is "id" (tenant_id), it will be ignored since this is the tenant identifier always served upon authentication and has predefined format. |
1.4 Example Activation
Link to Redirect Page
https://portal.phoneserver.dev/integrations/test-slug/activate?confirmation_key=123xyz&tenant_name=dummy&tenant_identifier=12345&redirect_url=https://dummy-integrator.be/dashboard
Activation URL
https://dummy-integrator.be/api/v1/activate
Request Body Example
{
"tenant_id": "b11d749b-8eb7-4236-a068-3d94ba3860d6",
"user_extension": "200",
"confirmation_key": "123xyz",
"access_token": "GRxSJe8Re2R5PUC314YvOYA9HpLyBj",
"refresh_token": "Fhw99p3FduscpIfsOR3tJpL7DmO6ly"
}
Request Headers (optional)
{
"security_token_if_needed": "X10rTtfHeMQmScVX2…"
}
2. Deactivation Flow
The deactivation process mirrors the activation flow with the following differences:
-
When the user visits the Link to Redirect Page, they are presented with an Unsubscribe CTA.
-
After confirmation:
- Telsmart sends an HTTP POST request to your Deactivation URL.
- Request body and headers are the same as activation.
access_tokenandrefresh_tokenare empty.
-
Your system:
- Marks the integration as deactivated.
- Responds with HTTP 200 OK.
-
Telsmart finalizes deactivation and redirects the user back to your system using the provided
redirect_url.
3. OAuth Tokens
3.1 Lifecycle
Access tokens are valid for 24 hours and are used to authenticate Telsmart API requests. Refresh tokens do not expire automatically, are single-use only, and are invalidated immediately after being used to obtain new access and refresh token.
3.2 Refreshing the Access Token
When an access token expires, use the refresh token to obtain a new access token and a new refresh token.
POST /v3/oauth/token/
curl --include --request POST \
--header "Content-Type: application/x-www-form-urlencoded" \
-d '{"grant_type": "refresh_token", "refresh_token": "Y45cDJcYAUF6WIJvb3VU5bs9rYQYqz", "client_id": "your_client_id", "client_secret": "your_client_secret"}' \
https://api-eu-central-1.phoneserver.dev/v3/oauth/token/
import requests
import json
# Prepare headers
headers = {
"Content-Type": "application/x-www-form-urlencoded",
}
# Prepare data
myDict = {
"grant_type": "refresh_token",
"refresh_token": "Y45cDJcYAUF6WIJvb3VU5bs9rYQYqz",
"client_id": "your_client_id",
"client_secret": "your_client_secret"
}
# Send the request
response = requests.post('https://api-eu-central-1.phoneserver.dev/v3/oauth/token/', headers=headers, json=json.dumps(myDict))
<?php
// Create a new cURL resource
$ch = curl_init();
// Prepare headers
$headers = array();
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
// Set the header
curl_setopt($ch, CURL_HTTPHEADER, $headers);
// Indicate URL
curl_setopt($ch, CURLOPT_URL, 'https://api-eu-central-1.phoneserver.dev/v3/oauth/token/');
// Return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// Indicate the method
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
// Prepare data
$data = array(
"grant_type" => "refresh_token",
"refresh_token" => "Y45cDJcYAUF6WIJvb3VU5bs9rYQYqz",
"client_id" => "your_client_id",
"client_secret" => "your_client_secret",
};
$fields = json_encode($data);
// Set the body
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
// Send the request
$result = curl_exec($ch);
curl_close($ch);
using (var httpClient = new HttpClient())
{
// Prepare request
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api-eu-central-1.phoneserver.dev/v3/oauth/token/"))
{
// Prepare headers
request.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
// Prepare body
request.content = JsonContent.Create(new {
grant_type = "refresh_token"
refresh_token = "Y45cDJcYAUF6WIJvb3VU5bs9rYQYqz"
client_id = "your_client_id"
client_secret = "your_client_secret"
});
// Send response
var response = await httpClient.SendAsync(request);
}
}
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;
// Prepare body
String jsonString = "{\"grant_type\": \"refresh_token\", \"refresh_token\": \"Y45cDJcYAUF6WIJvb3VU5bs9rYQYqz\", \"client_id\": \"your_client_id\", \"client_secret\": \"your_client_secret\"}";
Client client = ClientBuilder.newClient();
Response response = client.target("https://api-eu-central-1.phoneserver.dev/v3/oauth/token/")
.request(MediaType.APPLICATION_JSON_TYPE)
.header("Content-Type", "application/x-www-form-urlencoded")
.post(Entity.json(jsonString));
const Http = new XMLHttpRequest();
Http.open("POST", "https://api-eu-central-1.phoneserver.dev/v3/oauth/token/");
// Prepare headers
Http.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// Prepare data
const json = {
"grant_type": "refresh_token",
"refresh_token": "Y45cDJcYAUF6WIJvb3VU5bs9rYQYqz",
"client_id": "your_client_id",
"client_secret": "your_client_secret"
}
// Send the request
Http.send(JSON.stringify(json));
// Handle the response
Http.onreadystatechange = (e) => {
console.log(Http.responseText)
}
Request Body Fields
| Field | Required | Description |
|---|---|---|
| grant_type | Yes | Must be refresh_token |
| refresh_token | Yes | Previously issued refresh token |
| client_id | Yes | Provided by Telsmart |
| client_secret | Yes | Provided by Telsmart |
Successful Response Example
{
"access_token": "WlWSS1alosZF50lr8OS65HaSdYVcHi",
"expires_in": 86400,
"token_type": "Bearer",
"refresh_token": "j0gDyZi9x9H183ifnY4jB0hhOIax9o"
}
- Store both tokens securely.
- Discard the old refresh token immediately.
Invalid Refresh Token Response
If a refresh token is reused or already invalidated:
{
"error": "invalid_grant"
}
4. Post-Activation Behavior
Once activated:
- The integration remains active until explicitly deactivated.
-
Your system uses the access token to call Telsmart APIs on behalf of the user.
-
Call events are being pushed to your system for activated user's integration if Webhook URL is provided. See Webhook Events for more details.