Quickstart
BVE Gateway is a drop-in replacement for the OpenAI API. Point your SDK’s base URL at https://api.bve.me/v1 and use your sk-bve- key.
-
Install the SDK
Terminal window bun add openai# or: npm install openaiTerminal window pip install openaiNo installation needed —
curlships with macOS and most Linux distributions. -
Make your first request
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: 'user', content: 'Hello!' }],});console.log(response.choices[0].message.content);from openai import OpenAIclient = OpenAI(api_key="sk-bve-YOUR_KEY",base_url="https://api.bve.me/v1",)response = client.chat.completions.create(model="gpt-4o",messages=[{"role": "user", "content": "Hello!"}],)print(response.choices[0].message.content)Terminal window curl https://api.bve.me/v1/chat/completions \-H "Authorization: Bearer sk-bve-YOUR_KEY" \-H "Content-Type: application/json" \-d '{"model": "gpt-4o","messages": [{ "role": "user", "content": "Hello!" }]}' -
Verify the gateway is reachable
No auth required — call
/healthto confirm the gateway is up:Terminal window curl https://api.bve.me/health{"status": "ok","service": "bve-gateway","timestamp": "2026-05-21T12:00:00.000Z","request_id": "550e8400-e29b-41d4-a716-446655440000"} -
Discover available models
List all models your key can access, optionally filtered by capability type:
// All modelsconst models = await client.models.list();for (const model of models.data) {console.log(model.id, (model as Record<string, unknown>).bve_category);}// Only chat modelsconst chatModels = await fetch('https://api.bve.me/v1/models?category=chat',{ headers: { Authorization: 'Bearer sk-bve-YOUR_KEY' } });import httpx# All modelsmodels = client.models.list()for model in models.data:print(model.id)# Only embedding modelsr = httpx.get("https://api.bve.me/v1/models",params={"category": "embedding"},headers={"Authorization": "Bearer sk-bve-YOUR_KEY"},)print(r.json()["data"])Terminal window # All modelscurl https://api.bve.me/v1/models \-H "Authorization: Bearer sk-bve-YOUR_KEY"# Only chat modelscurl "https://api.bve.me/v1/models?category=chat" \-H "Authorization: Bearer sk-bve-YOUR_KEY"Each model entry includes
bve_category(chat,embedding,image,tts,transcription,ocr) andbve_endpoints(the gateway paths that accept the model). Use?category=or?endpoint=/v1/chat/completionsto narrow the list. -
Check your quota
After your first request, verify how much of your rate-limit window is consumed:
const res = await fetch('https://api.bve.me/v1/usage', {headers: { Authorization: 'Bearer sk-bve-YOUR_KEY' },});const usage = await res.json() as {object: string;key_id: string;this_minute: { used: number; limit: number | null; remaining: number | null };today: { used: number; limit: number | null; remaining: number | null };this_month: {requests: { used: number; limit: number | null };tokens: { used: number; limit: number | null };};};console.log('Requests this minute:', usage.this_minute.used);console.log('Requests today:', usage.today.used);import httpxr = httpx.get("https://api.bve.me/v1/usage",headers={"Authorization": "Bearer sk-bve-YOUR_KEY"},)usage = r.json()print("Requests this minute:", usage["this_minute"]["used"])print("Requests today:", usage["today"]["used"])Terminal window curl https://api.bve.me/v1/usage \-H "Authorization: Bearer sk-bve-YOUR_KEY"The response uses live counters from the quota Durable Object.
nulllimits mean no cap is set for that window. See the Usage Snapshot reference for the full field list.