Skip to main content
@alguna/sdk is the official TypeScript client for the Alguna Public API. It exposes one typed method per endpoint — customers, products and plans, subscriptions and versions, usage events and metrics, credits and wallets, invoices, payments, checkout and portal sessions — with request and response types generated from the versioned OpenAPI spec. Use it from Node services where you would otherwise hand-write HTTP calls; it sets the Authorization and Alguna-Version headers, maps failed responses to typed errors, sends an idempotency key on writes that use one, and retries transient failures only when a retry is safe. The objects it manipulates are described in How Alguna works.
The SDK is server-side only. API keys are secret — never ship them to a browser. For embedding a purchase flow in your frontend, use Embedded Checkout (@alguna/checkout-sdk) instead: your server mints the session with this SDK’s API key, your frontend mounts it.

How it works

  1. Create an API key under Settings → Connections → Developers → API keys. A key looks like <key_id>.<key_secret> and is a server secret.
  2. Instantiate the client with the key. Every request it makes carries Authorization: Bearer and pins the API version via the Alguna-Version header.
  3. Call resources (alguna.customers, alguna.subscriptions, …). Methods return typed response objects; failed requests throw typed errors.

Installation

Requires Node.js 20 or later. The package is @alguna/sdk on npm, and its source is alguna-io/alguna-ts on GitHub.

Quick start: customer → subscription → portal session

Subscriptions are created in draft status. Pass auto_activate: true (as above) or call alguna.subscriptions.activate(id) when you are ready to go live. See Creating a Subscription for the full set of patterns — plans, overrides, and bundles all work the same way through the SDK.

Resources

The SDK exposes one field per API resource. The client is generated from the versioned spec, so every public operation has a method. Highlights: Plus products, plans, bundles, creditNotes, payments, refunds, integrations, insights, quotes, revenueSchedules, merchants, tags and tax. Every method name follows the operation it wraps; the full list is in the generated API reference. Request and response types are exported from the package root, and under the AlgunaApi namespace:
Every method takes an optional last argument for per-request options: idempotencyKey (writes that accept one), timeoutInSeconds, maxRetries, headers and abortSignal.

Pagination & filtering

List endpoints accept limit, offset, sort (in field:order format), and the same filter parameters as the HTTP API. They return a Page: data holds the items of the current page, and response holds the full response body, including pagination:
To walk every item, iterate the page. The SDK requests the next page as you go:
The API sends at most the operation’s limit maximum per page (100 for every list today). Iteration stops at the first page that holds fewer items than limit, or than that maximum when limit is larger. When the last page is exactly full, the SDK makes one more request, which returns an empty page. Use page.hasNextPage() and page.getNextPage() to page by hand.

PDF downloads

invoices.generatePdf, quotes.getPdf and subscriptions.downloadPdf return a BinaryResponse. Read it with arrayBuffer(), blob() or stream():

Error handling

Failed requests throw typed errors, all extending AlgunaError:
All errors expose message (the body’s detail, else title, else message, else the HTTP status text), statusCode, requestId (the X-Request-Id of the failed response), code (when the body carries one), body and headers. Include the requestId when contacting support about a failed call. Status meanings and retry guidance are on the Errors page.

Idempotency and retries

Every request that is not a GET sends an Idempotency-Key: pass your own idempotencyKey, or the SDK generates a UUID v4 per call. The API then returns the original result instead of repeating the action (see Idempotency). events.ingest, credits.track and credits.check are the exceptions. The events in the request body identify the work, so the SDK generates no key for these calls and sends only one that you pass (see Writes identified by their events). Pass your own key when you retry a call yourself, for example after a restart:
The SDK retries a failed attempt 2 times by default (3 attempts in total) when:
  • the status is 408, 429, 502, 503 or 504;
  • the status is 409 with Retry-After. The API sends this only while a request with the same key is still running. A 409 without Retry-After is a real conflict and is not retried;
  • no response arrived: the connection was refused, reset or closed, or the attempt timed out.
The SDK never retries after you abort a call through abortSignal. Between attempts it waits 1 s, then 2 s, with jitter. When the response has Retry-After, it waits that long instead, at most 60 s. Each retry reuses the call’s key, so a retry never applies a write twice. events.ingest, credits.track and credits.check are retried without a key unless you pass one: the API identifies their events by unique_id, so a resent batch is applied once. Set maxRetries on the client or per call to change the count; 0 turns retries off. Each attempt times out after 60 s. Set timeout (milliseconds) on the client or timeoutInSeconds per call. To limit a whole call, retries included, pass an abortSignal; when it aborts, the SDK throws AbortError.

Configuration

Pass apiVersion to pin the version your integration is written against. Without it, the SDK sends the version its types were generated from, so upgrading the package can move you to a newer API version — see Versioning.

FAQ

Can I use the SDK in the browser? No. It authenticates with your secret API key. For browser purchase flows, mint a checkout session server-side and mount it with Embedded Checkout. Does the SDK cover every endpoint? Yes. The client is generated from the versioned OpenAPI spec, so every operation in the API reference has a method. Are there types for webhook payloads? Yes. AlgunaWebhookEvent is a union of every webhook body; narrow on type to get a typed data. The types come from the same spec as the Webhooks page. The SDK does not verify signatures: before you trust a payload, verify its svix-id, svix-timestamp and svix-signature headers with the Svix library, as Verifying signatures shows. Which version am I on, and how does it relate to the API version? Two different things, deliberately decoupled. The package version is the npm release of @alguna/sdk — read it from your lockfile, npm ls @alguna/sdk, or npm view @alguna/sdk version for the latest published. The API version is the date sent as Alguna-Version, and it is the only thing that decides request and response shapes. When you pass apiVersion, upgrading the package never moves you to a different API version: a newer SDK still speaks the date you pinned. When you do not, the SDK sends the version it was built for. Upgrade the package to pick up new endpoints, types and fixes; change apiVersion deliberately, as its own change, following Versioning. Is @alguna/checkout-sdk the same package? No. @alguna/sdk is the server-side API client; @alguna/checkout-sdk is the browser package that mounts a checkout session in your page. They version independently and are installed separately. How do I point it at a sandbox or local environment? Pass baseUrl to use another host — for example the sandbox host api.sandbox.alguna.io with a sandbox API key. Everything else works identically. Sandbox and production are separate environments with separate keys; see Base URLs. Is there an SDK for another language? Yes. There are Python, Go and Rust SDKs and an alguna CLI. They are generated from the same API spec as this SDK and behave the same way. See SDKs and CLI. What happens on rate limits? Only credits.check and credits.track get a 429: the credit gate is busy, or the credit ledger has too many open holds. The SDK retries it twice, waiting for Retry-After when the response has one, then throws RateLimitError. Insufficient credit is not a 429: those calls return allowed: false. See Errors.