S2S API
Melody Auth S2S API provides capabilities for server applications to manage resources.
Get Started
To get started, obtain an access_token from the /token endpoint by using your clientId and clientSecret as the Basic Auth header. Use this access_token as a Bearer token in the Authorization header for subsequent requests.
- HTTP Method:
POST - Content Type:
application/x-www-form-urlencoded - URL:
[melody_auth_server_url]/oauth2/v1/token
Token Request Parameters
| Property | Type | Required | Description |
|---|---|---|---|
grant_type | 'client_credentials' | true | Indicates the use of client credentials to exchange for a token |
scope | string | true | Scopes requested (e.g., 'read_user write_user') |
Token Request example
const credentials = `${clientId}:${clientSecret}`;
const encodedCredentials = Buffer.from(credentials).toString('base64');
const data = {
grant_type: 'client_credentials',
scope: 'read_user write_user',
}
const urlEncodedData = new URLSearchParams(data).toString()
fetch('/oauth2/v1/token', {
method: 'POST',
headers: {
'Content-type': 'application/x-www-form-urlencoded',
'Authorization': `basic ${encodedCredentials}`
},
body: urlEncodedData,
})
Token Response example
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMzQ1NiIsInNjb3BlIjoicmVhZF91c2VyIHdyaXRlX3VzZXIiLCJpYXQiOjE3MjE0MjE4MTcsImV4cCI6MTcyMTQyNTQxN30.blhriLgm67tkL89tVLdeNN5nl4EUssy6FIfp4kTOlqM",
"expires_in":3600,
"expires_on":1721425417,
"token_type":"Bearer",
"scope":"read_user write_user"
}
System Info
The /info endpoint returns active server configuration values, including feature flags and client-facing settings. Because these values can reveal security posture and deployment details, this endpoint requires a valid server-to-server access token, but it does not require any specific scope.
- HTTP Method:
GET - URL:
[melody_auth_server_url]/info - Required scope: none
- Authorization:
Bearer [access_token]
Scopes
The scopes granted to a server-to-server token determine which endpoints it can call. Each endpoint's required scope is listed in the Rest API Swagger. The root scope grants access to every endpoint.
Assigning the root scope
When creating an app (POST /api/v1/apps) or updating one (PUT /api/v1/apps/{id}), the root scope can only be assigned by a caller whose own token holds the root scope. A write_app token that lacks root can still manage other scopes, but any request that includes root in the app's scope list is rejected with 400 and the message Only an app with the root scope can assign the root scope to an app. This prevents a write_app token from escalating its own privileges to root.
Roles
Roles are assigned to users and can be managed when updating a user (PUT /api/v1/users/{authId}) or inviting one (POST /api/v1/users/invitations). Both require the write_user scope.
Assigning privileged roles
A privileged role grants elevated, cross-app trust — for example, super_admin is the role that gates user impersonation. To prevent a write_user token from escalating privileges (its own or another user's), a privileged role can only be assigned by a caller whose own token holds the root scope. A write_user token that lacks root can still assign non-privileged roles, but any request that includes a privileged role (e.g. super_admin) is rejected with 400 and the message Only an app with the root scope can assign a privileged role.
Detailed Documentation
For more detailed information, please see Rest API Swagger.