Skip to main content
The @lavapayments/nodejs SDK provides a typed client for all Lava API operations including checkout, customers, usage tracking, and forward token generation.

Installation

npm install @lavapayments/nodejs
Requirements: Node.js 18.0.0 or higher

Initialize

import { Lava } from '@lavapayments/nodejs';

const lava = new Lava();
The client reads your secret key from the LAVA_SECRET_KEY environment variable automatically. You can also pass it explicitly: new Lava('aks_live_...'). Never commit API keys to version control.

Resources

ResourcePurposeKey Methods
checkoutSessionsCreate payment flowscreate()
customersManage customer linkslist(), retrieve(), getSubscription(), delete()
requestsTrack API usagelist(), create(), retrieve()
usageAggregate usage statsretrieve()
subscriptionsManage billing planslistPlans(), retrievePlan(), createPlan(), updatePlan(), deletePlan(), list(), update(), cancel()
metersPricing configurationlist(), retrieve(), create(), update(), delete()
creditBundlesAdd-on credit packslist(), retrieve()
webhooksEvent notificationslist(), retrieve(), create(), update(), delete()
secretKeysAPI key managementlist(), create(), delete()
spendKeysWallet spend keyslist(), retrieve(), create(), update(), revoke(), rotate()
walletKeysWallet API keyslist(), revoke(), rotate()
modelsModel discoverylist()
Plus utility methods:
  • generateForwardToken() — Create authentication tokens for AI requests
  • Lava.login() — Browser-based CLI authentication (static)
  • Lava.exchangeAuthCode() — Exchange auth code for credentials (static)
  • providers.* — Pre-configured URLs for 26+ AI providers

Authentication

Generating Forward Tokens

Customer-based authentication — use this when billing a specific customer’s wallet with your pricing configuration:
const forwardToken = lava.generateForwardToken({
  customer_id: 'conn_id_from_customer',
  meter_slug: 'my-meter'
});

