Configuration
SDK initialization and configuration options
Configuration
Configure the Billwave SDK with your API keys and environment settings.
Initialization
import { Billwave } from "@digvijay-x1/billwave";
const billwave = new Billwave({
// billwave_sk_test_… selects sandbox, billwave_sk_live_… selects live
secretKey: process.env.BILLWAVE_SECRET_KEY,
});Configuration Options
| Option | Type | Required | Description |
|---|---|---|---|
secretKey | string | ✅ | Your API secret key. Scoped keys (billwave_sk_test_… / billwave_sk_live_…) also select the environment |
mode | "sandbox" | "live" | - | Environment. Required for legacy (unscoped) keys; must agree with a scoped key |
apiUrl | string | - | Custom API URL for self-hosted deployments (stands in for mode) |
debug | boolean | - | Enable debug logging |
catalog | CatalogEntry[] | - | Declarative plan/feature definitions |
Environments
Billwave has two fully isolated environments, each on its own host:
| Environment | Host | Key prefix |
|---|---|---|
| sandbox | https://sandbox.billwave.example | billwave_sk_test_ |
| live | https://api.billwave.example | billwave_sk_live_ |
A key only works against its own environment — a sandbox key sent to the live API is rejected with 401 environment_mismatch before anything is written. Every response also echoes where it landed: the X-Billwave-Environment header (sandbox or live) plus X-Billwave-Organization, and check()/track() results include environment in the body.
The SDK never defaults to live
The environment is resolved from, in order:
apiUrl— explicit host (self-hosted / local)mode— explicit"sandbox"or"live"- the key prefix —
billwave_sk_test_…→ sandbox,billwave_sk_live_…→ live
If none of these determine it (a legacy billwave_sk_… key with no mode), the client still constructs, but the first request throws an BillwaveError with code config_error instead of silently talking to production. If mode contradicts the key's scope, that is also a config_error.
// Scoped key: nothing else needed
const billwave = new Billwave({ secretKey: process.env.BILLWAVE_SECRET_KEY });
billwave.mode; // "sandbox" | "live", inferred from the key
billwave.apiUrl; // "https://sandbox.billwave.example/v1"
// Legacy key: say which environment you mean
const legacy = new Billwave({
secretKey: process.env.BILLWAVE_SECRET_KEY, // billwave_sk_…
mode: "sandbox",
});Use the dashboard to create one key per environment; legacy keys keep working on both hosts but should be rotated.
Custom API URL
For self-hosted deployments or custom endpoints, use apiUrl. This takes precedence over mode:
const billwave = new Billwave({
secretKey: process.env.BILLWAVE_SECRET_KEY,
apiUrl: "https://billing.mycompany.com",
// mode is ignored when apiUrl is provided
});URL Resolution Priority
The SDK resolves the API URL in this order:
- Explicit
apiUrl(highest priority) mode→https://sandbox.billwave.example/v1orhttps://api.billwave.example/v1- Key prefix → same hosts, inferred from
billwave_sk_test_/billwave_sk_live_ - Otherwise: unresolved — requests throw
config_error(there is no default host)
Debug Mode
Enable debug mode for verbose logging:
const billwave = new Billwave({
secretKey: process.env.BILLWAVE_SECRET_KEY,
mode: "sandbox",
debug: true,
});With Catalog
Pass a declarative catalog for plan/feature management:
import { metered, boolean, plan } from "@digvijay-x1/billwave";
const billwave = new Billwave({
secretKey: process.env.BILLWAVE_SECRET_KEY,
mode: "live",
catalog: [
plan("pro", {
name: "Pro",
price: 2900,
currency: "USD",
interval: "monthly",
features: [
metered("api-calls").limit(10000),
boolean("premium-support").enabled(),
],
}),
],
});
// Sync catalog to server
await billwave.sync();Runtime Configuration
Override configuration at runtime (useful for CLI tooling):
const billwave = new Billwave({
secretKey: process.env.BILLWAVE_SECRET_KEY,
});
// Point at sandbox (both calls re-resolve billwave.mode / billwave.apiUrl)
billwave.setSecretKey(process.env.BILLWAVE_SANDBOX_SECRET_KEY);
billwave.setApiUrl("https://sandbox.billwave.example/v1");Best Practices
- Use environment variables - Never hardcode API keys
- One scoped key per environment -
billwave_sk_test_…for sandbox,billwave_sk_live_…for live; the API refuses the wrong host - Check the echo -
X-Billwave-Environment/result.environmenttell you where a request actually landed - Custom URL stands in for mode - With
apiUrl,modeis optional but must still agree with a scoped key
Examples
Development Setup
// config.ts
export const billwave = new Billwave({
secretKey: process.env.BILLWAVE_SANDBOX_SECRET_KEY!,
mode: "sandbox",
debug: process.env.NODE_ENV === "development",
});Production Setup
// config.ts
export const billwave = new Billwave({
secretKey: process.env.BILLWAVE_LIVE_SECRET_KEY!,
mode: "live",
});Dynamic Mode
// config.ts
const mode = process.env.BILLWAVE_MODE as "sandbox" | "live" | undefined;
const secretKey =
mode === "sandbox"
? process.env.BILLWAVE_SANDBOX_SECRET_KEY
: process.env.BILLWAVE_LIVE_SECRET_KEY;
export const billwave = new Billwave({
secretKey: secretKey!,
mode, // undefined is fine with scoped keys; a legacy key needs it set
});Related
- Catalog Sync - Define plans and features declaratively
- Quickstart - Get started with Billwave