Skip to content
On this page

Authentication ​

Streamline APIs use OAuth 2.0 Client Credentials grant for authentication.

WARNING

All requests must use HTTPS. HTTP requests and unauthenticated requests will fail.

Quick Start ​

Every API request requires an access token:

CredentialHeaderDescription
Access TokenAuthorization: Bearer <token>OAuth 2.0 token for authentication

Getting Your Credentials ​

After completing the onboarding process, you'll receive:

CredentialDescription
Client IDYour application's unique identifier
Client SecretSecret key for token generation

Protect Your Credentials

  • Store credentials securely (use environment variables or a secrets manager)
  • Never commit credentials to version control
  • Never expose credentials in client-side code
  • The client_secret cannot be recovered if lost

Get an Access Token ​

Request a token from the authorization server.

Make a POST request to the token endpoint with your client credentials:

Token Endpoint: https://auth-api.streamline.laboremus.ug/realms/streamline-realm/protocol/openid-connect/token

bash
curl --request POST \
  --url https://auth-api-demo.streamline.laboremus.ug/realms/streamline-test-realm/protocol/openid-connect/token \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data 'client_id=YOUR_CLIENT_ID' \
  --data 'client_secret=YOUR_CLIENT_SECRET' \
  --data 'grant_type=client_credentials'
curl --request POST \
  --url https://auth-api-demo.streamline.laboremus.ug/realms/streamline-test-realm/protocol/openid-connect/token \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data 'client_id=YOUR_CLIENT_ID' \
  --data 'client_secret=YOUR_CLIENT_SECRET' \
  --data 'grant_type=client_credentials'
js
const response = await fetch(
  'https://auth-api-demo.streamline.laboremus.ug/realms/streamline-test-realm/protocol/openid-connect/token',
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: new URLSearchParams({
      client_id: 'YOUR_CLIENT_ID',
      client_secret: 'YOUR_CLIENT_SECRET',
      grant_type: 'client_credentials',
    }),
  }
)

const { access_token } = await response.json()
const response = await fetch(
  'https://auth-api-demo.streamline.laboremus.ug/realms/streamline-test-realm/protocol/openid-connect/token',
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: new URLSearchParams({
      client_id: 'YOUR_CLIENT_ID',
      client_secret: 'YOUR_CLIENT_SECRET',
      grant_type: 'client_credentials',
    }),
  }
)

const { access_token } = await response.json()
python
import requests

response = requests.post(
    'https://auth-api-demo.streamline.laboremus.ug/realms/streamline-test-realm/protocol/openid-connect/token',
    data={
        'client_id': 'YOUR_CLIENT_ID',
        'client_secret': 'YOUR_CLIENT_SECRET',
        'grant_type': 'client_credentials',
    }
)

access_token = response.json()['access_token']
import requests

response = requests.post(
    'https://auth-api-demo.streamline.laboremus.ug/realms/streamline-test-realm/protocol/openid-connect/token',
    data={
        'client_id': 'YOUR_CLIENT_ID',
        'client_secret': 'YOUR_CLIENT_SECRET',
        'grant_type': 'client_credentials',
    }
)

access_token = response.json()['access_token']
csharp
var client = new HttpClient();
var content = new FormUrlEncodedContent(new[]
{
    new KeyValuePair<string, string>("client_id", "YOUR_CLIENT_ID"),
    new KeyValuePair<string, string>("client_secret", "YOUR_CLIENT_SECRET"),
    new KeyValuePair<string, string>("grant_type", "client_credentials")
});

var response = await client.PostAsync(
    "https://auth-api-demo.streamline.laboremus.ug/realms/streamline-test-realm/protocol/openid-connect/token",
    content
);

var json = await response.Content.ReadFromJsonAsync<JsonObject>();
var accessToken = json["access_token"].ToString();
var client = new HttpClient();
var content = new FormUrlEncodedContent(new[]
{
    new KeyValuePair<string, string>("client_id", "YOUR_CLIENT_ID"),
    new KeyValuePair<string, string>("client_secret", "YOUR_CLIENT_SECRET"),
    new KeyValuePair<string, string>("grant_type", "client_credentials")
});

var response = await client.PostAsync(
    "https://auth-api-demo.streamline.laboremus.ug/realms/streamline-test-realm/protocol/openid-connect/token",
    content
);

var json = await response.Content.ReadFromJsonAsync<JsonObject>();
var accessToken = json["access_token"].ToString();

Token Response ​

json
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 300
}
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 300
}
FieldDescription
access_tokenThe Bearer token to use in API requests
token_typeAlways Bearer
expires_inToken lifetime in seconds

Token Expiration

Tokens expire after the time specified in expires_in. Request a new token before the current one expires.

Error Response ​

json
{
  "error": "invalid_client",
  "error_description": "Invalid client credentials"
}
{
  "error": "invalid_client",
  "error_description": "Invalid client credentials"
}

Using the Access Token ​

Include the token in the Authorization header in every request:

bash
curl --request GET \
  --url 'https://api.streamline.laboremus.ug/your-endpoint' \
  --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIs...'
curl --request GET \
  --url 'https://api.streamline.laboremus.ug/your-endpoint' \
  --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIs...'
