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 combines your merchant credentials with a specific customer connection and pricing configuration.

Token Structure

A forward token encodes four fields into a single credential:
ComponentPurposeObtained From
Secret KeyYour Lava API keyGenerated in merchant dashboard
Connection IDLinks to a customerReturned from checkout completion
Meter SlugSpecifies pricing configurationMeter configuration in dashboard
Provider Key (Optional)Enable BYOK (Bring Your Own Key)Your own provider credentials
Self token vs. customer token: The self forward token from Gateway > Secrets points to an auto-created connection and zero-fee meter that charge your own wallet — use it for development and internal usage. To charge customers, generate tokens with their connection_id and your pricing meter_slug.

Generating a Forward Token

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

const lava = new Lava();

const forwardToken = lava.generateForwardToken({
  connection_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.lavapayments.com/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.lavapayments.com/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 self 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