Gateway API

A single OpenAI-compatible endpoint that routes to 500+ models across 60+ providers. Drop it in wherever you already use the OpenAI SDK — no other changes required.

Base URL

https://getmegabrain.com/api/gateway

Authentication

All requests must include your API key as a Bearer token in the Authorization header. You can find your key on the Profile page after signing in.

curl https://getmegabrain.com/api/gateway/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "gpt-4o-mini", "messages": [{"role": "user", "content": "Hello"}]}'

Free models can be used without authentication, subject to rate limits.

Chat Completions

Fully compatible with the OpenAI Chat Completions API. Both streaming and non-streaming modes are supported.

POSThttps://getmegabrain.com/api/gateway/chat/completions
POSThttps://getmegabrain.com/api/gateway/v1/chat/completions

Example — non-streaming

curl https://getmegabrain.com/api/gateway/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-3-5-sonnet",
    "messages": [
      {"role": "system", "content": "You are a helpful assistant."},
      {"role": "user", "content": "What is the capital of France?"}
    ]
  }'

Example — streaming

curl https://getmegabrain.com/api/gateway/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-3-5-sonnet",
    "stream": true,
    "messages": [{"role": "user", "content": "Tell me a joke"}]
  }'

Example — OpenAI SDK

import OpenAI from "openai";

const client = new OpenAI({
  apiKey: "YOUR_API_KEY",
  baseURL: "https://getmegabrain.com/api/gateway",
});

const response = await client.chat.completions.create({
  model: "anthropic/claude-3-5-sonnet",
  messages: [{ role: "user", content: "Hello!" }],
});

console.log(response.choices[0].message.content);

Auto Model

Set model to one of the Auto Model IDs to let the Gateway choose the best model for each request.

Model IDDescription
mb-auto/frontierHighest performance, tuned for agentic coding
mb-auto/freeRoutes only to free models

Response

The OpenAI Chat Completions shape, plus provider (the serving upstream), native_finish_reason, and a usage object with cost (USD actually charged), is_byok and cached / reasoning token details. Every reply carries an X-Generation-Id header you can look up at GET /v1/generation?id=. Streams end with exactly one usage chunk and data: [DONE].

Parameters

Every field of the Chat Completions request the gateway accepts, and what it does with it. “Forwarded” fields reach the model unchanged — whether the model honours them is what its supported_parameters in GET /v1/models says.

