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 and a forward token. See Quickstart: Make Your First Request to get started.

Forward Tokens

Lava AI Gateway uses a forward token system for authenticating API requests. A forward token is a base64-encoded JSON string that contains your secret key and, optionally, a customer ID and pricing configuration.

Token Structure

A forward token encodes up to four fields into a single credential:
ComponentPurposeObtained From
Secret KeyYour Lava API keyGenerated in merchant dashboard
Customer ID (Optional)Links to a customerReturned from checkout completion
Meter Slug (Optional)Specifies pricing configurationMeter configuration in dashboard
Provider Key (Optional)Enable unmanaged (bring your own key)Your own provider credentials; Lava still meters usage
Only secret_key is required. When you omit customer_id and meter_slug, costs are charged directly to your merchant wallet — this is the simplest way to get started. To charge customers, generate tokens with their customer_id and your pricing meter_slug.

Generating a Forward Token

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

const lava = new Lava();

const forwardToken = lava.generateForwardToken({
  customer_id: 'conn_xyz789',
  meter_slug: 'my-meter'
});

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 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, ensure the Bearer prefix is in the Authorization header, and try the forward token from Gateway > Secrets to isolate the issue.
# Decode a forward token to inspect its contents
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