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
| Option | Type | Default | Notes |
|---|---|---|---|
projectKey | string | null | undefined | Sent 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. |
baseUrl | string | derived from env | Override the resolved base URL — use for self-hosted gateways, regional proxies, or local mocks. |
defaultHeaders | Record<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.
env | Resolves 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.
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.
| Client | Auth | Methods | Page |
|---|---|---|---|
stridge.gateway | projectKey required | start, poll, assets, rateBySymbol, rateByErc20 | Gateway endpoints |
stridge.onramp | projectKey required | catalog, fiats, crypto, countries, paymentMethods, quote, createSession, getSession, listOwnerSessions | Onramp endpoints |
stridge.uda | none | supportedAssets, quote | UDA endpoints |
stridge.balance | projectKey required | onchain | Balance 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:
httpClientsends noX-Gateway-Key. Use for public endpoints.projectHttpClientsends the configuredprojectKeyasX-Gateway-Keyon 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
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:
- The client's
"Content-Type": "application/json"baseline. - The
X-Gateway-Keyheader fromprojectKey(only onprojectHttpClient). defaultHeadersfromcreateApiClient(options.defaultHeaders)— reserved names are stripped (see above).- 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
- Gateway endpoints — the bread-and-butter authenticated surface.
- UDA endpoints — public catalogue and quote calls.
- Errors & retries —
BackendError, transport vs backend, retry guidance.