@strimz/sdk
The server SDK for Node.js + Bun.
The server SDK is the main way most teams use Strimz. It's fully typed, validates every response with Zod, and retries the right kinds of failures automatically (5xx errors and rate limits).
Install
Construct
The constructor doesn't make any network calls. It throws StrimzAuthenticationError unless apiKey is a secret key (sk_test_… or sk_live_…). StrimzClient is server-side only: never ship a secret key to the browser. Browser code uses StrimzBrowserClient from @strimz/sdk/browser or the React SDK, both with a publishable key.
Where StrimzClient runs
StrimzClient refuses to start in a browser runtime. There it throws StrimzAuthenticationError with code secret_key_in_browser, no httpStatus, and a message that links to Create sessions on your server. The message never contains your key. There is no option to turn the check off.
The SDK decides the runtime from the globals it can see. The first row that matches wins:
| Order | Signal | Runtime |
|---|---|---|
| 1 | EdgeRuntime is defined (Vercel Edge, Next.js middleware) | server |
| 2 | Deno is defined | server |
| 3 | Bun is defined | server |
| 4 | navigator.userAgent is Cloudflare-Workers | server |
| 5 | process.versions.electron is set and process.type is renderer | browser |
| 6 | process.versions.node is set (including Node test runs with jsdom) | server |
| 7 | window and document are defined | browser |
| 8 | self is a WorkerGlobalScope (web, shared and service workers) | browser |
| 9 | navigator.product is ReactNative | browser |
| 10 | anything else | server |
React Native counts as a browser: an app bundle can be unpacked as easily as a web bundle, and React Native has no CORS check to stop the call. Electron renderers and React Native apps should call your own server, like any web page.
The check is a guard rail: by the time the constructor throws, the key is already in your bundle. Rotate any secret key that has shipped to a browser.
Resources
Every API resource is exposed as a property:
Each follows the same create | retrieve | list shape, plus actions such as cancel or revoke. There are no generic update methods; agents.updateConfig, customers.upsert and storefronts.upsert change existing records. Returns are typed:
Pagination
List methods return a { data, nextCursor, hasMore } envelope:
Errors
Every error is a StrimzError or a subclass of it. Catch the base class and instanceof-narrow as needed. A 400, such as invalid_request, is a plain StrimzError, so check code:
See Errors for the full list.
Webhook signature verification
verifyWebhookSignature(payload, signatureHeader, secret, options?) is async. Pass the raw request body as a string, exactly as received, then check result.valid:
result.reason is one of malformed_header, missing_timestamp, missing_signature, timestamp_out_of_range, or signature_mismatch.
Constant-time comparison; safe to use directly without wrapping in your own crypto.timingSafeEqual call.
Idempotency
create methods accept an idempotencyKey option. The SDK generates one automatically if you don't provide one:
See Idempotency.
Compatibility
- Node.js ≥ 18 (uses
fetch) - Bun ≥ 1.0
- Deno via the npm shim
- Cloudflare Workers (
@strimz/sdkis Edge-runtime safe. It usesglobalThis.fetchandWeb Crypto API, no Node-builtins)

