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