Appearance
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:
| Credential | Header | Description |
|---|---|---|
| Access Token | Authorization: Bearer <token> | OAuth 2.0 token for authentication |
Getting Your Credentials
After completing the onboarding process, you'll receive:
| Credential | Description |
|---|---|
| Client ID | Your application's unique identifier |
| Client Secret | Secret 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_secretcannot 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
}| Field | Description |
|---|---|
access_token | The Bearer token to use in API requests |
token_type | Always Bearer |
expires_in | Token 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:
| Method | Header/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.
| Name | Type | Required | Description |
|---|---|---|---|
v | string | yes | The version of the API |