Skip to content

Quickstart

This guide takes you from no key to a streamed answer. You start with a sandbox key, so nothing is billed while you wire things up, then switch to a live key by changing one environment variable.

  1. Keys are created by an owner or administrator of your organization, in the organization dashboard under Governance → API keys. Select New key, give it a name, and set Mode to Sandbox. The token starts with bel_test_.

    The token is shown once. Copy it and store it as an environment variable:

    Terminal window
    export BELAREL_API_KEY="bel_test_..."
  2. First, list the models your key may call. Pick an id from the answer:

    Terminal window
    curl https://api.belarel.com/v1/models \
    -H "Authorization: Bearer $BELAREL_API_KEY"

    Then send a chat completion. The examples use openai/gpt-5.4-mini; replace it with an id from your own list.

    Terminal window
    curl https://api.belarel.com/v1/chat/completions \
    -H "Authorization: Bearer $BELAREL_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
    "model": "openai/gpt-5.4-mini",
    "messages": [{ "role": "user", "content": "Say hello in one word." }],
    "max_tokens": 64
    }'
  3. A sandbox key never reaches a real model: the answer echoes your last message after a [sandbox] marker, and the cost is zero. Everything else has the shape a live answer has:

    {
    "id": "chatcmpl-3b2f9c1e-7a4d-4f0e-9a51-0c6d2e8b4f17",
    "object": "chat.completion",
    "created": 1759400000,
    "model": "openai/gpt-5.4-mini",
    "choices": [
    {
    "index": 0,
    "message": { "role": "assistant", "content": "[sandbox] Say hello in one word." },
    "finish_reason": "stop"
    }
    ],
    "usage": {
    "prompt_tokens": 20,
    "completion_tokens": 8,
    "total_tokens": 28,
    "prompt_tokens_details": { "cached_tokens": 0 },
    "completion_tokens_details": { "reasoning_tokens": 0 }
    },
    "belarel": {
    "request_id": "req_8c0e4b7a2f9d41c6b3e05a7d9f2c1e84",
    "model_requested": "openai/gpt-5.4-mini",
    "model_served": "openai/gpt-5.4-mini",
    "cost": { "usd": 0, "credits": 0, "source": "estimated", "billing": "sandbox" },
    "policy": {
    "decisions": [{ "rule": "org_api_catalog", "verdict": "allow", "detail": "residency any" }]
    },
    "data_mode": "standard"
    }
    }

    What to look at:

    • usage — tokens in the OpenAI shape, with cached and reasoning tokens broken out.
    • belarel.request_id — the same value as the X-Request-Id response header. Log it: it is what you look up with GET /v1/requests/{id} and what support asks for.
    • choices[0].finish_reason — why the model stopped: stop, length when max_tokens cut the reply short, content_filter, or tool_calls.
    • belarel.model_served — the model that actually ran the call.
    • belarel.cost — usd at your organization’s price, credits, where the figure comes from (source), and how it is billed (billing: platform, byok or sandbox).
    • belarel.policy.decisions — the rules that let the call through.
    • belarel.data_mode — how the content of the call was handled.
    • belarel.ignored_parameters — present only when the model’s provider ignored a parameter you sent, such as seed.
  4. Set stream: true to receive server-sent events. The stream ends with one extra chunk that has an empty choices array and carries usage and belarel, then data: [DONE]. You get it on every stream, without asking for it.

    Terminal window
    curl -N https://api.belarel.com/v1/chat/completions \
    -H "Authorization: Bearer $BELAREL_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
    "model": "openai/gpt-5.4-mini",
    "messages": [{ "role": "user", "content": "Count to three." }],
    "stream": true
    }'
  5. When your integration works in the sandbox, create a second key with Mode set to Live (prefix bel_live_) and swap the environment variable. Your code does not change.

    Terminal window
    export BELAREL_API_KEY="bel_live_..."

    What changes with a live key:

    • The call reaches the real model and is billed from your organization’s credits.
    • The key’s spend caps and your organization’s budgets and contract ceilings apply.
    • belarel.cost carries the real figure. If it is not known when the answer is sent, cost.source is pending, and GET /v1/requests/{id} gives the settled figure later.