Skip to content

SDK Usage

BVE Gateway supports multiple official SDKs. Each requires only a baseURL override to point at api.bve.me — no provider-specific API key is needed. The one difference is the Anthropic SDK: use https://api.bve.me (without /v1) because the SDK appends /v1/messages automatically.

SDK / ProviderAuth header sentbaseURL to set
OpenAI TypeScript/PythonAuthorization: Bearerhttps://api.bve.me/v1
Anthropic TypeScript/Pythonx-api-keyhttps://api.bve.me
Groq TypeScript/PythonAuthorization: Bearerhttps://api.bve.me/v1
Cohere models (use OpenAI SDK)Authorization: Bearerhttps://api.bve.me/v1
Gemini models (use OpenAI SDK)Authorization: Bearerhttps://api.bve.me/v1
Mistral / Llama models (use OpenAI SDK)Authorization: Bearerhttps://api.bve.me/v1

Install:

Terminal window
bun add openai
# or: npm install openai
import OpenAI from 'openai';
const client = new OpenAI({
apiKey: 'sk-bve-YOUR_KEY',
baseURL: 'https://api.bve.me/v1',
});
const response = await client.chat.completions.create({
model: 'gpt-4o',
messages: [
{ role: 'system', content: 'You are a helpful assistant.' },
{ role: 'user', content: 'What is 2 + 2?' },
],
});
console.log(response.choices[0].message.content);
const stream = await client.chat.completions.stream({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Count from 1 to 5.' }],
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
}
const response = await client.embeddings.create({
model: 'text-embedding-3-small',
input: 'The quick brown fox',
});
console.log(response.data[0].embedding);
const models = await client.models.list();
for (const model of models.data) {
console.log(model.id);
}
try {
const response = await client.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Hello' }],
});
} catch (err) {
if (err instanceof OpenAI.APIError) {
console.error(err.status, err.message);
// err.error?.code for the machine-readable code (e.g. 'rate_limit_exceeded')
}
}

Use tools and tool_choice to let the model invoke functions:

const tools: OpenAI.ChatCompletionTool[] = [
{
type: 'function',
function: {
name: 'get_weather',
description: 'Get the current weather for a city',
parameters: {
type: 'object',
properties: {
city: { type: 'string', description: 'City name' },
},
required: ['city'],
},
},
},
];
const response = await client.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: "What's the weather in Tokyo?" }],
tools,
tool_choice: 'auto',
});
const choice = response.choices[0];
if (choice.finish_reason === 'tool_calls') {
const call = choice.message.tool_calls![0];
const args = JSON.parse(call.function.arguments);
console.log('Function to call:', call.function.name, 'Args:', args);
// { city: 'Tokyo' }
}

Force the model to return valid JSON using response_format:

// JSON object mode
const response = await client.chat.completions.create({
model: 'gpt-4o',
messages: [
{
role: 'user',
content: 'Return the capitals of France, Germany, and Japan as JSON.',
},
],
response_format: { type: 'json_object' },
});
const data = JSON.parse(response.choices[0].message.content!);
console.log(data);
// { france: 'Paris', germany: 'Berlin', japan: 'Tokyo' }

For strict schema validation, use json_schema:

const response = await client.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'What is 2 + 2? Return as JSON.' }],
response_format: {
type: 'json_schema',
json_schema: {
name: 'math_result',
strict: true,
schema: {
type: 'object',
properties: { answer: { type: 'integer' } },
required: ['answer'],
additionalProperties: false,
},
},
},
});
const result = JSON.parse(response.choices[0].message.content!);
console.log(result.answer); // 4

When a rate limit is hit, use the Retry-After header to wait before retrying:

import OpenAI from 'openai';
const client = new OpenAI({
apiKey: process.env.BVE_API_KEY,
baseURL: 'https://api.bve.me/v1',
maxRetries: 0, // disable SDK auto-retry; handle manually
});
async function chatWithRetry(
model: string,
messages: OpenAI.ChatCompletionMessageParam[],
maxAttempts = 3,
) {
for (let attempt = 0; attempt < maxAttempts; attempt++) {
try {
return await client.chat.completions.create({ model, messages });
} catch (err) {
if (err instanceof OpenAI.RateLimitError && attempt < maxAttempts - 1) {
const retryAfter = Number(err.headers?.['retry-after'] ?? 5);
console.warn(`Rate limited. Retrying in ${retryAfter}s…`);
await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
continue;
}
throw err;
}
}
}

Avoid hardcoding keys. Use environment variables:

const client = new OpenAI({
apiKey: process.env.BVE_API_KEY,
baseURL: 'https://api.bve.me/v1',
});

BVE Gateway accepts the x-api-key header that the Anthropic SDK sends by default. Set baseURL to https://api.bve.me — the SDK appends /v1/messages automatically.

Install:

