Skip to main content
All three SDKs take the same configuration object with the same option names. Only the idiomatic types and casing differ per language - the meaning and defaults are identical.
import { initialize } from "@expys/sdk";

const token = process.env.EXPYS_MEMBER_TOKEN;
if (!token) {
  throw new Error(
    "Set EXPYS_MEMBER_TOKEN (a member token from your backend's /v1/auth/exchange)",
  );
}

// A custom fetch wrapper: log each request, then delegate to the platform fetch.
// Use this seam for tracing, metrics, or a polyfill on Node < 18. The cast keeps
// it simple here under bun-types (whose `fetch` carries extra members); in a
// typical web/Node project the arrow satisfies `typeof fetch` without a cast.
const instrumentedFetch = ((input, init) => {
  const method = init?.method ?? "GET";
  const url =
    typeof input === "string"
      ? input
      : input instanceof URL
        ? input.href
        : input.url;
  console.log(`-> ${method} ${url}`);
  return fetch(input, init);
}) as typeof fetch;

const expys = initialize({
  baseUrl: process.env.EXPYS_BASE_URL,
  environment: "sandbox",
  fetch: instrumentedFetch,
  // Retry 429/5xx up to 3 extra times (4 attempts total) with backoff.
  maxRetries: 3,
  // Abort any single attempt that exceeds 8s.
  timeoutMs: 8_000,
  token,
});

async function main(): Promise<void> {
  const { data } = await expys.listOffers({ limit: 3 });
  console.log(`fetched ${data.length} offers with the configured client`);
}

Options

OptionDefaultDescription
token (required)-The short-lived member token. For server-mode clients, this is the Org-API-Key.
environmentliveDeclarative label for the credential’s environment; the other value is sandbox. See Environments.
baseUrlcanonical hostOverride the API host.
orgId-Optional. Included in the User-Agent for support attribution.
tokenExpiresAt / tokenExpiresAtMs-Optional. Token expiry; enables proactive refresh. See Authentication.
refreshToken-Optional hook returning a fresh token and expiry. Called proactively within refreshSkew, and reactively once on a 401.
maxRetries2Retry attempts on 429/5xx. See Retries and idempotency.
timeout / timeoutMsnonePer-request timeout.
refreshSkew / refreshSkewMs30sRefresh proactively when the token is within this window of expiry.
userAgentSuffix-Optional. Appended to the User-Agent.
Names are shared across SDKs; the duplicated rows (for example timeout / timeoutMs) show the idiomatic spelling per language. Pass whichever your SDK exposes - they configure the same behavior.

User-Agent

Every request carries a User-Agent the server uses for attribution and support. Its format is:
expys-sdk-{lang}/{sdkVersion} (spec/{specVersion}; env=<env>[; org=<org>])[ <suffix>]
  • {lang} is ts, swift, or kotlin.
  • {sdkVersion} and {specVersion} are embedded generated constants - see Versioning.
  • env is your configured environment; org is appended when orgId is set.
  • The optional trailing <suffix> is your userAgentSuffix.
For example: expys-sdk-ts/1.2.0 (spec/1.0.0; env=live; org=org_123) my-app/1.0.

Authentication

Tokens, expiry, and the refresh hook.

Environments

Sandbox vs live, selected by your credential.

Retries

Backoff and idempotency behavior.