Skip to content

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.

  1. Install the SDK

    Terminal window
    bun add openai
    # or: npm install openai
  2. 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);
  3. Verify the gateway is reachable

    No auth required — call /health to 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"
    }
  4. Discover available models

    List all models your key can access, optionally filtered by capability type:

    // All models
    const models = await client.models.list();
    for (const model of models.data) {
    console.log(model.id, (model as Record<string, unknown>).bve_category);
    }
    // Only chat models
    const chatModels = await fetch(
    'https://api.bve.me/v1/models?category=chat',
    { headers: { Authorization: 'Bearer sk-bve-YOUR_KEY' } }
    );

    Each model entry includes bve_category (chat, embedding, image, tts, transcription, ocr) and bve_endpoints (the gateway paths that accept the model). Use ?category= or ?endpoint=/v1/chat/completions to narrow the list.

  5. 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);

    The response uses live counters from the quota Durable Object. null limits mean no cap is set for that window. See the Usage Snapshot reference for the full field list.