Quick Start Guide
Follow these three steps to begin making authenticated requests to our services.
Step 1: Obtain Credentials
First, you must generate your API identity through the administration portal.
{your-slug} is your organization's unique identifier assigned to your account.
- Log in to the Admin Panel at
https://{your-slug}.admin-dev.alpha.looms.cloud - Navigate to Administration -> Api keys
- Click Create Api client and complete the form:
- Client ID — a unique name for this client.
- Description — optional; what this client is used for.
- Allow client credentials — enable this for machine-to-machine access (the Client Credentials flow in Step 2). Turning it on generates a
Client Secretand reveals the Permissions section. - Redirect URLs — required for the user-facing Password flow; add the URLs the auth server may redirect back to.
- Permissions — (shown only when Allow client credentials is on) select the actions this client may perform. A client-credentials token can only call endpoints covered by the permissions you grant here, so grant the minimum it needs.
- Click Save, then securely store your
Client IDandClient Secret.
Your Client Secret is sensitive information. Never share it in public repositories (like GitHub) or client-side code.
Permissions scope the Client Credentials flow only. If a machine-to-machine request returns 403 Forbidden, verify the required permission is selected on the client in the Admin Panel. The Password flow is instead restricted by the signed-in user's own permissions.
You can manage and revoke your clients from https://{your-slug}.admin-dev.alpha.looms.cloud/en/admin/open-api.
Step 2: Generate an Access Token
There are three ways to obtain a token depending on your use case.
Auth Base URL: https://kc-dev.alpha.looms.cloud
All authentication endpoints are relative to this base URL.
- Client Credentials
- Password
- Refresh Token
Machine-to-machine flow. Use this in backend services with your client_id and client_secret. The token expires after 5 minutes — your service should request a new one when it expires. No refresh token is issued.
This flow requires Allow client credentials to be enabled on the client (Step 1). The token's access is limited to the Permissions selected on that client.
POST /realms/admin-portal/protocol/openid-connect/token
curl --request POST \
--url {auth-base-url}/realms/admin-portal/protocol/openid-connect/token \
--header 'content-type: application/x-www-form-urlencoded' \
--data grant_type=client_credentials \
--data client_id={{client_id}} \
--data 'client_secret={{client_secret}}'
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
grant_type | string | Yes | Must be client_credentials |
client_id | string | Yes | Your Client ID |
client_secret | string | Yes | Your Client Secret |
Response
{
"access_token": "<jwt>",
"token_type": "Bearer",
"expires_in": 300,
"refresh_expires_in": 0,
"scope": "profile email"
}
| Field | Description |
|---|---|
access_token | JWT to use in the Authorization header |
token_type | Always Bearer |
expires_in | Token lifetime in seconds (300 = 5 minutes) |
refresh_expires_in | Always 0 — no refresh token is issued for this grant type |
scope | Granted scopes |
User-facing flow. Use this when authenticating on behalf of a specific user with their username and password.
POST /realms/admin-portal/protocol/openid-connect/token
curl --request POST \
--url {auth-base-url}/realms/admin-portal/protocol/openid-connect/token \
--header 'content-type: application/x-www-form-urlencoded' \
--data grant_type=password \
--data client_id={{client_id}} \
--data username={{username}} \
--data password={{password}}
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
grant_type | string | Yes | Must be password |
client_id | string | Yes | Your Client ID |
username | string | Yes | The user's email or username |
password | string | Yes | The user's password |
Response
{
"access_token": "<jwt>",
"refresh_token": "<jwt>",
"token_type": "Bearer",
"expires_in": 300,
"refresh_expires_in": 1800,
"scope": "profile email"
}
| Field | Description |
|---|---|
access_token | JWT to use in the Authorization header |
refresh_token | JWT used to obtain a new access token without re-authenticating |
token_type | Always Bearer |
expires_in | Access token lifetime in seconds |
refresh_expires_in | Refresh token lifetime in seconds |
scope | Granted scopes |
Use this to silently renew an expired access token using a refresh_token obtained from the Password flow.
POST /realms/admin-portal/protocol/openid-connect/refresh-token
curl --request POST \
--url {auth-base-url}/realms/admin-portal/protocol/openid-connect/refresh-token \
--header 'content-type: application/x-www-form-urlencoded' \
--data grant_type=refresh_token \
--data client_id={{client_id}} \
--data refresh_token={{refresh_token}}
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
grant_type | string | Yes | Must be refresh_token |
client_id | string | Yes | Your Client ID |
refresh_token | string | Yes | The refresh token from a previous token response |
Response
{
"access_token": "<jwt>",
"refresh_token": "<jwt>",
"token_type": "Bearer",
"expires_in": 300,
"refresh_expires_in": 1800,
"scope": "profile email"
}
| Field | Description |
|---|---|
access_token | New JWT to use in the Authorization header |
refresh_token | New refresh token — replace the previous one |
token_type | Always Bearer |
expires_in | Access token lifetime in seconds |
refresh_expires_in | Refresh token lifetime in seconds |
scope | Granted scopes |
Step 3: Use the Access Token
Include the access_token from Step 2 in the Authorization header of every request to our other service APIs.