SDK
Use the TypeScript SDK for the default implementation path.
SDK
Use the SDK when you are building a frontend, server route, or workflow that should stay aligned with 01.software conventions.
Setup Flow
Install the package
Add @01.software/sdk to the project package manager already used by the repository.
Create the browser client
Use the Publishable Key only from approved origins. The browser client supports public reads plus capability- or customer-authorized Cart, Checkout, and PaymentSession operations.
Create the server client
Use the Secret Key only in trusted server code for writes and privileged workflows.
Verify the slice
Run the target project's typecheck, lint, tests, and build before handoff.
Client Choice
| Context | Client | Notes |
|---|---|---|
| browser UI | browser client | public reads and capability/customer-authorized commerce, origin-limited |
| server route | server client | import from @01.software/sdk/server for server-authoritative and privileged operations |
| React data fetching | query helpers | keep cache and loading states explicit |
| AI-generated code | existing project patterns | avoid adding framework layers |
Collection find/count preserve null equality filters and reject unsupported
filter shapes before sending a request. where: {} also throws ValidationError;
omit where when no conditions remain. This read-input restriction is a
BREAKING (0.x minor) change. When a dynamic ID list is empty,
return an empty result before querying. See the SDK README filter guidance
for the shared read/bulk limits and supported values.
Import Boundaries
Use @01.software/sdk for the browser-safe client, commerce helpers, and core
types. Use @01.software/sdk/server for createServerClient, and use
@01.software/sdk/query only when your app needs React Query helpers. Error
guards are available from the client/server entry that creates the client and
also work across the root and @01.software/sdk/errors entries.
Rows marked none do not need any extra packages beyond @01.software/sdk.
| Import | Feature(s) | Install when used |
|---|---|---|
@01.software/sdk | browser-safe createClient, commerce helpers, collection helpers, types | none |
@01.software/sdk/client | browser-safe createClient entry and SDK error guards | none |
@01.software/sdk/server | createServerClient, server-only APIs, and SDK error guards | none; keep secretKey code on the server |
@01.software/sdk/errors | SDK error classes and guards | none |
@01.software/sdk/metadata | SEO metadata extraction and generation helpers | none |
@01.software/sdk/webhook | webhook handlers, event guards, and webhook types | none |
@01.software/sdk/query | React Query hooks, cache helpers, getQueryClient | @tanstack/react-query, react, react-dom |
@01.software/sdk/realtime | RealtimeConnection, useRealtimeQuery | @tanstack/react-query, react, react-dom |
@01.software/sdk/storefront-cache | product storefront cache resource helpers | none |
@01.software/sdk/embedded-admin | embedded app browser handshake and protocol types | none |
@01.software/sdk/embedded-admin/server | assertion verification and JWKS loading | none; keep receiver sessions on the server |
@01.software/sdk/ui/rich-text | RichTextContent, StyledRichTextContent | react, react-dom, @payloadcms/richtext-lexical |
@01.software/sdk/ui/form | FormRenderer | react, react-dom |
@01.software/sdk/ui/code-block | CodeBlock, highlight | react, react-dom, shiki, hast-util-to-jsx-runtime |
@01.software/sdk/ui/canvas | CanvasRenderer, CanvasFrame, useCanvas, prefetchCanvas | react, react-dom, @tanstack/react-query, @xyflow/react, quickjs-emscripten, postcss, sucrase |
@01.software/sdk/ui/canvas/server | canvas server helpers | none |
@01.software/sdk/ui/video | VideoPlayer | react, react-dom, @mux/mux-player-react |
@01.software/sdk/ui/image | Image | react, react-dom |
Video playback
For VOD, authorize the viewer in your server application, then call
createServerClient(...).video.playback(video.id) and pass its streamUrl to
<VideoPlayer video={video} streamUrl={streamUrl} />. Renew this bearer URL
before two hours for long playback or after a long pause. Free playback uses the metered gateway and may
return 403 at the monthly delivery limit or 503 if quota admission is
unavailable. Existing raw Mux URL helpers apply only to unmigrated paid assets;
the stored public ID on a migrated asset remains for usage history.
The following stored-ratio mapping requires SDK 0.66.3 or later and is unavailable in the published 0.65.1 artifact. Repository source availability is not publication.
VideoPlayer displays the stored aspectRatio values 16_9, 9_16,
4_3, and 1_1 as CSS ratios in both the placeholder and ready player.
An unset ratio defaults to 16/9. Override the ready player with
style.aspectRatio, or the placeholder with placeholderStyle.aspectRatio;
each override applies only to its own rendering path.
CanvasRenderer renders reserved shape nodes (terminator, process,
decision, io, subprocess) with first-party SVG geometry, without a workspace
catalog row or QuickJS template.
If a feature is not listed here, it does not need a separate peer install. For the full component-to-peer mapping, see the SDK package README.
Gallery image and video items
Use the browser-safe shaped helper to read a published gallery in curator order:
const gallery = await client.content.galleryItems.list({
gallerySlug: 'spring-lookbook',
limit: 24,
})Each item has optional mediaType: 'image' | 'video'; treat an omitted value
from an older response as image. Image items retain image media. Video
items include video.availability: 'ready' | 'processing' | 'unavailable' and
may include a video document id and safe uploaded thumbnail. Disabled or
plan-blocked video access, missing/deleted targets, and failed videos return
only { availability: 'unavailable' }, retaining the item's position and
pagination. The image relationship is not used as a video poster.
ready describes preparation, not playback permission. Your application server
must verify that the video belongs to the published gallery/item and apply its
viewer policy before calling server.video.playback(video.id). Pass the
returned streamUrl to your player; admission rechecks the current workspace,
video state, and feature/plan. Keep server credentials on that server. Gallery
DTOs omit playback URLs, provider IDs, tokens, and private storage fields.
Domain and integration references
- Customers SDK: Customer identity, hosted sessions and source-aware groups.
- Ecommerce SDK: Market context, product edits, orders and storefront caching.
- Events SDK: Canonical event dates and paid-admission projections.
- Community SDK: Browser-safe post reads and nullable detail results.
- Payments: Payment action reuse, reconciliation and custom server bridges.
- Membership: Prepare paid subscriptions and deliver signed charge results.
- Embedded Admin: Receive and verify an embedded app session behind fixed origins.
- External Effects: Server-only effect claims, installation custody and customer links.
Paid Membership Subscription
Continue at Membership.
Embedded Admin Apps
Continue at Embedded Admin.
Error reasons
Canonical commerce failures keep their closed, typed reason on
CommerceSDKError.reason. Other endpoints expose their open-ended machine
reason on SDKError.apiReason. Shared handlers can import
getSDKErrorReason from @01.software/sdk/errors to read either family without
inspecting details.reason or details.body.reason; unknown commerce reasons
are returned verbatim from rawReason.
PortOne Standard V2 cancellation and retry
Continue at Payments.
Server-only PortOne identity reconciliation
Continue at Payments.
Server-only custom payment bridge
Continue at Payments.
Idempotent mutation responses are not exactly-once gates
Continue at Payments.
Existing variant base prices
Continue at Ecommerce SDK.
Orders update compatibility
Continue at Ecommerce SDK.
External-effect claims (server only)
Continue at External Effects.
Installation credentials (server only)
Continue at External Effects.
Tenant Context Introspection
Trusted server workflows can read the resolved workspace features, active and inactive collections, and field configuration through the server-only client:
import { createServerClient } from '@01.software/sdk/server'
const server = createServerClient({
publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!,
secretKey: process.env.SOFTWARE_SECRET_KEY!,
})
const context = await server.tenant.context()
const productSchema = await server.tenant.collectionSchema('products')Use server.tenant.context({ includeCounts: true }) only when collection counts
and webhook configuration are required. It performs additional reads and is
slower than the default call. Keep this API and both credentials in trusted
server code.
productSchema.collection.customFields is optional. When present, it describes
active workspace-defined fields stored under customData using machine keys,
types, optional required markers, and select option storage values. It excludes
operator labels and stored document values; ordinary collection authorization
still governs reads and writes.
Source-aware customer groups
Continue at Customers SDK.
External Customer links
Continue at External Effects.
Customer Auth
Continue at Customers SDK.
Self-withdrawal
Continue at Customers SDK.
Community public reads
Continue at Community SDK.
Event ranges and all-day dates
Continue at Events SDK.
Events Admission
Continue at Events SDK.
Market context
Continue at Ecommerce SDK.
Analytics
For website analytics, integrate an external tool such as GA4, Plausible, or Vercel Analytics in your own frontend. The SDK no longer provides analytics collection helpers.
Storefront Cache Resources
Continue at Ecommerce SDK.
Next.js Mapping
Continue at Ecommerce SDK.
Before Production
- Confirm collection and feature availability for the workspace plan.
- Confirm key storage and rotation ownership.
- Confirm failure handling for customer-facing flows.
Do not put Secret Key values in browser bundles, public env vars, analytics events, or generated examples.
Errors, retries and request identity
Branch on machine reason, never localized error text. Preserve requestId for support and tolerate unknown reasons. Canonical commerce uses CommerceSDKError.reason (unknown values remain in rawReason); generic failures use SDKError.apiReason. getSDKErrorReason reads both. A malformed canonical envelope or mismatched body/header request ID is a protocol failure.
Automatic SDK retry is limited to safe methods on 408/500/502/503/504 failures with bounded backoff. A terminal 429 is not automatically retried; honor Retry-After. Customer-token 401 gets at most one refresh retry, only for token_expired. Never automatically replay token exchange or unsafe mutations. Reuse the original durable idempotencyKey after an interrupted supported mutation; a response flag does not deduplicate your own side effects.
The split examples use published SDK 0.65.1, Next.js 16.3.8 where shown, and Node 24.15.0. Import/peer checks against workspace source, compilation against npm artifacts, controlled local runtime checks, and remote service availability are separate observations. Follow the linked task guides for complete app sessions and deployment checks.
Next Actions
- Need exact HTTP contracts: open API.
- Need a shell-capable coding agent: open CLI.
- Need hosted, shell-less discovery: open MCP.
- Need event delivery: open Webhooks.
- Need ready-made commerce flows? See Commerce helpers.
Customer benefit vouchers
Tenant-admins manage benefit voucher definitions in Console. These are single-use, non-monetary benefits, with no Checkout discount or credit effect. Your server decides recipients and timing (for example from a membership webhook or your own cron); source uniqueness prevents duplicate effects only.
import { createServerClient } from '@01.software/sdk/server'
const server = createServerClient({ publishableKey, secretKey })
const { voucher, created } = await server.benefitVouchers.issue({
definitionId,
customerId,
sourceNamespace: 'member-benefits',
sourceRef: 'period:2030-01:member-opaque-id',
})
const redeemed = await server.benefitVouchers.redeem({
customerId,
voucherId: voucher.id,
requestId,
actorRef: 'staff:opaque-id',
})server.benefitVouchers.get({ customerId, voucherId }) and list({ customerId, state?, definitionId?, limit?, cursor? }) require a read-scoped server key. issue, redeem, and voidVoucher({ customerId, voucherId, requestId, actorRef, reason }) require write scope, sk01 credentials and no browser Origin. Void reasons are issued_in_error, benefit_revoked, customer_request, and other. Issuing and redeeming require effective Ecommerce and Customers; server get/list, customer self-list and void remain available after feature loss. The Console panel lives inside Customer detail and is unavailable with that screen when Customers is disabled.
Reuse the same sourceNamespace/sourceRef and identical issue input on an unknown outcome. For redeem/void, create a request UUID once and reuse it on retries; these POSTs are not automatically retried. Reusing an identity with different input returns 409. A successful transition is irreversible. Expiry uses database time and is inclusive at expiresAt. Correct an issued benefit by voiding it and issuing a new source identity.
client.benefitVouchers.listMine({ status: 'available', limit: 20 }) uses the Customer JWT and returns only identity, customer-visible copy, state and timestamps. Use status: 'all' for history and the returned nextCursor for another page (maximum 100). The response is private, no-store. Server lists return the server DTO and require customerId; cross-customer/tenant targets are masked as 404. Console Customer detail also offers role-gated redeem and void confirmations.
The staff app server must verify the staff member and Customer before redeeming: voucherId is not a bearer capability. actorRef is app-attested evidence, never a platform-verified staff identity or an authorization input. Use opaque references without personal data in sourceRef and actorRef. Definitions snapshot name, description and expiry at issue; later edits do not change issued vouchers. Voucher history survives Customer erasure and blocks tenant hard deletion. Referenced definitions must be archived.