Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content
Route model calls

Connect with the Neon AI Gateway

Neon gives each branch of a project its own AI Gateway. Add the gateway's URL and a Neon token to Mubit as a provider key, and Mubit sends your project's calls on the OpenAI, Anthropic and Gemini prefixes to that gateway, unless the project has its own key for that provider. Your app keeps Mubit's base URL for the provider and your Mubit key.

ℹ️Note

The Neon AI Gateway is offered in the workspaces on app.mubit.ai, for every organization there. It isn't offered in other workspaces yet. If Neon AI Gateway isn't in the Provider menu under Provider keys, your workspace doesn't offer it.

Before you start

  • Your Neon branch's Gateway URL and a Neon token. Provider keys shows where to find both.
  • A Neon AI Gateway key in your project. An admin of your organization adds it under Provider keys, as Add a Neon key shows.
  • A Mubit key for your project. To create one, follow step 1 of the Quickstart.

Which calls go to Neon

A call goes to Neon when it is on the OpenAI, Anthropic or Gemini prefix, and your project has a Neon key but no key of its own for that prefix's provider. Neon has no prefix in Mubit: your app uses the same base URLs as without Neon.

For each call, Mubit uses the first of these that applies:

  1. Your key for the provider. A call on /anthropic uses your Anthropic key, a call on /openai/v1 your OpenAI key, and a call on /gemini your Gemini key.
  2. Your Neon AI Gateway key. Mubit sends the call to your branch's gateway.

With none of these, the call gets 403 provider_key_missing.

  • Your own key always comes first. With an OpenAI key and a Neon key, your OpenAI calls go to OpenAI. Delete the OpenAI key to send them to Neon.
  • OpenAI-compatible services never go to Neon. A call under /compat/{service}/v1 uses the service's own key. Neon is not one of the services: see OpenAI-compatible services.
  • A project takes one Neon key, so its calls go to one branch's gateway.

The order holds for every client that calls these prefixes, such as the tools in Coding tools and the libraries in Frameworks.

Where Neon receives the call

Mubit sends the call to the Gateway URL saved with your key. It adds Neon's path for that API, then the rest of your call's path:

Your callMubit sends it to your gateway at
POST /openai/v1/chat/completions, POST /openai/v1/embeddings, GET /openai/v1/models/v1/…
POST /openai/v1/responses/openai/v1/responses
POST /anthropic/v1/messages/anthropic/v1/messages
POST /gemini/v1beta/models/{model}:generateContent/gemini/v1beta/models/{model}:generateContent

Neon's documentation says which of its models each path serves. It says most of its models, Claude and Gemini models included, work on Chat Completions, so the OpenAI prefix reaches the most models.

Send a call

The code is the code on the OpenAI, Anthropic and Gemini pages: Mubit's base URL for the provider, and your Mubit key. Install the SDKs as those pages show. These examples assume your project has no key of its own for the provider.

Only the model changes. Use a model ID from Neon's list, and replace MODEL_ID in the examples with it. To list the IDs your gateway serves, call GET /openai/v1/models. With a Neon key and no OpenAI key, the answer is Neon's list:

curl https://api.mubit.ai/openai/v1/models \
  -H "Authorization: Bearer $MUBIT_API_KEY"

OpenAI

Python
import os
from openai import OpenAI
 
client = OpenAI(
    base_url="https://api.mubit.ai/openai/v1",
    api_key=os.environ["MUBIT_API_KEY"],
)
 
instructions = (
    "Sort the support message into one category: "
    "billing, bug, account or other. Reply with the category only."
)
 
response = client.chat.completions.create(
    model="MODEL_ID",
    messages=[
        {"role": "system", "content": instructions},
        {"role": "user", "content": "I was charged twice for my October invoice."},
    ],
)
print(response.choices[0].message.content)

Anthropic

Python
import os
from anthropic import Anthropic
 
client = Anthropic(
    base_url="https://api.mubit.ai/anthropic",  # no /v1
    api_key=os.environ["MUBIT_API_KEY"],
)
 
instructions = (
    "Sort the support message into one category: "
    "billing, bug, account or other. Reply with the category only."
)
 
message = client.messages.create(
    model="MODEL_ID",
    max_tokens=64,
    system=instructions,
    messages=[
        {"role": "user", "content": "I was charged twice for my October invoice."},
    ],
)
print(message.content[0].text)

Gemini

Python
import os
from google import genai
from google.genai import types
 
client = genai.Client(
    api_key=os.environ["MUBIT_API_KEY"],
    http_options=types.HttpOptions(
        base_url="https://api.mubit.ai/gemini",  # no /v1beta
    ),
)
 
instructions = (
    "Sort the support message into one category: "
    "billing, bug, account or other. Reply with the category only."
)
 
response = client.models.generate_content(
    model="MODEL_ID",
    contents="I was charged twice for my October invoice.",
    config=types.GenerateContentConfig(system_instruction=instructions),
)
print(response.text)

The TypeScript examples use top-level await, so run them as ES modules: save the file with an .mts name, such as neon.mts, and run npx tsx neon.mts, or add "type": "module" to your package.json.

To stream an answer, set the options the provider's page shows: OpenAI, Anthropic or Gemini. Mubit streams Neon's answer back to your app as it arrives.

Neon's documentation lists generateContent and streamGenerateContent for its Gemini path. Another Gemini call, such as countTokens, gets an error from Neon. To call a Gemini model with the OpenAI SDK, use the OpenAI base URL and a Gemini model ID from Neon's list.

What Mubit sends to Neon

  • Where: only to the Gateway URL saved with your key, over HTTPS, and only while that URL is under Neon's gateway domain, which is aws.neon.tech today. Mubit checks the URL again before each call. A URL it doesn't send keys to gets 403 provider_region_unavailable. Mubit connects to public addresses only and follows no redirect: a redirect from Neon gets 502 upstream_redirect.
  • The token: your Neon token goes in the Authorization: Bearer header, whichever API the call uses. Mubit takes out your Mubit key and the credentials an SDK sends for its own key: authorization, x-api-key, x-goog-api-key and key= in the query.
  • Other headers: headers such as anthropic-version and anthropic-beta go on as you sent them. Cookies, x-middleware-store and x-middleware-record don't.
  • The answer: Neon's answer comes back as Neon sent it, with its retry-after and x-ratelimit-* headers. Mubit passes Neon's errors back too.
  • Recording: Mubit records a call to Neon as it records any call, and you lower it with the same headers: see What Mubit records.
  • Adapters: a recorded call can become an example an adapter trains on. A Chat Completions call on /openai/v1 can be answered by an adapter in place of Neon: see Calls answered by an adapter.

See the call in Requests

A call that goes to Neon shows in Requests like any other call. See Find calls in Requests.

If a call fails

The error names its code. Troubleshooting lists the codes and what to do. Each answer carries the call's ID in the x-middleware-request-id header: see Find a call's request ID.

  • 403 provider_region_unavailable: the URL saved with your Neon key isn't one Mubit sends keys to. An admin deletes the key and adds it again under Provider keys.
  • An error from Neon: an error without the type middleware_gateway_error came from Neon, as Neon sent it. Its message says why, and Neon's documentation lists its codes. A 401 or 403 usually means Neon refused the token: an admin rotates the key under Provider keys.

Next