Skip to content

Node.js / TypeScript

Reusable client for backend teams — instead of scattering token logic across services and jobs.

Handles token caching and avoids duplicate refresh requests when multiple calls hit at the same time.

Full example

import axios, { AxiosInstance } from "axios";

interface TokenResponse {
  access_token: string;
  expires_in: number;
  token_type: string;
}

export class EstiaApiClient {
  private readonly http: AxiosInstance;
  private token?: string;
  private tokenExpiresAt = 0;
  private tokenRequest?: Promise<string>;

  constructor(
    private readonly clientId: string,
    private readonly clientSecret: string,
    private readonly apiBaseUrl = "https://api.insurancegateway.gr",
    private readonly authUrl = "https://auth.insurancegateway.gr/realms/estia/protocol/openid-connect/token",
  ) {
    this.http = axios.create({ baseURL: this.apiBaseUrl });
  }

  private async getToken(): Promise<string> {
    if (this.token && Date.now() < this.tokenExpiresAt - 300_000) {
      return this.token;
    }

    if (this.tokenRequest) {
      return this.tokenRequest;
    }

    this.tokenRequest = (async () => {
      try {
        const params = new URLSearchParams({
          grant_type: "client_credentials",
          client_id: this.clientId,
          client_secret: this.clientSecret,
        });
        const { data } = await axios.post<TokenResponse>(this.authUrl, params);
        this.token = data.access_token;
        this.tokenExpiresAt = Date.now() + data.expires_in * 1000;
        return this.token;
      } finally {
        this.tokenRequest = undefined;
      }
    })();

    return this.tokenRequest;
  }

  async get<T>(path: string): Promise<T> {
    const token = await this.getToken();
    const { data } = await this.http.get<T>(path, {
      headers: { Authorization: `Bearer ${token}` },
    });
    return data;
  }

  async post<T>(path: string, body: unknown): Promise<T> {
    const token = await this.getToken();
    const { data } = await this.http.post<T>(path, body, {
      headers: { Authorization: `Bearer ${token}` },
    });
    return data;
  }
}

Example usage

const client = new EstiaApiClient(
  process.env.ESTIA_CLIENT_ID!,
  process.env.ESTIA_CLIENT_SECRET!,
);

const brands = await client.get<Brand[]>("/intersalonica/auto/brands");

Plain JavaScript version

If you're not on TypeScript yet, same flow:

async function getToken() {
  const res = await fetch(
    "https://auth.insurancegateway.gr/realms/estia/protocol/openid-connect/token",
    {
      method: "POST",
      headers: { "Content-Type": "application/x-www-form-urlencoded" },
      body: new URLSearchParams({
        grant_type: "client_credentials",
        client_id: process.env.ESTIA_CLIENT_ID,
        client_secret: process.env.ESTIA_CLIENT_SECRET,
      }),
    },
  );
  const { access_token } = await res.json();
  return access_token;
}

const token = await getToken();
const res = await fetch("https://api.insurancegateway.gr/intersalonica/auto/brands", {
  headers: { Authorization: `Bearer ${token}` },
});
const brands = await res.json();