const response = await fetch(lava.providers.openai + '/chat/completions', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${forwardToken}`
  },
  body: JSON.stringify({
    model: 'gpt-4o-mini',
    messages: [{ role: 'user', content: 'Hello!' }]
  })
});
Unmanaged (bring your own key) authentication — use this when you want usage tracking without wallet billing:
const forwardToken = lava.generateForwardToken({
  customer_id: null,
  meter_slug: null,
  provider_key: process.env.OPENAI_API_KEY!
});
Unmanaged mode (bring your own key) lets you use Lava’s proxy for usage tracking and analytics without setting up wallet billing. You supply your own provider API key; the AI provider charges your account directly. Lava may still charge a service fee for metering.

CLI Authentication

Use Lava.login() to authenticate from a CLI or script. It opens the browser, waits for the user to authorize, and returns credentials:
import { Lava } from '@lavapayments/nodejs';

const credentials = await Lava.login();
// credentials: { secret_key, wallet_key?: string | null, wallet_id, merchant_id, ... }

const merchant = new Lava(credentials.secret_key);
const wallet = credentials.wallet_key
  ? new Lava(credentials.wallet_key)
  : null;
Lava.login() loads the active secret key, creating one if needed. It also returns a usable wallet key if one is already available or creates the first wallet key if none exists. If you already have an authorization code (from a custom callback flow), exchange it directly:
const credentials = await Lava.exchangeAuthCode({
  code: 'abc123...',
});
Lava.login() requires a Node.js environment. It starts a local HTTP server and opens the system browser. It is not intended for use in production web applications.

Key Management

Spend Keys

Spend keys give scoped access to your wallet for AI requests. Today these endpoints are still wallet-key authenticated, so use a wallet key if one is available:
const wallet = new Lava('lava_wk_...');

const spendKey = await wallet.spendKeys.create({
  name: 'Agent Key',
  allowed_providers: ['openai', 'anthropic'],
  spend_limit: { amount: '50.00', cycle: 'monthly' },
  rate_limit: { rpm: 60 },
});
// spendKey.key — the raw key, only shown once

// Rotate a key's secret (preserves settings)
const rotated = await wallet.spendKeys.rotate(spendKey.spend_key_id);
// rotated.key — new raw key

// Revoke a key
await wallet.spendKeys.revoke(spendKey.spend_key_id);
Secret keys are the long-term primary credential. Wallet-key usage here is transitional while spend-key management is moved off wallet-key auth.

Wallet Keys

Wallet keys authenticate API calls for wallet-scoped operations (spend keys, wallet keys, models):
const wallet = new Lava('lava_wk_...');

const { data: walletKeys } = await wallet.walletKeys.list();

// Rotate a wallet key's secret
const rotated = await wallet.walletKeys.rotate(walletKeys[0].wallet_key_id);
// rotated.key — new raw key, only shown once

// Revoke a wallet key
await wallet.walletKeys.revoke('wk_abc123');

Model Discovery

List available AI models in OpenAI-compatible format. When authenticated with a spend key, results are filtered by the key’s allowed models and providers:
const wallet = new Lava('lava_wk_...');

const { data: models } = await wallet.models.list();
// models[0]: { id: 'gpt-4o-mini', object: 'model', owned_by: 'openai', created: ... }

Key Operations

Create a Checkout Session

const session = await lava.checkoutSessions.create({
  checkout_mode: 'subscription',
  origin_url: 'https://yourapp.com',
  plan_id: 'sc_plan_id'
});

// Pass session.checkout_session_token to the checkout SDK
Checkout modes: subscription (recurring plan), credit_bundle (add-on credits).

Retrieve a Customer

const customer = await lava.customers.retrieve('conn_abc123');

customer.customer_id;              // unique customer ID
customer.contact;                  // { phone, email, first_name, last_name }
customer.subscription;             // summary or null

Check Subscription Status

const { subscription } = await lava.customers.getSubscription('conn_abc123');

if (subscription) {
  subscription.plan.name;                  // plan name
  subscription.credits.total_remaining;    // total available credits
  subscription.credits.cycle_remaining;    // from included credit + rollover
  subscription.credits.bundle_remaining;   // from bundle purchases + rollover
  subscription.cycle_end_at;               // current cycle end date
  subscription.pending_change;             // null, or { type: 'cancellation' | 'downgrade', effective_at }
}

Update a Subscription

// Set auto top-up bundle for a customer's subscription
await lava.subscriptions.update('as_abc123', {
  auto_top_up_bundle_id: 'cb_pack_id'
});

// Disable auto top-up
await lava.subscriptions.update('as_abc123', {
  auto_top_up_bundle_id: null
});

Report Usage (Post-Request Billing)

For advanced scenarios where you track usage outside of Lava’s proxy:
const request = await lava.requests.create({
  request_id: 'req_custom_' + Date.now(),
  customer_id: 'conn_abc123',
  meter_slug: 'my-meter',
  input_tokens: 100,
  output_tokens: 50,
  metadata: {
    feature: 'code-generation',
    user_id: 'user_789'
  }
});

request.cost;                // base AI provider cost
request.charge.amount;       // merchant fee/markup charged
request.model_usage;         // { input_tokens, output_tokens, total_cost, ... }

Get Usage Statistics

const usage = await lava.usage.retrieve({
  start: '2025-01-01T00:00:00Z',
  end: '2025-01-31T23:59:59Z',
  // Optional filters:
  // customer_id: 'conn_abc123',
  // meter_id: 'meter_abc123',
  // metadata_filters: { feature: 'chat' },
});

usage.totals.total_requests;      // aggregate request count
usage.totals.total_usage_tokens;  // aggregate token count
usage.totals.total_cost;          // aggregate AI provider cost
usage.totals.total_charge;        // aggregate merchant fees/markup
usage.items;                      // daily breakdown array

Common Patterns

Pagination

All list methods support cursor-based pagination:
let cursor: string | undefined;
const allCustomers = [];

do {
  const response = await lava.customers.list({ limit: 100, cursor });
  allCustomers.push(...response.data);
  cursor = response.next_cursor;
} while (cursor);

Error Handling

const response = await fetch(lava.providers.openai + '/chat/completions', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${forwardToken}`
  },
  body: JSON.stringify({
    model: 'gpt-4o-mini',
    messages: [{ role: 'user', content: 'Hello!' }]
  })
});

if (!response.ok) {
  const error = await response.json();
  // 402 — insufficient wallet balance
  // 401 — invalid forward token
  // Other — provider error (passed through)
}

const data = await response.json();

Complete Flow Example

A complete integration from checkout to AI request:
import { Lava } from '@lavapayments/nodejs';

const lava = new Lava();

// 1. Create a checkout session for a new customer
const session = await lava.checkoutSessions.create({
  checkout_mode: 'subscription',
  origin_url: 'https://yourapp.com',
  plan_id: 'sc_plan_id'
});
// Pass session.checkout_session_token to the checkout SDK

// 2. After checkout completes, your frontend receives a customer_id
//    Store it in your database, associated with your user

// 3. Generate a forward token for AI requests
const forwardToken = lava.generateForwardToken({
  customer_id: 'conn_...', // from your database
  meter_slug: process.env.LAVA_METER_SLUG!
});

// 4. Make an AI request through Lava's proxy
const response = await fetch(lava.providers.openai + '/chat/completions', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${forwardToken}`
  },
  body: JSON.stringify({
    model: 'gpt-4o-mini',
    messages: [
      { role: 'system', content: 'You are a helpful assistant.' },
      { role: 'user', content: 'Hello!' }
    ]
  })
});

const data = await response.json();

// 5. Check remaining credit
const { subscription } = await lava.customers.getSubscription('conn_...');
// subscription?.credits.total_remaining
The SDK automatically detects test vs production mode based on your secret key prefix:
  • aks_test_* routes to sandbox (sandbox-api.lava.so)
  • Other prefixes route to production (api.lava.so)

Next Steps