const TOKEN_ENDPOINT = "https://auth.pylon.mortgage/oauth/token";
let cachedToken = null;
let tokenExpiresAt = 0;
async function getAccessToken() {
// Reuse the cached token while it's still valid.
if (cachedToken && Date.now() < tokenExpiresAt) {
return cachedToken;
}
// Expired (or never fetched): request a brand-new token.
const response = await fetch(TOKEN_ENDPOINT, {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
grant_type: "client_credentials",
client_id: process.env.PYLON_CLIENT_ID,
client_secret: process.env.PYLON_CLIENT_SECRET,
}),
});
const data = await response.json();
cachedToken = data.access_token;
// Refresh slightly early to avoid edge-of-expiry failures.
tokenExpiresAt = Date.now() + (data.expires_in - 60) * 1000;
return cachedToken;
}
async function makeGraphQLRequest(query, variables) {
const token = await getAccessToken();
const response = await fetch("https://pylon.mortgage/graphql", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({ query, variables }),
});
return response.json();
}