js
const response = await fetch('https://api.streamline.laboremus.ug/your-endpoint', {
  headers: {
    'Authorization': `Bearer ${accessToken}`
  }
})
const response = await fetch('https://api.streamline.laboremus.ug/your-endpoint', {
  headers: {
    'Authorization': `Bearer ${accessToken}`
  }
})
python
response = requests.get(
    'https://api.streamline.laboremus.ug/your-endpoint',
    headers={
        'Authorization': f'Bearer {access_token}'
    }
)
response = requests.get(
    'https://api.streamline.laboremus.ug/your-endpoint',
    headers={
        'Authorization': f'Bearer {access_token}'
    }
)
csharp
client.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", accessToken);

var response = await client.GetAsync("https://api.streamline.laboremus.ug/your-endpoint");
client.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", accessToken);

var response = await client.GetAsync("https://api.streamline.laboremus.ug/your-endpoint");

Subscription Key ​

INFO

Always add your Subscription key to the request.

Include your subscription key in every request using one of these methods:

MethodHeader/Parameter
Header (recommended)Ocp-Apim-Subscription-Key: <your_key>
Query parameter?subscription-key=<your_key>
bash
curl --request POST \
  --url 'https://api.example.com/endpoint' \
  --header 'Authorization: Bearer <access_token>' \
  --header 'Ocp-Apim-Subscription-Key: <your_subscription_key>' \
  --header 'Content-Type: application/json' \
  --data '{"key": "value"}'
curl --request POST \
  --url 'https://api.example.com/endpoint' \
  --header 'Authorization: Bearer <access_token>' \
  --header 'Ocp-Apim-Subscription-Key: <your_subscription_key>' \
  --header 'Content-Type: application/json' \
  --data '{"key": "value"}'
js
const response = await fetch(API_ENDPOINT, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${accessToken}`,
    'Ocp-Apim-Subscription-Key': '<your_subscription_key>',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(data)
})
const response = await fetch(API_ENDPOINT, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${accessToken}`,
    'Ocp-Apim-Subscription-Key': '<your_subscription_key>',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(data)
})
python
import requests

response = requests.post(
    API_ENDPOINT,
    headers={
        'Authorization': f'Bearer {access_token}',
        'Ocp-Apim-Subscription-Key': '<your_subscription_key>',
        'Content-Type': 'application/json'
    },
    json=data
)
import requests

response = requests.post(
    API_ENDPOINT,
    headers={
        'Authorization': f'Bearer {access_token}',
        'Ocp-Apim-Subscription-Key': '<your_subscription_key>',
        'Content-Type': 'application/json'
    },
    json=data
)
csharp
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", accessToken);
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "<your_subscription_key>");

var content = new StringContent(
    JsonSerializer.Serialize(data),
    Encoding.UTF8,
    "application/json"
);

var response = await client.PostAsync(API_ENDPOINT, content);
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", accessToken);
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "<your_subscription_key>");

var content = new StringContent(
    JsonSerializer.Serialize(data),
    Encoding.UTF8,
    "application/json"
);

var response = await client.PostAsync(API_ENDPOINT, content);
java
HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create(API_ENDPOINT))
    .header("Authorization", "Bearer " + accessToken)
    .header("Ocp-Apim-Subscription-Key", "<your_subscription_key>")
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create(API_ENDPOINT))
    .header("Authorization", "Bearer " + accessToken)
    .header("Ocp-Apim-Subscription-Key", "<your_subscription_key>")
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

Authorization Methods ​

There are two ways to be authorized when making this request.

js
const token = 'eyJhbGciOiJIUzI1NiIsInR5.eyJzd...ssw5c'
axios.get(API_ENDPOINT, 
  headers: {
    Authorization: `Bearer ${token}`
  }
)
const token = 'eyJhbGciOiJIUzI1NiIsInR5.eyJzd...ssw5c'
axios.get(API_ENDPOINT, 
  headers: {
    Authorization: `Bearer ${token}`
  }
)
js
import axios from 'axios'
    import oauth from 'axios-oauth-client'
    
    const getClientCredentials = oauth.clientCredentials(
    axios.create(),
    'https://oauth.com/2.0/token',
    'CLIENT_ID',
    'CLIENT_SECRET'
    )

    const auth = await getClientCredentials('OPTIONAL_SCOPES')
    // => { "access_token": "...", "expires_in": 900, ... }

    axios.get(API_ENDPOINT, 
      headers: {
        Authorization: `Bearer ${auth.access_token}`
      }
    )
import axios from 'axios'
    import oauth from 'axios-oauth-client'
    
    const getClientCredentials = oauth.clientCredentials(
    axios.create(),
    'https://oauth.com/2.0/token',
    'CLIENT_ID',
    'CLIENT_SECRET'
    )

    const auth = await getClientCredentials('OPTIONAL_SCOPES')
    // => { "access_token": "...", "expires_in": 900, ... }

    axios.get(API_ENDPOINT, 
      headers: {
        Authorization: `Bearer ${auth.access_token}`
      }
    )

Query Parameters ​

Certain query parameters must be included in your API requests for versioning.

NameTypeRequiredDescription
vstringyesThe version of the API

Tech Served Right