ParameterTypeRangeHandlingDescription
model *stringHandled by the gatewayCatalogue model id (`GET /models`), e.g. `anthropic/claude-fable-5.1`, `openai/gpt-6-astra`, `mb-auto/frontier`, or a preset reference (`@preset/<slug>`, `<model>@preset/<slug>`). Routing variant suffixes (`:nitro`, `:floor`, `:exacto`, `:batch`, `:online`, `:thinking`, `:extended`) are stripped; `openrouter/auto` resolves to `mb-auto/frontier`.
messages *arrayForwarded to the modelThe conversation, OpenAI Chat Completions shape (`system`, `developer`, `user`, `assistant`, `tool` roles; text, image, file and audio parts).
modelsstring[]up to 8 idsHandled by the gatewayFallback models tried in order after `model` fails upstream with any 4xx/5xx; the reply `model` and the price are those of the model that served. Suppressed by `provider.allow_fallbacks: false`.
presetstringHandled by the gatewayA saved preset (`POST /presets`): `@preset/<slug>` or the bare slug. Also expressible as `model: "@preset/<slug>"` or `model: "<model>@preset/<slug>"`. Request fields override the preset’s; the preset fills the rest (model, parameters, provider, system prompt; tools are unioned).
streamboolean (default false)Handled by the gatewayServer-sent events. A stream ends with exactly one usage chunk and `data: [DONE]`; `: MEGABRAIN PROCESSING` comment lines keep the connection warm.
stream_optionsobjectSet by the gateway`include_usage` is always set to `true`; usage is returned on every stream.
max_tokensinteger≥ 1Forwarded to the modelMaximum completion tokens. Rewritten to `max_completion_tokens` for OpenAI-served models that no longer accept `max_tokens`.
max_completion_tokensinteger≥ 1Forwarded to the modelMaximum completion tokens (OpenAI naming); takes precedence over `max_tokens`.
temperaturenumber0 – 2Forwarded to the modelSampling temperature.
top_pnumber0 – 1Forwarded to the modelNucleus sampling.
top_kinteger≥ 0Forwarded to the modelSample from the K most likely tokens; not every model supports it.
min_pnumber0 – 1Forwarded to the modelMinimum probability relative to the most likely token; not every model supports it.
top_anumber0 – 1Forwarded to the modelTop-A sampling; not every model supports it.
frequency_penaltynumber-2 – 2Forwarded to the modelPenalises tokens by how often they already appeared.
presence_penaltynumber-2 – 2Forwarded to the modelPenalises tokens that already appeared at all.
repetition_penaltynumber0 – 2 (default 1)Forwarded to the modelMultiplicative repetition penalty (1 = none); not every model supports it.
seedintegerForwarded to the modelBest-effort deterministic sampling.
stopstring | string[]up to 4Forwarded to the modelStop sequences.
logit_biasobjectForwarded to the modelToken id → bias (-100 – 100).
logprobsbooleanForwarded to the modelReturn token log probabilities.
top_logprobsinteger0 – 20Forwarded to the modelNumber of top log probabilities per token (needs `logprobs: true`).
response_formatobjectForwarded to the model`{ "type": "text" | "json_object" | "json_schema", "json_schema": { … } }`. Check `structured_outputs` in the model's `supported_parameters` before relying on `json_schema`.
toolsarrayForwarded to the modelFunction tools (`{ "type": "function", "function": { … } }`). Tools with an empty name are removed.
tool_choicestring | objectForwarded to the model`none`, `auto`, `required`, or `{ "type": "function", "function": { "name": … } }`.
parallel_tool_callsbooleanForwarded to the modelAllow several tool calls in one reply.
predictionobjectForwarded to the modelPredicted output (`{ "type": "content", "content": … }`) for models that support it.
modalitiesstring[]Forwarded to the modelRequested output modalities (`text`, `image`, `audio`) for models that support them.
image_configobjectForwarded to the modelImage-output options for image-capable models.
cache_controlobjectForwarded to the modelRequest-level prompt-cache directive for providers that support explicit caching.
reasoningobjectForwarded to the model`{ "effort": "max" | "xhigh" | "high" | "medium" | "low" | "minimal" | "none", "max_tokens": n, "exclude": bool, "enabled": bool }`. Check `reasoning` in the model record for supported efforts.
reasoning_effortstringmax | xhigh | high | medium | low | minimal | noneForwarded to the modelShorthand for `reasoning.effort`.
include_reasoningbooleanForwarded to the modelReturn reasoning content alongside the answer (legacy form of `reasoning.exclude: false`).
providerobjectHandled by the gateway`allow_fallbacks` (false suppresses `models[]` and the routing chain), `data_collection: "deny"` and `zdr: true` are honoured; `order`, `only`, `ignore` apply to BYOK and direct-gateway providers; `require_parameters`, `max_price`, `sort`, `quantizations`, `preferred_*`, `enforce_distillable_text` are accepted and not enforced yet.
routestringAccepted and ignoredDeprecated alias of `provider.sort`; accepted and ignored.
pluginsarrayHandled by the gatewayOpenRouter plugins. `{id: "file-parser", pdf: {engine}}` is honoured: `pdf-text` extracts the text of `file` / `input_file` / `document` PDF attachments at the gateway (free) and sends it as text, `native` sends the PDF to the model; without the plugin, models with native PDF input get the file and every other model gets the text. `mistral-ocr` is not offered (400). Other plugins (`web`, `context-compression`, …) are accepted and ignored.
transformsstring[]Accepted and ignored`["middle-out"]` is recorded on the usage row and not applied.
usageobjectAccepted and ignored`{ "include": true }` is a no-op: usage is always returned.
session_idstring≤ 256 charsHandled by the gatewaySticky-routing / grouping key, recorded on the usage row (aliases: `x-session-id`, `x-kilo-session` headers).
userstring≤ 256 charsRecorded, not forwardedYour end-user id. Stored on the usage row (`GET /generation` → `external_user`) and forwarded to the upstream as sent; when absent the gateway sends its own hashed identity.
metadataobject≤ 16 pairs, 64-char keys, 512-char valuesRecorded, not forwardedFree-form string tags stored on the usage row (`GET /generation` → `metadata`); not sent upstream. 400 when over the limits.
prompt_cache_keystringSet by the gatewayReplaced by a hash of your session id when one is present (per-session prompt caching).
safety_identifierstringSet by the gatewayReplaced by the gateway's hashed identity for the calling account.
service_tierstringAccepted and ignoredAccepted and ignored.
traceobjectAccepted and ignoredAccepted and ignored.
debugobjectAccepted and ignoredAccepted and ignored.
web_search_optionsobjectAccepted and ignoredAccepted and ignored (web search is not offered yet).
prompt_cache_optionsobjectAccepted and ignoredAccepted and ignored.
stop_server_tools_whenobjectAccepted and ignoredAccepted and ignored (no server tools yet).

