On this page

On this page

Providers

Neon AI Gateway

Neon AI Gateway is an OpenAI-compatible inference gateway provided by Neon. One Neon credential reaches models from OpenAI, Anthropic, Google, Meta, Databricks and Alibaba, so OpenClaw talks to it over the same openai-completions transport used for other proxy providers.

Each Neon branch has its own gateway host, so requests are scoped to the branch you point at, the same isolation your Neon database already has.

Property Value
Provider id neon (custom; configure under models.providers.neon)
Plugin none; not a bundled OpenClaw provider plugin
Auth Neon credential with the ai_gateway:invoke scope, sent as a bearer token
API openai-completions, plus openai-responses and anthropic-messages for specific models
Base URL $NEON_AI_GATEWAY_BASE_URL/v1, /openai/v1 for Responses or /anthropic for Anthropic Messages

Quick start

  • Create a credential

    In the Neon Console, select your branch and click Credentials under APP BACKEND. Click Create credential and check ai_gateway:invoke. The token starts with nt_live_, and Neon shows it only once.

    With the neon CLI, neon env pull --file .env writes the credential and the branch host for the current branch instead.

  • Find the branch host

    The Neon Console shows it on the AI Gateway page as NEON_AI_GATEWAY_BASE_URL:

    bash
    export NEON_AI_GATEWAY_BASE_URL="https://<your-neon-branch-host>"export NEON_AI_GATEWAY_TOKEN="example-neon-gateway-token-not-real"

    This is not the database connection string. <your-neon-branch-host> is a placeholder: paste the bare host from the Console in its place, with no path after it.

  • Add the provider to your config

    Copy the Configuration block below and swap <your-neon-branch-host> for the bare host from NEON_AI_GATEWAY_BASE_URL, keeping the /v1 suffix. The placeholder is not a real endpoint, so the config fails until you replace it. Do this before selecting a model.

  • Select a model

    bash
    openclaw models set neon/gpt-5-miniopenclaw models list --provider neon

    Because you added the models.providers.neon entry in the previous step, openclaw models set recognizes the provider and saves the selection. If you run it before adding that entry or you misspell the provider, it fails with Unknown model provider "neon" and leaves your config unchanged. A model ID the local catalog does not know still saves under a configured provider, with a warning to check the ID, so confirm the result with openclaw models list --provider neon.

  • Configuration

    json5
    {  models: {    providers: {      neon: {        baseUrl: "https://<your-neon-branch-host>/v1",        apiKey: "${NEON_AI_GATEWAY_TOKEN}",        api: "openai-completions",        models: [          {            id: "gpt-5-mini",            name: "GPT-5 Mini",            reasoning: true,            input: ["text", "image"],            cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },            contextWindow: 400000,          },          {            id: "gemini-3-flash",            name: "Gemini 3 Flash",            reasoning: true,            input: ["text", "image"],            cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },            contextWindow: 1000000,          },          {            id: "qwen3-next-80b-a3b-instruct",            name: "Qwen3-Next 80B Instruct",            reasoning: false,            input: ["text"],            cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },            contextWindow: 131000,          },        ],      },    },  },  agents: {    defaults: {      model: { primary: "neon/gpt-5-mini" },    },  },}

    baseUrl is the bare host from NEON_AI_GATEWAY_BASE_URL with /v1 on the end, so replace <your-neon-branch-host> before loading the config. The /v1 suffix is required because OpenClaw hands the URL to the OpenAI client, which appends chat/completions. Neon serves the same endpoint at the longer /ai-gateway/mlflow/v1 path, and Neon documents that both forms behave identically and neither is deprecated, with the longer /ai-gateway/... paths guaranteed to keep working indefinitely (see Shorter paths).

    Because a Neon branch host is a public HTTPS endpoint, you do not need a private-network override.

    Cost and output limits

    Set cost from the Neon model catalog. Neon charges the model provider's published per-token rate with no markup, billed from prepaid credits. The catalog rates for the three models above are $0.25 and $2.00 per million tokens for gpt-5-mini, $0.50 and $3.00 for gemini-3-flash and $0.15 and $1.20 for qwen3-next-80b-a3b-instruct. OpenClaw reads cost in USD per million tokens, so those numbers drop in as written.

    None of the model entries set maxTokens, which means OpenClaw applies its own default of 8192 output tokens, capped at the model's contextWindow. Neon's catalog publishes context windows but no per-model output ceiling, so there is no upstream number to copy here. Set maxTokens yourself if you want longer completions. The 20,000 output tokens per minute that Neon documents is a rate limit, not a per-request cap.

    The input array accepts text, image, video and audio. Neon's catalog lists more input types than that for some models, including PDF for gpt-5-3-codex and video and audio for Gemini, but only the four values above are valid in an OpenClaw model entry.

    OpenClaw does not ask Neon for streamed token usage

    OpenClaw resolves supportsUsageInStreaming to false for this Neon route, so it does not send stream_options to Neon. A Neon branch host is a custom baseUrl that OpenClaw does not recognize as one of its built-in endpoints, and for an unregistered endpoint like that the derived default is false. That applies to every model above, and no compat block is needed to get it.

    This is the default for the Neon route specifically, not a rule about every provider that sets a baseUrl: endpoints OpenClaw does classify can derive the opposite value, and an explicit compat.supportsUsageInStreaming on a model always overrides the derived default.

    This is a statement about the outgoing request, not about what you will see. OpenClaw still records a usage object on any chunk that carries one, so a provider that reports usage without being asked is accounted for normally. In practice, not asking usually means no final usage arrives, and a streamed turn is then reported at zero tokens.

    Enable compat: { supportsUsageInStreaming: true } only after verifying that the selected model accepts stream_options and returns usage. Keep this override per model: support can differ between the upstream providers that Neon routes to.

    Models

    Neon uses short model IDs with no vendor prefix, such as gpt-5-mini, gemini-3-flash, llama-4-maverick, gpt-oss-120b and qwen3-next-80b-a3b-instruct. The databricks- prefixed form is accepted too. To list what a branch can actually reach:

    bash
    curl "$NEON_AI_GATEWAY_BASE_URL/v1/models" \  -H "Authorization: Bearer $NEON_AI_GATEWAY_TOKEN"

    Neon returns that list in an OpenRouter-shaped response, but pricing, context_length and per_request_limits are currently always null, so take contextWindow values from the Neon model catalog. The same catalog is browsable on models.dev.

    Neon's model access documentation states that paid projects with prepaid credits can use the catalog. Check the enabled field in your branch's response before selecting a model; contact Neon support if access is unexpectedly disabled.

    Advanced

    Branch-scoped credentials

    A credential is valid on the branch it was created on and on every branch descended from it, so one credential created on main covers preview and feature branches forked from main. It is not valid on a branch outside that lineage, where the gateway returns credential not authorized for this branch with a 403.

    To rotate, create the new credential first, update the environment, then revoke the old one.

    Models that require the Responses API

    Neon exposes the OpenAI Responses API under /openai/v1 rather than /v1. Most OpenAI models answer on both endpoints, but a few are served only through Responses and are rejected by chat completions. Check Neon's endpoint guide and Responses model list before choosing a model. Models that require Responses need the configuration below.

    Reach them with a second provider entry using the openai-responses API and that base URL, which is the same branch host you substituted above with /openai/v1 on the end:

    json5
    {  models: {    providers: {      "neon-responses": {        baseUrl: "https://<your-neon-branch-host>/openai/v1",        apiKey: "${NEON_AI_GATEWAY_TOKEN}",        api: "openai-responses",        models: [          {            id: "gpt-5-3-codex",            name: "GPT-5.3 Codex",            reasoning: true,            input: ["text", "image"],            cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },            contextWindow: 400000,          },        ],      },    },  },}

    This endpoint takes OpenAI model IDs only. Sending a Gemini, Llama or Qwen ID returns 400 model "<model-id>" is not available on the openai_responses endpoint.

    Claude models through the Anthropic Messages endpoint

    Neon also exposes the Anthropic Messages API under /anthropic, where the Anthropic SDK appends /v1/messages. This dialect is Claude only, and it reaches native Anthropic features that the OpenAI-compatible /v1 path cannot express, such as extended thinking and prompt caching. Set cacheRetention explicitly to choose retention, as the configuration below shows. Reach it with a second provider entry using the anthropic-messages API and the /anthropic base URL, the same shape as the bundled Anthropic-compatible provider examples:

    json5
    {  models: {    providers: {      "neon-anthropic": {        baseUrl: "https://<your-neon-branch-host>/anthropic",        apiKey: "${NEON_AI_GATEWAY_TOKEN}",        authHeader: true,        api: "anthropic-messages",        models: [          {            id: "claude-sonnet-4-6",            name: "Claude Sonnet 4.6",            reasoning: true,            input: ["text", "image"],            cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },            contextWindow: 200000,          },        ],      },    },  },  agents: {    defaults: {      model: { primary: "neon-anthropic/claude-sonnet-4-6" },      models: {        "neon-anthropic/claude-sonnet-4-6": {          params: { cacheRetention: "short" },        },      },    },  },}

    The same cost, maxTokens and contextWindow caveats from the OpenAI entry apply here: set cost from the Neon model catalog, and take contextWindow from that catalog as well.

    Set authHeader: true because Neon requires a bearer credential, including on this Anthropic-compatible endpoint.

    Set params.cacheRetention under agents.defaults.models, as the example above does, to choose caching behavior for this custom anthropic-messages route. Use "short" for the 5-minute cache or "long" for the 1-hour TTL; "none" disables it. See Prompt caching.

    Two behaviors matter here:

    • This endpoint takes Claude model IDs only. Sending a non-Anthropic ID returns 400 model "<model-id>" is not available on the anthropic_messages endpoint, so keep this entry separate from the /v1 entry, which reaches every model.
    • On a non-api.anthropic.com host, OpenClaw suppresses implicit anthropic-beta headers, such as interleaved thinking, so a proxy does not reject them. Set headers with an anthropic-beta value on the provider if you need a specific beta.
    Rate limits and quota

    Neon enforces account-level token-per-minute rate limits. Going over returns 429 Too Many Requests with a message naming the model. Upstream output-token limits also apply, so a 429 can happen on output tokens alone.

    Neon also enforces an account-level spend cap that returns 429 with error code REQUEST_LIMIT_EXCEEDED.

    Response shape

    For most models message.content is a plain string. Some models return an array of typed content blocks instead; see Neon's content-shape guidance. OpenClaw's openai-completions transport flattens those blocks on the way in, treating text blocks as assistant output and reasoning blocks as thinking, so nothing in your config has to handle the array form.

    A low output-token limit can cut a response off before the text block appears. If the response contains reasoning but no answer, check the finish reason and output-token budget before raising maxTokens.

    Proxy behavior notes
    • Custom reasoning models marked reasoning: true support OpenAI-style reasoning controls. With openai-completions, selecting a thinking level can send reasoning_effort to Neon. If the upstream model rejects that field, set compat.supportsReasoningEffort: false on that model entry.
    • Inference uses prepaid credits on a paid plan. Neon charges the model provider's per-token rate with no markup. See the AI Gateway overview.
    Common errors and troubleshooting

    Neon's troubleshooting guide covers the errors you are most likely to hit:

    • For account-access errors, check the model's enabled field in GET /v1/models. If your project has a paid plan and prepaid credits but access is disabled, contact Neon support. For credential errors, check the ai_gateway:invoke scope and branch lineage.
    • 400 model "<model-id>" is not available on the <endpoint> endpoint means the model ID does not belong to the dialect you called, such as an OpenAI ID sent to /anthropic or a Claude ID sent to /openai/v1. Use the provider entry that matches the model.
    • AI Gateway is generally available on paid plans and is not available in every region, so a project created in an unsupported region or on a free plan cannot reach it. See Regions for current coverage.
    Was this useful?