SDK reference — @dscodotco/sdk
The official typed client for the Flightdeck commerce API (ADR-0007). Everything in it is generated from the API’s OpenAPI document, so a wrong path, query field, or body field is a compile error, not a runtime surprise. The types ship prebuilt in the package — you never run a code generator.
The package exports two factory functions, one built on the other:
| Factory | Use it to | Auth header |
|---|---|---|
createStorefrontClient | Build a headless storefront: read the catalog and place orders, pinned to one tenant. | x-storefront-token |
createFlightdeckClient | Call any spec path directly (merchant/operator routes, or storefront paths the wrapper does not expose). | Authorization: Bearer and/or x-storefront-token |
Most consumers only need createStorefrontClient. Reach for the low-level client
when you are on a merchant surface holding an fdk_ credential, or when you need
a spec path the storefront wrapper does not name.
The SDK today is primarily a storefront client — catalog reads plus checkout. The merchant surface is reachable through the low-level client, but a few merchant operations (notably catalog writes) are not in the generated spec yet. See the merchant client.
Install
pnpm add @dscodotco/sdkThe package is ESM and ships its own .d.ts types. No @types/* companion and
no OpenAPI generation step are needed.
Your first call
Construct a tenant-pinned storefront client on the server and read the catalog.
Everything is one await and fully typed.
import { createStorefrontClient } from "@dscodotco/sdk";
const store = createStorefrontClient({
apiUrl: "https://api.ruo.pro",
tenant: "ruo-demo",
storefrontToken: process.env.FLIGHTDECK_STOREFRONT_TOKEN!, // server-side only
});
const { products } = await store.products.list();
const first = await store.products.get(products[0].slug);
console.log(first.product.name, first.product.price_cents);The storefront token authorizes placing orders. Never construct either
client in browser code — build it in a server runtime (a Next.js Route
Handler, a server component, an edge function — anywhere fetch exists) and
keep the token in a server env var.
When to use which client
Building a storefront (reading catalog, placing orders)
Use createStorefrontClient. It pins one tenant into
every path (fail-closed tenancy — it can never address another store), names the
surface (store.products.list() instead of a raw path), and sends the narrow
x-storefront-token. This is what surfaces/storefront itself uses.
Calling a merchant/operator route with an fdk_ credential
Use createFlightdeckClient. It is the raw, path-keyed
client — you call client.request("get", "/v1/merchant/orders/{id}", …) with
the operation’s own generated argument and return types. Send the fdk_
credential as fdkToken.
Needing a storefront path the wrapper does not name
The storefront wrapper covers site, products, collections, search, checkout,
shopper orders, and store credit. A handful of spec paths (for example
/v1/tenants/{tenant}/checkout/preview) exist but have no named method — reach
them through the low-level client, which can call any path in the spec.
What the SDK exports
import {
createStorefrontClient,
createFlightdeckClient,
FlightdeckError,
} from "@dscodotco/sdk";
import type {
StorefrontClient,
StorefrontClientOptions,
FlightdeckClient,
FlightdeckClientOptions,
HttpMethod,
MethodsOf,
Operation,
RequestArgs,
ResponseBody,
paths,
operations,
components,
} from "@dscodotco/sdk";See TypeScript usage for how to reach into components and
paths for the exact request and response shapes.
In this section
- Storefront client —
createStorefrontClient: every namespace and method, with signatures and verified examples. - Merchant / low-level client —
createFlightdeckClient, therequest()surface, and auth-header behavior. - Error handling —
FlightdeckError: its shape, catching it, and retry/idempotency. - TypeScript usage — importing types, inference tips, and known type drift.