Merchant / low-level client — createFlightdeckClient
The raw, path-keyed typed client the storefront client
is built on. It exposes a single method, request(), keyed off the generated
paths type: method, path, the per-call args (path / query / header /
body), and the return type are all checked against the OpenAPI spec — a typo in a
path or a wrong body field does not compile.
Reach for it when you are on a merchant/operator surface holding an fdk_
credential, or when you need a spec path the storefront wrapper does not name.
Construction
import { createFlightdeckClient } from "@dscodotco/sdk";
const client = createFlightdeckClient({
baseUrl: "https://api.ruo.pro",
fdkToken: process.env.FDK_TOKEN, // merchant Bearer credential
// storefrontToken: process.env.FLIGHTDECK_STOREFRONT_TOKEN, // or the storefront credential
});Options — FlightdeckClientOptions
| Option | Type | Required | Notes |
|---|---|---|---|
baseUrl | string | yes | Base origin the paths resolve against, e.g. https://api.ruo.pro. A trailing slash is trimmed. |
fdkToken | string | no | The fdk_ merchant credential — sent as Authorization: Bearer <fdkToken>. |
storefrontToken | string | no | The narrow storefront credential — sent as x-storefront-token. |
fetch | typeof fetch | no | Injectable fetch. Defaults to the global fetch. |
Construct a client with whichever credential(s) its surface uses. Both are optional individually, but a client with neither can only reach unauthenticated routes.
Auth-header behavior
The two credentials map to two headers, and both are sent when configured:
| Option | Header sent |
|---|---|
fdkToken | Authorization: Bearer <fdkToken> |
storefrontToken | x-storefront-token: <storefrontToken> |
These auth headers are the client’s own. A per-call header parameter (see
below) can set operation-declared headers like Idempotency-Key, but it can
never override authorization or x-storefront-token — those two names are
ignored if you try to pass them per call. This keeps a request from silently
re-authenticating as someone else.
Both credentials are server-side secrets. The fdk_ merchant credential
authorizes operator actions; the storefront token authorizes placing orders.
Never construct this client in browser code.
The request() surface
request<P extends keyof paths, M extends MethodsOf<P>>(
method: M,
path: P,
args?: RequestArgs<Operation<P, M>>,
): Promise<ResponseBody<Operation<P, M>>>method—"get" | "post" | "put" | "patch" | "delete", narrowed to the methods the chosenpathactually defines.path— any key of the generatedpaths. A path not in the spec does not compile.args— optional; each part is typed to the operation:
args field | Purpose |
|---|---|
path | Path parameters filled into {…} segments (URL-encoded). A missing required path param throws before the request. |
query | Query parameters. undefined / null values are dropped; arrays repeat the key. |
header | Operation-declared header parameters (e.g. Idempotency-Key). Cannot override the auth headers. |
body | JSON body. When present, content-type: application/json is set and the value is JSON.stringify-ed. |
The resolved return type is the operation’s own generated 2xx body. A 204 (or
any non-JSON success response) resolves to undefined. On a non-2xx it throws
FlightdeckError carrying the parsed body.
Calling a merchant route
// Read one merchant order (fdk_ credential).
const order = await client.request("get", "/v1/merchant/orders/{id}", {
path: { id: "ord_1" },
});
// Refund a merchant order — an operation-declared Idempotency-Key header.
await client.request("post", "/v1/merchant/orders/{id}/refund", {
path: { id: "ord_1" },
header: { "Idempotency-Key": `order-ord_1:refund-1` },
body: { amount_cents: 1500, reason: "return accepted" },
});The merchant surface in the spec today includes (non-exhaustive): orders
(/v1/merchant/orders, /v1/merchant/orders/{id}, plus /refund and
/cancel), the catalog list (/v1/merchant/catalog), subscriptions,
webhooks and deliveries, gift cards, returns, marketing campaigns, and API
credentials (/v1/my/credentials). Each is fully typed through request().
Calling a storefront path directly
The low-level client can call any storefront path too — useful for the ones the
wrapper does not name (for example /v1/tenants/{tenant}/checkout/preview), or
where a wrapper method omits a required query parameter. Send the
storefrontToken and pass the query yourself:
const sf = createFlightdeckClient({
baseUrl: "https://api.ruo.pro",
storefrontToken: process.env.FLIGHTDECK_STOREFRONT_TOKEN,
});
// A single shopper order — the wrapper's shopper.order(id) cannot pass person_id,
// so reach the endpoint directly and supply it.
const one = await sf.request("get", "/v1/tenants/{tenant}/shopper/orders/{id}", {
path: { tenant: "ruo-demo", id: orderId },
query: { person_id },
});
// Read-only pricing preview (no named wrapper method).
const totals = await sf.request("post", "/v1/tenants/{tenant}/checkout/preview", {
path: { tenant: "ruo-demo" },
body: { items: [{ variant_id: variantId, quantity: 1 }], coupon_code: "SAVE10" },
});The catalog-write gap
The SDK today is primarily a storefront (read + checkout) client. The
merchant surface it can reach is largely read-oriented: /v1/merchant/catalog
exposes only a get (list the tenant’s catalog). There are no catalog product
create / update / delete operations in the generated spec — so there is no
typed namespace for catalog writes, and, because request() is constrained to
keyof paths, a catalog-write path is not even callable through the typed
client without an escape hatch.
If you need catalog writes today, drive them through the console or the
merchant API directly (outside the generated types) — for example a hand-built
fetch against the merchant catalog write endpoints, carrying your fdk_
credential as Authorization: Bearer. When those routes land in the OpenAPI
spec, they will become callable through request() (and, if wrapped, a named
merchant namespace) in a future SDK release. Do not hand-edit the generated
types to fake them in.
See also
- Storefront client — the ergonomic wrapper most consumers use.
- Error handling —
FlightdeckErrorand retry/idempotency. - TypeScript usage —
paths,Operation,RequestArgs, andResponseBody.