SDK — install & client
@boomin/sdk is the server-side SDK for the Boomin Platform API. It is built on
fetch + WebCrypto only, with zero dependencies and no Node builtins — so it
runs on Node ≥ 18, Cloudflare Workers, Bun, Deno, and edge runtimes.
npm install @boomin/sdkimport Boomin from "@boomin/sdk";
const boomin = new Boomin(process.env.BOOMIN_SECRET_KEY);Client options
Section titled “Client options”const boomin = new Boomin("sk_boomin_live_...", { baseUrl: "https://api.boomin.ai", // API origin; paths live under /v1/platform brand: "brand_123", // threads the Boomin-Brand header maxRetries: 2, // retries on 429/5xx timeout: 30000, // per-request timeout in ms fetch: myFetch, // custom fetch implementation});Pass the API origin, not the versioned path — the SDK appends
/v1/platform itself.
Per-call options
Section titled “Per-call options”Every method takes per-call RequestOptions as its trailing argument:
await boomin.distributions.launch(id, {}, { idempotencyKey: "launch-2026-08-01", // otherwise auto-generated per mutation brand: "brand_456", // per-call Boomin-Brand override timeout: 10000, maxRetries: 0,});Note the shape: methods that accept a body take (id, params, options). For
verbs with no body (pause, resume, approve, …) pass {} or null for
params.
Brands
Section titled “Brands”A platform key belongs to an organization. If your org has more than one
brand, select the brand with the Boomin-Brand header — the SDK’s brand
option, either on the client or per call. It accepts a brand id or slug. With
no header, the org’s first brand (oldest) is used.
Idempotency
Section titled “Idempotency”Every mutation automatically carries an Idempotency-Key header — a fresh UUID
per call unless you supply idempotencyKey. Because mutations are always keyed,
the SDK can safely retry them on 429 and 5xx.
Supply your own key when your retry loop must not double-apply:
await boomin.distributions.launch(id, {}, { idempotencyKey: `launch:${orderId}` });On launch, the key serves two contracts at once: HTTP response replay and
operation dedupe in the execution kernel.
Pagination
Section titled “Pagination”List calls resolve one page and are also async-iterable across every page
(cursor pagination on starting_after):
// one pageconst page = await boomin.relationships.list({ limit: 20 });console.log(page.object, page.data.length, page.hasMore);// "list" 20 true
// every pagefor await (const enrollment of boomin.enrollments.list({ program: "prog_123" })) { console.log(enrollment.id);}limit must be between 1 and 100 (default 20). Camel-cased query params are
converted to the wire’s snake_case (startingAfter → starting_after).
Casing
Section titled “Casing”Since 1.0.0-beta.2 the SDK speaks camelCase in both directions. Request
bodies and query params are converted to the wire’s snake_case on the way out
(periodStart → period_start), and responses are converted to camelCase on
the way back (download_url → downloadUrl).
const accepted = await boomin.payouts.exportCsv({ periodStart, periodEnd });const batch = await boomin.payouts.batches.retrieve(accepted.batch);console.log(batch.downloadUrl, batch.itemCount);Already-snake_case keys you send are passed through untouched, so
{ period_start } still works. Sending both spellings of one field throws
ConflictingParametersError rather than picking a winner.
Ids are returned with a type prefix and accepted with or without it:
| Prefix | Resource |
|---|---|
prog_ | program |
enr_ | enrollment |
dist_ | distribution |
dep_ | deployment |
conn_ | connection |
op_ | operation |
evt_ | event |
perf_ | performance event |
po_ / pob_ | payout / payout batch |
prule_ / prail_ | payout rule / payout rail |
we_ | webhook endpoint |
Passing a wrong prefix for the resource returns that resource’s typed 404 — it never leaks whether another tenant’s object exists.
Response shapes
Section titled “Response shapes”Success responses are Stripe-style bare objects — the resource itself, not
{ distribution: {...} }. Three deliberate exceptions:
distributions.launch→{ distribution, status, operation }, all id strings.distributions.pause/resume/cancel(and the deployment verbs on the API) → the bare resource plus anoperationid alongside.payouts.exportCsvandpayouts.batches.export→{ batch, status: "exporting", operation }, all id strings;payouts.batches.confirm→ the same withstatus: "confirming".
On the raw wire, webhook endpoints are the one exception to bareness —
create/retrieve/update/rotate_secret answer
{ "webhook_endpoint": { ... } } — but the SDK unwraps that envelope, so
every webhooks.endpoints.* method still resolves to the bare endpoint.
A handful of reads return the bare resource plus a companion field:
distributions.validate adds valid and errors;
relationships.retrieve adds enrollments;
payouts.batches.retrieve adds items and downloadUrl;
payouts.batches.create adds items and skipped;
performance.events.create adds duplicate and projected.
Lists are always { object: "list", data: [...], hasMore: boolean } (wire:
has_more).
Errors
Section titled “Errors”Every non-2xx raises a subclass of BoominError carrying code, status,
requestId, and param. See Errors.
Resource clients
Section titled “Resource clients”| Client | Methods |
|---|---|
programs | create retrieve update list standingPreview + nested requirements / tiers / connectConfig / handoffConfig |
entities | retrieve list (canonical; deprecated entities delegates here) |
relationships | list retrieve pause resume end updatePermissions (canonical; deprecated relationships delegates here) |
assertions | create revoke list retrieveEvent — claim-addressed tenant truth |
operatingTypes | create retrieve update list archive — capacity vocabulary |
metricKeys | create retrieve update list archive — tenant x: metrics |
enrollments | create retrieve list approve reject pause resume update + nested requirementOverrides |
distributions | create retrieve update list validate launch pause resume cancel |
deployments | retrieve list |
connections | list retrieve revoke |
performance | summary + events.create |
events | list |
operations | retrieve list wait |
webhooks | endpoints.create/retrieve/update/list/del/rotateSecret + constructEvent |
payouts | list run exportCsv connectStatus |
payouts.rules | create retrieve list update archive — no del() |
payouts.rails | create retrieve list update |
payouts.batches | create retrieve list export confirm cancel |
resume is the canonical verb on every surface — never unpause.
Deprecated packages
Section titled “Deprecated packages”| Package | Status |
|---|---|
boominjs | Deprecated. Use @boomin/sdk for the Platform API, or @boomin/connect for browser Partner Connect. |
@boomin/server | Maintenance only. Still used by the generated Signed Handoff routes; new server integrations should use @boomin/sdk. |