Skip to main content
This page covers how to authenticate with Lava, construct proxy URLs, and handle responses and errors.
Prerequisites: You need a Lava merchant account with a secret key. See Quickstart: Make Your First Request to get started.

Authentication

Lava supports two ways to authenticate gateway requests:
MethodWhen to useAuth header
Secret keyGateway access without customer billingBearer aks_live_...
Forward tokenCustomer billing, metering, or BYOKBearer <base64-encoded JSON>

Using Your Secret Key (Simplest)

Pass your secret key directly in the Authorization header. Costs are charged to your merchant wallet — no token generation needed.
curl -X POST 'https://api.lava.so/v1/forward?u=https%3A%2F%2Fapi.openai.com%2Fv1%2Fchat%2Fcompletions' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $LAVA_SECRET_KEY" \
  -d '{"model": "gpt-4o-mini", "messages": [{"role": "user", "content": "Hello!"}]}'
This is all you need to route requests through the gateway with usage tracking and cost logging.

Forward Tokens

When you need to bill customers, apply metering, or use your own provider keys, use a forward token — a base64-encoded JSON that bundles your secret key with billing parameters.

Token Combinations

The fields you include determine how the request is authenticated and billed:
CombinationModeWho pays
secret_key onlyGatewayMerchant
secret_key + meter_slugMeter-onlyMerchant (usage tracked on meter)
secret_key + customer_id + meter_slugCustomer billingCustomer
secret_key + customer_id + meter_slug + disable_billingBilling disabledMerchant (customer still tracked)
Any combination can include provider_key to use your own provider credentials (BYOK) instead of Lava’s managed keys. disable_billing is only meaningful together with customer_id and meter_slug — it preserves full customer context while redirecting charges to your merchant wallet. Use it for free trials, testing, or promotional requests. See Meter-Only Mode & Disable Billing for details.

Customer Billing Mode

To bill a customer’s wallet, include their customer_id and your pricing meter_slug in the token:
import { Lava } from '@lavapayments/nodejs';

const lava = new Lava();

const forwardToken = lava.generateForwardToken({
  customer_id: 'conn_xyz789',    // optional — charges this customer's plan
  meter_slug: 'my-meter',        // optional — prices usage with this meter
  provider_key: 'sk-your-key',   // optional — uses your own provider key (BYOK)
  disable_billing: false,        // optional — when true, tracks usage without charging
});

Constructing the Request URL

Lava routes requests by wrapping the provider’s API endpoint (e.g., OpenAI’s chat completions URL) as a query parameter using Lava’s forward endpoint:
https://api.lava.so/v1/forward?u=<PROVIDER_URL>
See Supported Providers for the full list of providers you can access with Lava AI Gateway.
As a best practice, the provider URL should be URL-encoded.

Provider Examples

The pattern is the same for every provider — only the URL, body format, and provider-specific headers change.
const response = await fetch(
  'https://api.lava.so/v1/forward?u=' +
    encodeURIComponent('https://api.openai.com/v1/chat/completions'),
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${forwardToken}`
    },
    body: JSON.stringify({
      model: 'gpt-4o-mini',
      messages: [{ role: 'user', content: 'Hello!' }]
    })
  }
);

const data = await response.json();
const requestId = response.headers.get('x-lava-request-id');
Provider-specific headers (like anthropic-version) are passed through unchanged. The request body uses the provider’s native format — Lava doesn’t modify it.

Streaming

Add "stream": true to your request body. Lava proxies SSE chunks in real-time without buffering — the response is identical to calling the provider directly. Usage and billing are recorded after the stream completes.
body: JSON.stringify({
  model: 'gpt-4o-mini',
  messages: [{ role: 'user', content: 'Hello!' }],
  stream: true  // That's it — everything else stays the same
})

Error Handling

StatusCauseRetryable
401Invalid secret key or malformed forward tokenNo — check credentials
402Insufficient credit balanceNo — add funds first
429Rate limit exceededYes — back off and retry
500/502/503Provider or Lava server errorYes — retry with backoff
Provider error responses are forwarded unchanged — check your request body against the provider’s API docs if you see provider-level errors.

Troubleshooting

Verify your secret key matches the dashboard and the Bearer prefix is in the Authorization header. If using a forward token, decode it to inspect:
echo "your_forward_token" | base64 -d
Lava blocks frontend requests to prevent token exposure. Always call Lava from your backend: Frontend → Your Backend → Lava → AI Provider.

Next Steps

Supported Providers

Full list of providers you can access with Lava AI Gateway

Webhooks

Receive real-time notifications for billing and usage events