API authentication
The API uses OAuth2 client credentials flow for server-to-server calls, and the Azure AD auth code flow for user-context calls.
Client credentials (server-to-server)
async function getClientToken(): Promise<string> {
const params = new URLSearchParams({
grant_type: 'client_credentials',
client_id: process.env.AZURE_CLIENT_ID!,
client_secret: process.env.AZURE_CLIENT_SECRET!,
scope: 'https://api.charliemac.com/.default',
});
const response = await fetch(
`https://login.microsoftonline.com/${process.env.AZURE_TENANT_ID}/oauth2/v2.0/token`,
{ method: 'POST', body: params }
);
const { access_token } = await response.json();
return access_token;
}
Making authenticated requests
const token = await getClientToken();
const response = await fetch('https://api.charliemac.com/v1/documents', {
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
});
Token caching
Tokens are valid for 3600 seconds. Cache them and refresh before expiry:
let cachedToken: { value: string; expiresAt: number } | null = null;
async function getCachedToken(): Promise<string> {
if (cachedToken && Date.now() < cachedToken.expiresAt - 60_000) {
return cachedToken.value;
}
const value = await getClientToken();
cachedToken = { value, expiresAt: Date.now() + 3_600_000 };
return value;
}