Developers

API client

createApiClient(options) is the SDK's single entry point. It wires together the two underlying HttpClient instances (one authenticated, one not), instantiates the four namespaced endpoint clients (gateway, uda, balance, onramp), and returns an ApiClient object you can pass around your service.

import { createApiClient } from "@stridge/sdk"

const stridge = createApiClient({
  projectKey: process.env.STRIDGE_PROJECT_KEY!,
  env: "prod",
})

The same builder is used by the Kit under the hood, and the two layers are interchangeable at this seam — you can pass a Kit-built client straight into a custom hook, or instantiate the SDK manually inside a Node worker the Kit will never touch.

createApiClient options

OptionTypeDefaultNotes
projectKeystring | nullundefinedSent on every authenticated request as X-Gateway-Key. Safe to omit when you only call public endpoints.
env"prod" | "dev""prod"Picks the managed base URL. Ignored when baseUrl is set.
baseUrlstringderived from envOverride the resolved base URL — use for self-hosted gateways, regional proxies, or local mocks.
defaultHeadersRecord<string, string>{}Headers merged into every outgoing request from both underlying HTTP clients.

All four are optional. Passing {} returns a client that talks to api.stridge.com/v1 with no auth header and no extra defaults — perfectly valid for hitting only the unauthenticated uda.* endpoints.

projectKey

The Stridge project key from the Dashboard. When set, the SDK's authenticated HttpClient sends it as the X-Gateway-Key header on every request through gateway.* and balance.*. When omitted or null, the authenticated client still exists — it just sends no auth header, and the gateway rejects the call with a BackendError.

The key is the same identifier the Gateway Kit ships as gatewayKey and the HTTP API expects as X-Gateway-Key. See Installation for where to mint it and how to store it.

env

Picks the managed base URL.

envResolves to
"prod"https://api.stridge.com/v1
"dev"https://api.stridge.dev/v1

Both URLs are also exported as the constants API_HTTP_PROD and API_HTTP_DEV for direct reference. Pass env unset to default to "prod"; passing anything other than "prod" or "dev" throws synchronously inside createApiClient.

baseUrl

Overrides env entirely. The supplied URL must be absolute (http://… or https://…); trailing slashes are tolerated. Relative request paths (/gateway/start) resolve against the base; if you ever pass an absolute path to a low-level httpClient.request, the base is bypassed.

defaultHeaders

Headers merged into every outgoing request, from both the authenticated and unauthenticated clients. Useful for tracing (X-Request-Id), tenant tagging (X-Tenant-Id), or any custom telemetry the gateway-fronting infrastructure expects.

Warning

The SDK strips reserved header names from defaultHeaders to prevent silent auth confusion. Today the only reserved name is x-gateway-key (case-insensitive) — supply the project key via projectKey instead. Per-request overrides on the low-level HttpClient.request(path, { headers }) still win, but client-level defaults can't shadow the auth header.

The returned ApiClient

createApiClient returns a plain object with four namespaced endpoint clients and three escape hatches.

interface ApiClient {
  /** Public, unauthenticated endpoints. No X-Gateway-Key. */
  httpClient: HttpClient

  /** Project-scoped, authenticated endpoints. Sends X-Gateway-Key. */
  projectHttpClient: HttpClient

  /** Resolved base URL — reflects baseUrl or env. */
  baseUrl: string

  /** Public catalogue + quotes. Backed by httpClient. */
  uda: Uda.Client

  /** Authenticated UDA lifecycle + pricing. Backed by projectHttpClient. */
  gateway: Gateway.Client

  /** Authenticated wallet-balance reads. Backed by projectHttpClient. */
  balance: Balance.Client

  /** Authenticated buy-crypto-with-fiat (onramp). Backed by projectHttpClient. */
  onramp: Onramp.Client
}

Namespaced endpoint clients

These are the bread-and-butter — every documented gateway feature surfaces through one of them. Each client maps 1:1 onto the Gateway HTTP API and returns typed models.

ClientAuthMethodsPage
stridge.gatewayprojectKey requiredstart, poll, assets, rateBySymbol, rateByErc20Gateway endpoints
stridge.onrampprojectKey requiredcatalog, fiats, crypto, countries, paymentMethods, quote, createSession, getSession, listOwnerSessionsOnramp endpoints
stridge.udanonesupportedAssets, quoteUDA endpoints
stridge.balanceprojectKey requiredonchainBalance endpoint

The two HTTP clients

httpClient and projectHttpClient are exposed for callers that need to issue an arbitrary request the SDK doesn't ship a typed helper for — a one-off /v1/internal/... route, a forward-compat endpoint, or a custom diagnostic probe.

Both are instances of the same HttpClient class, configured against the same baseUrl and defaultHeaders. The difference is auth:

  • httpClient sends no X-Gateway-Key. Use for public endpoints.
  • projectHttpClient sends the configured projectKey as X-Gateway-Key on every request. Use for project-scoped endpoints.
// Hit an undocumented public endpoint
const raw = await stridge.httpClient.get<MyDto>("/uda/diagnostics")

// Hit an undocumented project-scoped endpoint
const traced = await stridge.projectHttpClient.post<TraceResponse>("/gateway/trace", {
  request_id: "req_42",
})

HttpClient supports get, post, put, patch, and delete. Every method returns a Promise<T>, JSON bodies are parsed automatically, 204 responses resolve to undefined, and non-2xx responses throw a BackendError. See Errors & retries for the failure shape.

baseUrl (readback)

The resolved base URL. Useful if you serialize the client config for logging or surface it in a startup banner.

console.log(`Stridge SDK pointed at ${stridge.baseUrl}`)
// → "Stridge SDK pointed at https://api.stridge.com/v1"

Multi-tenant patterns

The client holds no global state — every call goes through fetch against the configured baseUrl and headers, so you can run as many clients as you need in the same process.

One client per tenant

worker.ts
import { createApiClient } from "@stridge/sdk"

const clients = new Map<string, ReturnType<typeof createApiClient>>()

function clientFor(tenantId: string) {
  const cached = clients.get(tenantId)
  if (cached) return cached
  const fresh = createApiClient({
    projectKey: getTenantKey(tenantId),
    env: "prod",
    defaultHeaders: { "X-Tenant-Id": tenantId },
  })
  clients.set(tenantId, fresh)
  return fresh
}

The cache is process-local, so the hot path is one map lookup per request. Each ApiClient instance carries its own HttpClient pair — they share no buffers, no in-flight queues, no retry state.

Rotating a key in place

HttpClient.setProjectKey(newKey) lets you swap the authenticated client's key without rebuilding the whole ApiClient. Useful when you rotate a key from a key-management service and want existing in-flight clients to pick up the new value.

stridge.projectHttpClient.setProjectKey(await secrets.read("STRIDGE_PROJECT_KEY"))

Pass null to clear the key entirely (subsequent project-scoped calls will then fail at the gateway).

Header precedence

Three layers of headers feed into every outgoing request. They resolve in this order — later layers overwrite earlier ones:

  1. The client's "Content-Type": "application/json" baseline.
  2. The X-Gateway-Key header from projectKey (only on projectHttpClient).
  3. defaultHeaders from createApiClient(options.defaultHeaders) — reserved names are stripped (see above).
  4. Per-call RequestOptions.headers, the strongest override — wins over everything else, including the reserved-name filter.

The per-call override exists deliberately as an escape hatch: if you need to send X-Gateway-Key with a different value for one request (multi-key debugging, support tooling), pass it under headers on the call itself instead of defaultHeaders.

Next

Was this page helpful?