Authentication
Overview
The Voice ReGen Service API uses Microsoft Entra ID for authentication. To authenticate, the API client sends the following parameters to Microsoft Entra ID and receives an access token in response.
| Parameter | Description |
|---|---|
| Tenant ID | Identifies the Microsoft Entra ID tenant used for authentication. You can find this value in the API Keys tab. |
| Client ID | The client identifier for the API key/application credentials. You can find this value in the API key you created. |
| Client Secret | The API key secret shown when the API key was created. |
| Scope | The fixed default scope for Voice ReGen API access. You can find this value in the API Keys tab. |
The API client application must include the access token received from Microsoft Entra ID in every API call:
-H "Authorization: Bearer <access_token>"
Access Token Expiration and Renewal
The access_token is valid for 1 hour. We recommend implementing a token renewal mechanism.
Authentication - Getting the Access Token
Request a token from the Microsoft Entra ID authentication endpoint:
https://login.microsoftonline.com/<tenantId>/oauth2/v2.0/token
TENANT_ID="<tenantId>"
CLIENT_ID="<clientId>"
CLIENT_SECRET="<clientSecret>"
SCOPE="api://<application-id-uri>/.default"
curl -s -X POST "https://login.microsoftonline.com/$TENANT_ID/oauth2/v2.0/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "client_id=$CLIENT_ID" \
--data-urlencode "client_secret=$CLIENT_SECRET" \
--data-urlencode "grant_type=client_credentials" \
--data-urlencode "scope=$SCOPE"
Microsoft Entra ID token response example:
{
"access_token": "...",
"token_type": "Bearer",
"expires_in": 3599,
"ext_expires_in": 3599
}
Using the Token with Service API Endpoints
Once you have an access_token, call the Voice ReGen endpoint:
API_BASE_URL="<api-base-url>"
ACCESS_TOKEN="<access_token>"
curl -s -X POST "$API_BASE_URL/api/v1/getFilesStatus" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{ "fileIds": ["file-123"] }'
Token Renewal Example (Node.js + TypeScript)
With client_credentials, Microsoft Entra ID does not issue a refresh token.
The API client application needs to:
- Cache the access token used with each request.
- Fetch a new token before the current one expires.
Below is a sample implementation for token renewal:
Token manager (cache + auto-renewal)
type TokenResponse = {
access_token: string;
token_type: 'Bearer';
expires_in: number; // seconds
};
export class EntraAccessTokenProvider {
private token: string | null = null;
private expiresAtMs = 0;
private refreshInFlight: Promise<string> | null = null;
constructor(
private readonly opts: {
tenantId: string;
clientId: string;
clientSecret: string;
scope: string; // e.g. api://<application-id-uri>/.default
// refresh slightly early to avoid edge cases / clock skew
refreshSkewMs?: number;
},
) {}
async getAccessToken(): Promise<string> {
const skew = this.opts.refreshSkewMs ?? 60_000;
const now = Date.now();
if (this.token && now + skew < this.expiresAtMs) {
return this.token;
}
if (!this.refreshInFlight) {
this.refreshInFlight = this.fetchNewToken().finally(() => {
this.refreshInFlight = null;
});
}
return this.refreshInFlight;
}
private async fetchNewToken(): Promise<string> {
const tokenUrl = `https://login.microsoftonline.com/${this.opts.tenantId}/oauth2/v2.0/token`;
const body = new URLSearchParams({
client_id: this.opts.clientId,
client_secret: this.opts.clientSecret,
grant_type: 'client_credentials',
scope: this.opts.scope,
});
const res = await fetch(tokenUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body,
});
if (!res.ok) {
throw new Error(
`Token request failed: ${res.status} ${res.statusText} - ${await res.text()}`,
);
}
const json = (await res.json()) as TokenResponse;
this.token = json.access_token;
this.expiresAtMs = Date.now() + json.expires_in * 1000;
return this.token;
}
}
// Usage
const voiceRegenConfig = {
tenantId: '<tenantId>',
clientId: '<clientId>',
clientSecret: '<clientSecret>',
scope: 'api://<application-id-uri>/.default',
apiBaseUrl: '<api-base-url>',
};
const tokenProvider = new EntraAccessTokenProvider({
tenantId: voiceRegenConfig.tenantId,
clientId: voiceRegenConfig.clientId,
clientSecret: voiceRegenConfig.clientSecret,
scope: voiceRegenConfig.scope,
});
async function callVoiceRegen() {
const accessToken = await tokenProvider.getAccessToken();
const resp = await fetch(
`${voiceRegenConfig.apiBaseUrl}/api/v1/getFilesStatus`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${accessToken}`,
},
body: JSON.stringify({ fileIds: ['file-123'] }),
},
);
return resp.json();
}