* required

Embeddings

Generate vector embeddings from text. Compatible with the OpenAI Embeddings API.

POSThttps://getmegabrain.com/api/gateway/embeddings
curl https://getmegabrain.com/api/gateway/embeddings \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "text-embedding-3-small",
    "input": "The quick brown fox"
  }'
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: "YOUR_API_KEY",
  baseURL: "https://getmegabrain.com/api/gateway",
});

const result = await client.embeddings.create({
  model: "text-embedding-3-small",
  input: "The quick brown fox",
});

console.log(result.data[0].embedding);

Audio

Speech to text and text to speech, in OpenAI's shapes, so the OpenAI SDK's audio.transcriptions and audio.speech work against the same base URL. Audio models are their own set, not catalogue models — GET /v1/audio/models lists them. An upload is at most 4 MiB, and both routes need a gateway key: there is no anonymous tier for audio.

POSThttps://getmegabrain.com/api/gateway/audio/transcriptions
POSThttps://getmegabrain.com/api/gateway/audio/speech
GEThttps://getmegabrain.com/api/gateway/audio/models
curl https://getmegabrain.com/api/gateway/audio/transcriptions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F file=@meeting.mp3 \
  -F model=openai/whisper-1
curl https://getmegabrain.com/api/gateway/audio/speech \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -o speech.mp3 \
  -d '{
    "model": "openai/gpt-4o-mini-tts",
    "input": "One API, every model.",
    "voice": "onyx"
  }'

List Models

Retrieve the list of models available through the Gateway. The response follows the OpenAI models format.

GEThttps://getmegabrain.com/api/gateway/models
GEThttps://getmegabrain.com/api/gateway/embedding-models
GEThttps://getmegabrain.com/api/gateway/providers
curl https://getmegabrain.com/api/gateway/models \
  -H "Authorization: Bearer YOUR_API_KEY"
{
  "data": [
    {
      "id": "anthropic/claude-fable-5.1",
      "canonical_slug": "anthropic/claude-fable-5.1",
      "name": "Anthropic: Claude Fable 5.1",
      "context_length": 1000000,
      "architecture": { "modality": "text+image->text", "input_modalities": ["text", "image"], ... },
      "pricing": { "prompt": "0.000005", "completion": "0.000025", ... },
      "supported_parameters": ["max_tokens", "reasoning", "tools", ...],
      "reasoning": { "supported_efforts": ["max", "high", "low"], ... }
    },
    ...
  ],
  "total_count": 445,
  "links": { "next": "/api/gateway/v1/models?offset=100&limit=100" }
}

Filter and page with query parameters: offset, limit (≤ 1000), q, supported_parameters, input_modalities, output_modalities, providers, arch, context, min_price / max_price (USD per million prompt tokens), min_output_price / max_output_price, zdr, max_age_days, min_bench (0–100 Terminal-Bench), sort (newest, pricing-low-to-high, pricing-high-to-low, context-high-to-low, bench-high-to-low). total_count is the size of the filtered set before paging. The public models page offers the same filters as facets and mirrors them into its query string.

Keys, credits, generations

