@bachs/sdk is the official Bachs library for Node.js and TypeScript servers. It sends authenticated requests, checks and types the responses, retries reads safely, and verifies webhook signatures.
It runs on your server only. Keep your secret API key out of browser code.
Install
You need Node.js 22 or later.import and require.
Create a client
Create one client and reuse it. Pass your secret key and the environment it belongs to.lib/bachs.ts
environment is required. "sandbox" sends requests to https://sandbox-api.bachs.io and "production" sends them to https://api.bachs.io. Use a sandbox key with "sandbox" and a production key with "production". See Authentication.
Creating a client sends no request, so a wrong key shows up on your first call.
Send requests
Each resource on the client maps to a group of API endpoints. Methods follow one pattern:- Create:
create(input, options?) - Retrieve:
get(id, options?) - List:
list(filters?, options?)
"12.00", never numbers.
Resources
subscriptions.cancel(id, input?, options?) takes { cancel_at_period_end: true } to cancel at the end of the paid period, or false to cancel now. See Manage subscriptions.
Not in the SDK yet
Use the API directly for these. You can call it alongside the SDK with the same key.- Connect: connected accounts, onboarding, the
X-Account-Idheader and split payments - Customers, refunds, disputes and conversions
- Updating, archiving or unarchiving products, and changing a subscription’s seats or plan
- Virtual accounts, uploads, product groups and account settings
Lists and pagination
List methods return one page, in the same shape as the API response. The SDK does not fetch further pages for you. Products page by cursor. Passpagination.next_cursor as cursor to get the next page:
limit and offset. Payout destinations are in destinations; the others are in items.
Request options
Every method takes an options object as its last argument.Retries and uncertain writes
Reads are retried up tomaxRetries times after a network failure or an HTTP 429, 500, 502, 503 or 504. The SDK waits about half a second, then a second, and follows any Retry-After header. It stops when the next wait would pass timeoutMs.
Writes are sent once, even with an idempotency key. A write can reach Bachs and still fail on the way back, for example when the connection drops or the API returns a 5xx. In those cases the error has outcomeUnknown: true: the payment, payout or product may exist.
When a write’s outcome is unknown, do not send it again with a new key. Look it up first, for example in your payout history or by retrieving the checkout session. If it does not exist, repeat the write with the same idempotency key and the same request.
Errors
Every SDK error extendsBachsError.
errorCode is the error_code from the response body, and fieldErrors lists any problems with individual fields. See Errors. Include requestId when you contact support.
Error bodies and customer portal URLs can contain personal data or credentials. Do not log them in full.
Verify webhooks
webhooks.constructEvent checks the signature on a delivery and returns the event. Pass the raw request body, before any JSON parsing, the request headers, and your endpoint’s signing secret. The signing secret is not your API key.
app/api/webhooks/bachs/route.ts
X-Bachs-Signature-V2, accepts any matching signature while you rotate a secret, and rejects deliveries more than 300 seconds old or ahead. Change the window with a fourth argument, { toleranceSeconds }. You can call it without a client, or as bachs.webhooks.constructEvent.
It does not deduplicate events or run your handlers. Your app stores processed event IDs and returns a 5xx when handling fails, so Bachs retries. See Webhooks.
TypeScript
Request and response types are exported from the package:unknown, so a new field never breaks your build.
Source code
The SDK is open source under the MIT license.- GitHub repository: source, issues and the full README
- npm package
- Changelog

