Avnology ID
SDKsTypeScript SDK

Configuration

Advanced configuration options for the TypeScript SDK including retry policies, interceptors, and custom transports.

Configuration

The AvnologyId client can be customized extensively for different deployment scenarios -- server-side services, browser SPAs, edge functions, and test environments.

Basic configuration

import { AvnologyId } from "@avnology/sdk-typescript";

const client = new AvnologyId({
  baseUrl: "https://api.id.avnology.com",
  clientId: "app_abc123",
  timeout: 15000,
  retries: 2,
});

Retry policy

The SDK retries requests on transient failures (network errors, 429 rate limits, 502/503/504 server errors). Each retry uses exponential backoff with jitter.

const client = new AvnologyId({
  baseUrl: "https://api.id.avnology.com",
  clientId: "app_abc123",

  // Retry configuration
  retries: 5,                // Max retry attempts (default: 3)
  retryDelay: 500,           // Initial delay in ms (default: 1000)
  retryMaxDelay: 30000,      // Maximum delay cap in ms (default: 30000)
  retryStatusCodes: [429, 502, 503, 504], // HTTP codes to retry (default)
});

Retry behavior by error type

ErrorRetriedNotes
Network timeoutyesRetried up to retries times
Connection refusedyesRetried with exponential backoff
HTTP 429 (Rate Limit)yesWaits for Retry-After header duration
HTTP 502/503/504yesServer errors, retried with backoff
HTTP 400 (Bad Request)noClient error, not retried
HTTP 401 (Unauthorized)noToken may be refreshed, then retried once
HTTP 403 (Forbidden)noPermission denied, not retried
HTTP 404 (Not Found)noResource missing, not retried
HTTP 409 (Conflict)noConflict, not retried
HTTP 422 (Validation)noValidation error, not retried

Token management

Automatic token refresh

When autoRefresh is enabled (the default), the SDK automatically refreshes expired access tokens using the refresh token before making API calls.

const client = new AvnologyId({
  baseUrl: "https://api.id.avnology.com",
  clientId: "app_abc123",
  autoRefresh: true,  // default

  // Called each time tokens are refreshed
  onTokenRefresh: (tokens) => {
    console.log("New access token:", tokens.accessToken);
    console.log("New refresh token:", tokens.refreshToken);
    // Persist tokens to storage
    localStorage.setItem("tokens", JSON.stringify(tokens));
  },
});

Manual token management

For full control over token lifecycle, disable auto-refresh and manage tokens yourself.

const client = new AvnologyId({
  baseUrl: "https://api.id.avnology.com",
  clientId: "app_abc123",
  autoRefresh: false,
});

// Set tokens explicitly
client.setTokens({
  accessToken: "eyJ...",
  refreshToken: "rt_...",
  expiresAt: new Date("2026-04-09T12:00:00Z"),
});

// Manually refresh when needed
const newTokens = await client.oauth.refreshToken({
  refreshToken: "rt_...",
});
client.setTokens(newTokens);

For browser applications using HTTP-only session cookies (no explicit tokens), configure the client to include credentials.

const client = new AvnologyId({
  baseUrl: "https://api.id.avnology.com",
  clientId: "app_abc123",
  credentials: "include",  // Send cookies with every request
  autoRefresh: false,       // Cookies are managed by the browser
});

Custom fetch

Override the global fetch to add logging, custom headers, or use a different HTTP client.

import { AvnologyId } from "@avnology/sdk-typescript";

const client = new AvnologyId({
  baseUrl: "https://api.id.avnology.com",
  clientId: "app_abc123",

  fetch: async (input, init) => {
    console.log(`[Avnology] ${init?.method ?? "GET"} ${input}`);
    const start = performance.now();
    const response = await globalThis.fetch(input, init);
    const duration = performance.now() - start;
    console.log(`[Avnology] ${response.status} in ${duration.toFixed(0)}ms`);
    return response;
  },
});

Request interceptors

Add headers or transform requests before they are sent.

const client = new AvnologyId({
  baseUrl: "https://api.id.avnology.com",
  clientId: "app_abc123",

  headers: {
    "X-Request-Source": "my-app",
    "X-Correlation-Id": () => crypto.randomUUID(), // Dynamic header
  },

  // Transform every request
  onRequest: (request) => {
    request.headers.set("X-Trace-Id", getTraceId());
    return request;
  },

  // Transform every response
  onResponse: (response) => {
    const rateLimit = response.headers.get("RateLimit-Remaining");
    if (rateLimit && parseInt(rateLimit) < 10) {
      console.warn("Approaching rate limit:", rateLimit, "remaining");
    }
    return response;
  },
});

Error handling

Global error handler

Register a global error handler for logging or telemetry.

const client = new AvnologyId({
  baseUrl: "https://api.id.avnology.com",
  clientId: "app_abc123",

  onError: (error) => {
    // Send to error tracking service
    Sentry.captureException(error, {
      tags: {
        errorCode: error.code,
        statusCode: error.statusCode,
      },
    });
  },
});

Per-request abort

Cancel individual requests using AbortController.

const controller = new AbortController();

// Cancel after 5 seconds
setTimeout(() => controller.abort(), 5000);

try {
  const users = await client.admin.listUsers({
    pageSize: 100,
    signal: controller.signal,
  });
} catch (error) {
  if (error.name === "AbortError") {
    console.log("Request was cancelled");
  }
}

Environment-specific configuration

Server-side (Node.js / Bun / Deno)

const client = new AvnologyId({
  baseUrl: process.env.AVNOLOGY_BASE_URL!,
  clientId: process.env.AVNOLOGY_CLIENT_ID!,
  clientSecret: process.env.AVNOLOGY_CLIENT_SECRET!,
  timeout: 10000,
  retries: 3,
});

Browser SPA

const client = new AvnologyId({
  baseUrl: "https://api.id.avnology.com",
  clientId: "app_abc123",
  credentials: "include",
  timeout: 30000,
  autoRefresh: true,
  onTokenRefresh: (tokens) => {
    sessionStorage.setItem("avnology_tokens", JSON.stringify(tokens));
  },
});

Edge function (Cloudflare Workers)

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const client = new AvnologyId({
      baseUrl: env.AVNOLOGY_BASE_URL,
      apiKey: env.AVNOLOGY_API_KEY,
      timeout: 5000,  // Edge functions have strict time limits
      retries: 1,
    });

    const session = await client.getSession();
    return new Response(JSON.stringify(session));
  },
};

Testing

import { AvnologyId, createMockClient } from "@avnology/sdk-typescript/testing";

const mockClient = createMockClient({
  baseUrl: "http://localhost:4455",
  // All methods return mock data by default
  // Override specific methods:
  overrides: {
    login: async () => ({
      id: "session_test",
      identity: { id: "user_test", email: "[email protected]" },
      expiresAt: new Date("2099-01-01").toISOString(),
    }),
  },
});

See also

On this page