Terminal window
bun add @anthropic-ai/sdk
# or: npm install @anthropic-ai/sdk
import Anthropic from '@anthropic-ai/sdk';
const client = new Anthropic({
apiKey: 'sk-bve-YOUR_KEY', // sent as x-api-key, accepted by BVE Gateway
baseURL: 'https://api.bve.me',
});
const message = await client.messages.create({
model: 'claude-sonnet-4-6',
max_tokens: 1024,
messages: [
{ role: 'user', content: 'Explain quantum entanglement in one paragraph.' },
],
});
console.log(message.content[0].text);
const stream = await client.messages.stream({
model: 'claude-sonnet-4-6',
max_tokens: 512,
messages: [{ role: 'user', content: 'Write a haiku about autumn.' }],
});
for await (const event of stream) {
if (event.type === 'content_block_delta' && event.delta.type === 'text_delta') {
process.stdout.write(event.delta.text);
}
}

The Groq SDK is OpenAI-compatible and sends Authorization: Bearer headers. Set baseURL to https://api.bve.me/v1.

Install:

Terminal window
bun add groq-sdk
# or: npm install groq-sdk
import Groq from 'groq-sdk';
const client = new Groq({
apiKey: 'sk-bve-YOUR_KEY',
baseURL: 'https://api.bve.me/v1',
});
const response = await client.chat.completions.create({
model: 'llama-4-maverick-17b-128e',
messages: [
{ role: 'user', content: 'What is the capital of France?' },
],
});
console.log(response.choices[0].message.content);
const stream = await client.chat.completions.create({
model: 'llama-4-maverick-17b-128e',
messages: [{ role: 'user', content: 'List 5 programming languages.' }],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
}

Cohere’s command-r family is accessible via the OpenAI SDK — just swap in the Cohere model ID. No Cohere SDK or Cohere API key is needed; your BVE Gateway key handles authentication.

Supported Cohere model IDs:

ModelID
Command A (Mar 2025)command-a-03-2025
Command R+command-r-plus
Command R+ (Aug 2024)command-r-plus-08-2024
Command Rcommand-r
Command R (Aug 2024)command-r-08-2024
Command R7B (Dec 2024)command-r7b-12-2024
import OpenAI from 'openai';
const client = new OpenAI({
apiKey: 'sk-bve-YOUR_KEY',
baseURL: 'https://api.bve.me/v1',
});
const response = await client.chat.completions.create({
model: 'command-r-plus',
messages: [
{ role: 'system', content: 'You are a helpful assistant.' },
{ role: 'user', content: 'Summarize the water cycle in two sentences.' },
],
});
console.log(response.choices[0].message.content);
const stream = await client.chat.completions.stream({
model: 'command-r7b-12-2024',
messages: [{ role: 'user', content: 'List 3 fun facts about penguins.' }],
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
}

Google’s Gemini models are accessible via the OpenAI SDK — use the model ID directly. No Google SDK or Google API key is needed; your BVE Gateway key handles authentication.

Supported Gemini models available via BVE Gateway (select examples — see Models for the full list):

ModelID
Gemini 2.5 Flashgemini-2.5-flash
Gemini 2.5 Progemini-2.5-pro
Gemini 3 Flashgemini-3-flash
Gemini 3.1 Progemini-3.1-pro
Gemini 3.5 Flashgemini-3.5-flash
import OpenAI from 'openai';
const client = new OpenAI({
apiKey: 'sk-bve-YOUR_KEY',
baseURL: 'https://api.bve.me/v1',
});
const response = await client.chat.completions.create({
model: 'gemini-2.5-flash',
messages: [
{ role: 'user', content: 'Explain the Transformer architecture in one paragraph.' },
],
});
console.log(response.choices[0].message.content);
const stream = await client.chat.completions.stream({
model: 'gemini-2.5-flash',
messages: [{ role: 'user', content: 'Write a short poem about the moon.' }],
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
}

Mistral and Meta’s Llama models are accessible via the OpenAI SDK with no additional SDK or provider key. Use their model IDs directly with the same client setup.

ProviderModelID
MistralMistral Largemistral-large-24.02
MistralMixtral 8x7Bmixtral-8x7b-32768
Meta (via Groq)Llama 4 Maverickllama-4-maverick-17b-128e
Meta (via Groq)Llama 4 Scoutllama-4-scout-17b-16e
Meta (via Groq)Llama 3.3 70Bllama-3.3-70b-versatile
Meta (via Groq)Llama 3.1 70Bllama-3.1-70b-versatile
import OpenAI from 'openai';
const client = new OpenAI({
apiKey: 'sk-bve-YOUR_KEY',
baseURL: 'https://api.bve.me/v1',
});
// Mistral
const mistralResponse = await client.chat.completions.create({
model: 'mistral-large-24.02',
messages: [{ role: 'user', content: 'What is mixture-of-experts architecture?' }],
});
console.log(mistralResponse.choices[0].message.content);
// Llama
const llamaResponse = await client.chat.completions.create({
model: 'llama-4-maverick-17b-128e',
messages: [{ role: 'user', content: 'Describe attention mechanisms in LLMs.' }],
});
console.log(llamaResponse.choices[0].message.content);