Everything else the gateway serves on the same base URL. Named keys (mb-v1-…) carry their own spend limit and reset window; a management key can create keys and read credits but cannot call inference.

POST/v1/completionsLegacy text completions (prompt → choices[].text), same models and parameters
POST/v1/responsesOpenAI Responses API, same models
POST/v1/messagesAnthropic Messages API (also /api/anthropic/v1 with x-api-key)
GET/v1/models/countCount of the (filtered) catalogue
GET/v1/models/userThe catalogue as your key sees it (401 when anonymous)
GET/v1/generation?id=Receipt for one request: tokens, cost, latency, app, user
POST/v1/generation/feedbackReport feedback on a generation: category + comment
GET/v1/keyThe calling key: label, limits, usage
POST/v1/auth/keysOAuth PKCE: exchange the code from /auth?callback_url&code_challenge for an inference key
GET/v1/creditsBalance and usage (management keys)
GET/v1/keysList named keys (management keys)
POST/v1/keysCreate a named key with a spend limit; plaintext returned once
PATCH/v1/keys/{id}Rename, disable, change limits
DELETE/v1/keys/{id}Revoke
GET/v1/activityDaily usage per model and upstream, last 30 days (management keys)
GET/v1/byokList BYOK credentials (management keys)
POST/v1/byokStore a provider key: provider + key
PATCH/v1/byok/{id}Replace the key, enable / disable
DELETE/v1/byok/{id}Remove a BYOK credential
GET/v1/model/{author}/{slug}One catalogue entry
GET/v1/notificationsLow-balance alert threshold and the channels alerts go to: email, signed webhook, Slack
PATCH/v1/notificationsSet the threshold (USD or null) and / or the channels
GET/v1/notifications/deprecationsRetiring models you used in the last 30 days, with when you were notified
GET/v1/privacyPersonal privacy toggles: data collection, training on paid / free models
PATCH/v1/privacyChange them; models that may train are hidden and refused when off
GET/v1/presetsList presets (management keys)
POST/v1/presetsCreate a preset; use it as model: "@preset/<slug>"
PATCH/v1/presets/{slug}Rename, describe, or publish a new config version
DELETE/v1/presets/{slug}Delete a preset
GET/v1/broadcast/destinationsBroadcast: where generation traces are exported (management keys)
POST/v1/broadcast/destinationsAdd a webhook or OpenTelemetry collector: url, headers, secret, sampling, key filters
PATCH/v1/broadcast/destinations/{id}Change any field
DELETE/v1/broadcast/destinations/{id}Remove a destination
POST/v1/broadcast/destinations/{id}/testSend a synthetic trace now
GET/v1/guardrailsGuardrails: budget + model/provider/privacy policy (management keys)
POST/v1/guardrailsCreate a guardrail: budget, allowed/ignored models and providers, privacy, assignments
PATCH/v1/guardrails/{id}Change any field
DELETE/v1/guardrails/{id}Remove a guardrail
POST/v1/guardrails/{id}/assignmentsCover an account, member or key scope
GET/v1/datasets/rankings-dailyPublic: top models per UTC day by tokens
GET/v1/datasets/app-rankingsPublic: attributed apps by tokens (?model narrows)
GET/v1/datasets/session-costPublic: sessions and spend per session per model
GET/v1/filesFiles API: uploaded files and the storage quota
POST/v1/filesUpload (multipart or JSON file_data, ≤ 4 MiB) or reserve a presigned upload; use the id as file_id in a file part
GET/v1/files/{id}One file
GET/v1/files/{id}/contentIts bytes
POST/v1/files/{id}/completeConfirm a presigned upload
DELETE/v1/files/{id}Delete a file
POST/v1/analytics/queryUsage analytics: metrics × dimensions × granularity, with filters (management keys)
GET/v1/analytics/metaThe analytics metrics, dimensions and limits
curl -X POST https://getmegabrain.com/api/gateway/v1/keys \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "ci-runner", "limit": 25, "limit_reset": "monthly"}'

Errors

