Skip to content

Migrate from OpenRouter

If your app calls OpenRouter through an OpenAI-compatible client, moving to Belarel is mostly a configuration change. This page lists what carries over as-is, the OpenRouter-specific options Belarel refuses, and the controls you get on the Belarel side.

Replace OpenRouter’s base URL with https://api.belarel.com/v1 and your OpenRouter key with a Belarel key (bel_live_…, or bel_test_… for the sandbox). Keep sending X-Title and HTTP-Referer if you already do: Belarel reads them.

Terminal window
curl https://api.belarel.com/v1/chat/completions \
-H "Authorization: Bearer $BELAREL_API_KEY" \
-H "Content-Type: application/json" \
-H "X-Title: Acme Assistant" \
-H "HTTP-Referer: https://app.acme.example/chat" \
-d '{"model": "<model-id>", "messages": [{"role": "user", "content": "Hello"}], "max_tokens": 64}'
OpenRouter habit On Belarel
X-Title header Recorded as the tag app (up to 200 characters).
HTTP-Referer header Recorded as the tag app_url — the URL’s origin only (https://app.acme.example). A value that is not a URL is ignored.
Catalog fields on /models GET /v1/models returns name, description, context_length, architecture, top_provider, and supported_parameters, plus a belarel block with capabilities and your price. Without a key, it returns the public catalog.
Reading the key’s own limits GET /v1/key — caps, spend today and this month, what remains, and when each window resets.
Reading the credit balance GET /v1/credits — included, consumed, and balance, in credits.
Usage in the response Always included, with no opt-in, plus the cost of the call in belarel.cost.

X-Title and HTTP-Referer are attribution only: they never cause a refusal. An explicit tag with the same name (app or app_url) wins, and if a call already carries 16 tags, these two are dropped rather than refused. See Tags and attribution.

OpenRouter feature Behavior on Belarel
provider routing object (order, allow_fallbacks, sort, ignore…) Refused: 400 unsupported_parameter, param: "provider". Each model id in your catalog has one serving route: you cannot pick or order providers per call.
models fallback array Refused: 400 unsupported_parameter, param: "models". Send one model.
route, transforms, plugins, usage request fields Refused: 400 unsupported_parameter, with param naming the field. Usage is always in the answer, without asking.
Extra sampling fields such as top_k, min_p, top_a, repetition_penalty Refused: 400 unsupported_parameter. temperature, top_p, stop, seed, presence_penalty and frequency_penalty are forwarded.
reasoning request object Refused on Chat Completions (400 unsupported_parameter). Use OpenAI’s reasoning_effort (minimal, low, medium, high) on models that support it. On the Responses API, reasoning.effort is read.
Model variants such as :online, :nitro, :floor The suffix is part of the id. An id that is not in your catalog answers 404 model_not_found.

If you used fallbacks, move the logic into your client: on 503 model_unavailable or 503 service_unavailable, retry with another id from GET /v1/models. On 404 or 403, don’t retry the same model — the answer will not change.

If you used :online, Belarel has an explicit switch: "web_search": true on Chat Completions, or a {"type": "web_search"} tool on Responses. It works on models whose belarel.capabilities.web_search is true and that your organization allows; otherwise the call is refused (403 web_search_not_allowed or 400 web_search_unavailable) rather than answered without search.

  • Caps on every key. Spend per day and per month in USD, requests and tokens per minute, calls in flight, and a ceiling on output tokens. A capped key answers 402 key_cap_exceeded. See Budgets and caps.
  • Sub-keys through the API. A key with the keys:manage scope mints, edits, disables, and revokes its own sub-keys, each with its own caps and tags, never above its parent. See One sub-key per customer.
  • Your organization’s policy, enforced on every call. The models and providers your contract allows, your residency zone, and the models your organization opened to its API keys. A refusal names the rule in belarel.policy.decisions. See Policies and catalog.
  • Zero data retention per key. A key in zero_retention mode only reaches models with a zero-retention agreement and refuses the others with 400 model_not_zdr. See Zero data retention.
  • The cost in every answer. belarel.cost gives USD and credits at your organization’s price, and GET /v1/usage aggregates it by key, model, day, or tag.
  • Required tags. A key can require tags such as customer on every model call, and refuses calls to the model endpoints without them (400 missing_tags). Reading the catalog, usage, credits or requests, and managing keys, never needs them.