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()
modelsModel discoverylist()
Plus utility methods:
  • gateway() — Make requests through the gateway in a single call
  • generateForwardToken() — Create authentication tokens for manual requests
  • Lava.login() — Browser-based CLI authentication (static)
  • Lava.exchangeAuthCode() — Exchange auth code for credentials (static)
  • providers.* — Pre-configured URLs for 27 AI providers

Gateway Requests

The gateway() method makes a request through Lava’s gateway in a single call. It handles forward token generation, URL construction, and body serialization automatically.
const data = await lava.gateway('https://api.openai.com/v1/chat/completions', {
  body: {
    model: 'gpt-4o',
    messages: [{ role: 'user', content: 'Hello!' }],
  },
});

Parameters

ParameterTypeRequiredDescription
urlstringYesThe raw provider URL (e.g., https://api.openai.com/v1/chat/completions)
options.methodstringNoHTTP method. Defaults to POST.
options.bodyunknownNoRequest body. Objects/arrays are auto-serialized to JSON. Strings, Buffers, and streams pass through unchanged.
options.headersRecord<string, string>NoHeaders to forward to the provider. Authorization is set automatically.
options.customer_idstringNoCustomer ID for billing. Must be used with meter_slug.
options.meter_slugstringNoMeter slug for billing. Use with customer_id for customer billing, or alone for meter-only mode.
options.provider_keystringNoOverride the provider key for this request.
options.disable_billingbooleanNoDisable billing for this request.

With Customer Billing

const data = await lava.gateway('https://api.openai.com/v1/chat/completions', {
  body: { model: 'gpt-4o', messages: [{ role: 'user', content: 'Hello!' }] },
  customer_id: 'cus_123',
  meter_slug: 'ai-usage',
});

Meter-Only Mode

Track usage on a meter without billing a specific customer:
const data = await lava.gateway('https://api.openai.com/v1/chat/completions', {
  body: { model: 'gpt-4o', messages: [{ role: 'user', content: 'Hello!' }] },
  meter_slug: 'ai-usage',
});

With Format Translation (Rewrite)

Use format to send requests in one LLM format and have Lava translate to the provider’s native format automatically. The provider format is auto-detected from the target URL.
// Send OpenAI-shaped requests to Anthropic — Lava translates both request and response
const data = await lava.gateway('https://api.anthropic.com/v1/messages', {
  format: 'openai',
  body: {
    model: 'claude-haiku-4-5',
    messages: [{ role: 'user', content: 'Hello!' }],
  },
});
// Response is in OpenAI format, regardless of provider
Supported formats: openai, anthropic, google, bedrock. See Rewrite Proxy for details on format translation.

With Custom Headers

Some providers require additional headers. Pass them via options.headers — the Authorization header is always set to the forward token automatically.
const data = await lava.gateway('https://api.anthropic.com/v1/messages', {
  body: {
    model: 'claude-haiku-4-5',
    max_tokens: 1024,
    messages: [{ role: 'user', content: 'Hello!' }],
  },
  headers: { 'anthropic-version': '2023-06-01' },
});
Pass the raw provider URL to gateway() (e.g., https://api.openai.com/v1/chat/completions), not lava.providers.* URLs. The method constructs the forwarding URL internally.
Passing customer_id without meter_slug will throw an error. Provide both for customer billing, use meter_slug alone for meter-only mode, or omit both for merchant billing.
The gateway() method returns parsed JSON. For streaming responses, use generateForwardToken() with manual fetch() instead.

Authentication

Using Your Secret Key (Simplest)

The simplest way to authenticate is to pass your secret key directly — no forward token needed. Costs are charged to your merchant wallet:
const response = await fetch(lava.providers.openai + '/chat/completions', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${process.env.LAVA_SECRET_KEY}`
  },
  body: JSON.stringify({
    model: 'gpt-4o-mini',
    messages: [{ role: 'user', content: 'Hello!' }]
  })
});
Or use the gateway() method which handles this automatically.

Generating Forward Tokens

When you need customer billing, metering, or BYOK, generate a forward token that bundles your credentials with billing parameters. Meter-only authentication — use this when you want usage tracking on a specific meter without billing a customer:
const forwardToken = lava.generateForwardToken({
  meter_slug: 'my-meter'
});
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'
});
Billing-disabled authentication — proxy requests through a customer’s meter without charging their wallet:
const forwardToken = lava.generateForwardToken({
  customer_id: 'conn_id_from_customer',
  meter_slug: 'my-meter',
  disable_billing: true
});
Unmanaged (bring your own key) authentication — use your own provider API key with Lava for usage tracking only:
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_id, merchant_id, ... }

const lava = new Lava(credentials.secret_key);
Lava.login() loads the active secret key, creating one if needed. 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:
const lava = new Lava('aks_live_...');

const spendKey = await lava.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 lava.spendKeys.rotate(spendKey.spend_key_id);
// rotated.key — new raw key

// Revoke a key
await lava.spendKeys.revoke(spendKey.spend_key_id);

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 lava = new Lava();

const { data: models } = await lava.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();

Gateway Flow Example

A minimal integration for developers using Lava as an AI proxy:
import { Lava } from '@lavapayments/nodejs';

const lava = new Lava();

// 1. Generate a gateway-mode forward token
const forwardToken = lava.generateForwardToken({});

// 2. 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();

// 3. Check usage via the API
const usage = await lava.usage.retrieve({
  start: new Date(Date.now() - 86400000).toISOString(),
});
// usage.totals.total_requests, usage.totals.total_cost
Gateway mode charges costs to your merchant wallet. To bill customers instead, see the Monetization Flow below.

Monetization 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

API Reference

Complete API documentation with all parameters and response types

Forward Proxy

Route AI requests through Lava’s proxy