Every error, on every endpoint, uses the OpenRouter envelope: error.code equals the HTTP status, error.message is human-readable, error.metadata.error_type is the canonical class (invalid_request, authentication, payment_required, permission_denied, not_found, rate_limit_exceeded, provider_unavailable, …) and error.metadata.megabrain_error_type the precise reason below. Upstream failures also carry provider_code and raw. A failure after a stream has started arrives as a final chunk with an error object and finish_reason: "error".

{
  "error": {
    "code": 402,
    "message": "API key has reached its spend limit",
    "metadata": {
      "error_type": "payment_required",
      "megabrain_error_type": "insufficient_credits",
      "reason": "api_key_over_limit"
    }
  },
  "error_type": "insufficient_credits"
}
Statusmegabrain_error_typeerror_typeWhen
400invalid_requestinvalid_requestMalformed JSON, a missing required field, or a value outside its documented limits (`user`, `metadata`, …).
400api_kind_not_supportedinvalid_requestThe model cannot be served on this API (chat / responses / messages).
400context_length_exceededcontext_length_exceededThe prompt is longer than the model's context window.
400unsupported_fieldinvalid_requestA field is not supported on this endpoint.
400missing_client_ipinvalid_requestThe client IP could not be determined.
401authentication_requiredauthenticationMissing, invalid, disabled or expired API key (`error.metadata.reason` says which), or the wrong key class for the endpoint (403).
401paid_model_auth_requiredauthenticationA paid model needs an API key; only free models are anonymous.
402usage_limit_exceededpayment_requiredThe organization's or account's configured usage limit is reached.
402insufficient_creditspayment_requiredThe account balance, or the API key spend limit, is exhausted.
403upgrade_requiredpermission_deniedThe request needs a plan the account does not have.
403data_collection_requiredpermission_deniedThe model needs data collection the organization has denied.
403model_not_allowedpermission_deniedThe organization's model policy does not allow this model.
403feature_exclusive_modelpermission_deniedThe model is only available to a specific product feature.
403provider_not_allowedpermission_deniedThe `provider` preferences leave no provider the organization's policy allows.
403byok_key_requiredpermission_deniedThis model is only served with your own provider key.
403abuse_blockedpermission_deniedThe request was blocked by abuse prevention rules.
404invalid_pathnot_foundUnknown endpoint on the gateway prefix.
404discontinued_free_modelnot_foundThis free model is no longer served.
404model_not_foundnot_foundNo catalogue model with this id.
404unsupported_fim_modelnot_foundNot a fill-in-the-middle model.
404unsupported_edit_modelnot_foundNot an edit-completions model.
404generation_not_foundnot_foundNo generation with this id for the caller (`GET /generation`).
429rate_limit_exceededrate_limit_exceededFree-model rate limit reached; `error.metadata` carries the window.
429promotion_limit_reachedrate_limit_exceededThe anonymous free-model allowance is used up; sign in to continue.
429mpass_limit_reachedrate_limit_exceededThe subscription's usage window is exhausted; `error.metadata.resets_at` says when.
502byok_errorprovider_unavailableYour own provider key was refused upstream.
502upstream_errorprovider_unavailableThe upstream returned an error; `error.metadata.provider_code` and `raw` carry its status and body. The status mirrors the upstream when it is meaningful (e.g. 429).
503temporarily_unavailableprovider_unavailableThe model or its upstream is unavailable right now; retry with backoff.
503no_free_models_availableprovider_unavailableThe free tier has no model available for this request right now.

OpenAPI

The whole contract — every endpoint, the request and response schemas, the parameter and error references above — is published as an OpenAPI 3.1 document, generated from the same source as this page. Point a client generator or an API explorer at it.

GEThttps://getmegabrain.com/openapi.json
GEThttps://getmegabrain.com/api/gateway/v1/openapi.json

MCP server

The catalogue and this reference are also served over the Model Context Protocol, so an agent can look a model up or read a parameter's range without a browser and without anyone pasting documentation into a prompt. Four read-only tools: search_models, get_model, list_providers and gateway_reference. No key: it answers from the public catalogue and never sees your usage or spend.

POSThttps://getmegabrain.com/api/mcp

Ready to start?

Create a free account and get your API key in 2 minutes.

Get started free