Get startedChangelog

Changelog

Notable changes to the public developer surface — the API, the @dscodotco/sdk client, and the storefront contract. Internal-only changes (console panels, infra scaffolding) are omitted. Dates are grouped by month; where a change alters a contract you consume, the migration note says so.

September 2026

Public catalog now returns a resolvable image_url

The public catalog previously emitted only the opaque asset:<store>/<sha> ref and pushed all resolution to the client. Commerce now resolves the ref and includes image_url (and a per-image url) on products list, product-by-slug, search, and collection detail. Resolution is a pure string transform against an ASSET_BASE_URL; when the base is unset the field is null (honest absence, never a broken guess). The OpenAPI spec and SDK types carry the new field.

Migration: none required — the field is additive. Headless consumers that were resolving asset refs themselves can now read image_url directly.

Replay-safe webhook signatures

Outbound webhooks are now signed with a versioned, replay-safe scheme: x-webhook-timestamp plus x-webhook-signature-v1, where the signature is t=<ts>,v1=<HMAC(secret, ts.body)>. The delivery envelope also gains a created_at. The legacy signature header is still sent but is deprecated. See the webhooks reference for the verification recipe.

Migration: move verification to x-webhook-signature-v1 (timestamp + HMAC over timestamp.body); stop trusting the legacy header.

Public authored-site endpoint — GET /v1/tenants/{tenant}/site

The merchant’s authored site (sections, nav, theme tokens) is now part of the public contract. GET /v1/tenants/{tenant}/site returns the active manifest for a live store — the same ETag contract as store resolve. A non-live or unknown tenant is the same 404 (no existence oracle), and a repo failure is a 503, never a silent empty manifest. The SDK exposes it as store.site.get(). See Manifest & sections and Build your own frontend.

Idempotency-Key on money-path routes

The money-moving routes now take a required, deterministic idempotency key so a retried write replays instead of double-posting. Checkout requires an Idempotency-Key header (a submit without it is a 400); the returns receive (restock + settle refund) route requires it too; the storefront cancel/edit/refund calls take the same key. Make the key deterministic — derive it from the business event, never a fresh random value. See Money invariants.

Store credit and gift cards as checkout tenders

Two money tenders are now first-class at checkout. Store credit (an authed shopper’s cash balance) applies as a partial tender behind the storeCredit.enabled manifest gate, reducing the card charge by min(balance, orderTotal). Gift cards are purchasable/redeemable bearer codes behind the giftCards.enabled gate — the plaintext code is shown once at issue, and redemption applies as a partial decrement. A multi-tender order stays zero-sum across store credit + gift card + card. Recipes: store credit, gift cards.

Public, unauthenticated catalog route

Commerce gained the one public, tenant-scoped catalog route the storefront shop pages (and unauthenticated headless callers) need: GET /commerce/v1/tenants/:tenant/catalog/products and .../products/:slug. Read-only, and gated three independent ways — only active products, only a live store, and a failed read is a 503 — so a draft or suspended tenant 404s identically to an unknown tenant slug (no slug enumeration).

Two discovery surfaces on the public catalog: GET /v1/tenants/:tenant/catalog/search (full-text search with price and collection facets) and .../catalog/collections[/:slug]. Both share the live-store gate and the honest-absence contract; a blank query is a valid “no query” (empty 200), a DB failure is a 503. See the collections & search reference.

Typed SDK — @dscodotco/sdk 0.0.3

@dscodotco/sdk is a typed fetch client generated from the API’s OpenAPI document. createFlightdeckClient({ baseUrl, fdkToken?, storefrontToken? }) gives compile-time-checked paths, path/query/body shapes, and response types, with the fdk_ Bearer / x-storefront-token credentials injected automatically; createStorefrontClient(...) wraps it as a tenant-pinned storefront client. The package is MIT-licensed, has zero workspace dependencies, and is publishable and consumable standalone.

Merchant site builder — drafts, preview, publish, rollback

The manifest is now edited as immutable versioned drafts with an active pointer. New merchant routes (GET /v1/my/site, PUT /v1/my/site/draft, POST /v1/my/site/publish, POST /v1/my/site/preview-token) let a merchant build against the live storefront without touching the published site; publishing an older version is the rollback. A signed, short-lived preview token renders a draft behind a non-dismissible banner and forced noindex. See Manifest & sections.