Autoscaling Report: Production databases on Neon use 2.4x less compute and 50% less cost than if they were running on a provisioned platform.
/AI Gateway/Authentication

AI Gateway authentication

How Neon credentials work with AI Gateway

Private Preview

This feature is in private preview: it's not ready for production use, and it may be briefly unavailable as we deploy updates. To get access, sign up here.

AI Gateway uses Neon bearer credentials, the same credential system as Neon Storage. No provider API keys are needed.

Creating a credential

A credential must include the ai_gateway:invoke scope.

In the Neon Console, select your branch and click Credentials under APP BACKEND in the sidebar. Click Create credential, give it a name, and check ai_gateway:invoke.

After creation, the credential is shown once. Copy the snippet or click Download .env before closing. The snippet includes all four gateway env vars (see Environment variables below).

To view or revoke credentials later, return to the Credentials page and use the action menu (⋮) next to the credential.

Pull credentials with neon

For local development, neon env pull writes your AI Gateway credentials to your .env file automatically, with no manual copy-paste from the API response:

neon env pull .env

This populates NEON_AI_GATEWAY_TOKEN and NEON_AI_GATEWAY_BASE_URL for the current branch alongside your database connection string. Running neon config apply or neon deploy also auto-pulls credentials after a successful apply. To check current credential status:

neon config status

For production deployments, use the API-based workflow to create named credentials with optional expiry.

Using your credential

Pass your credential as a bearer token on every request:

Authorization: Bearer <your-credential>

When using an AI SDK, set this as the apiKey parameter:

import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: process.env.NEON_AI_GATEWAY_TOKEN,
  baseURL: `${process.env.NEON_AI_GATEWAY_BASE_URL}/ai-gateway/mlflow/v1`,
});

Environment variables

Neon provides four gateway env vars. Two follow OpenAI's standard naming so existing SDKs pick them up automatically. Two use NEON_-prefixed names that survive a user overriding the OPENAI_* variables with their own provider keys.

VariableValue
OPENAI_API_KEYBearer token (nt_live_...)
OPENAI_BASE_URLFull OpenAI Responses dialect URL: https://<branch-host>/ai-gateway/openai/v1includes the path
NEON_AI_GATEWAY_TOKENSame bearer token as OPENAI_API_KEY
NEON_AI_GATEWAY_BASE_URLBare branch host: https://<branch-host>no path; append /ai-gateway/<dialect>/v1 yourself

OPENAI_BASE_URL and NEON_AI_GATEWAY_BASE_URL point at different URLs. OPENAI_BASE_URL already includes /ai-gateway/openai/v1, so new OpenAI() picks it up with zero config and calls the Responses API. NEON_AI_GATEWAY_BASE_URL is the bare host — append the dialect path yourself:

NEON_AI_GATEWAY_BASE_URL + /ai-gateway/mlflow/v1   → chat completions (all providers)
NEON_AI_GATEWAY_BASE_URL + /ai-gateway/openai/v1   → OpenAI Responses API (= OPENAI_BASE_URL)
NEON_AI_GATEWAY_BASE_URL + /ai-gateway/anthropic   → Anthropic Messages API
NEON_AI_GATEWAY_BASE_URL + /ai-gateway/gemini      → Gemini generateContent API

Credentials in Neon Functions

When your code runs inside Neon Functions, all four env vars are injected automatically. No credential creation step required:

VariableValue
NEON_AI_GATEWAY_TOKENBearer token for the AI Gateway
NEON_AI_GATEWAY_BASE_URLBranch gateway host with https:// prefix, no path
OPENAI_API_KEYSame value as NEON_AI_GATEWAY_TOKEN
OPENAI_BASE_URLBranch gateway host including the OpenAI Responses path

new OpenAI() works with zero configuration because OPENAI_API_KEY and OPENAI_BASE_URL are already set:

import OpenAI from 'openai';

// Reads OPENAI_API_KEY + OPENAI_BASE_URL from the environment automatically.
const client = new OpenAI();

const response = await client.responses.create({
  model: 'gpt-5-mini',
  input: 'What is Neon?',
});

For the chat completions endpoint or when you need credentials that survive a user overriding OPENAI_* with their own keys, use the NEON_AI_GATEWAY_* vars:

import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: process.env.NEON_AI_GATEWAY_TOKEN,
  baseURL: `${process.env.NEON_AI_GATEWAY_BASE_URL}/ai-gateway/mlflow/v1`,
});

How branch binding works

Each credential is tied to the branch it was created on. It's valid for:

  • That branch (the anchor branch)
  • Any branch descended from it: preview branches, feature branches, CI branches

It's not valid for branches outside that lineage.

This means a credential created on your main branch works in all branches that were forked from main. A credential created on a feature branch only works within that feature branch's descendants.

main  ──── credential valid here
  └── preview/feature-x  ──── and here
        └── preview/sub-branch  ──── and here
staging  ──── credential NOT valid here (different lineage)

This design lets you use a single credential across your entire development workflow (local dev, preview deployments, and CI) without creating separate credentials for each environment.

Common auth errors

ErrorCauseFix
401 UnauthorizedMissing or invalid credentialCheck that NEON_AI_GATEWAY_TOKEN is set and contains the full token
403 ForbiddenCredential lacks ai_gateway:invoke scopeRecreate the credential with the correct scope
403 ForbiddenBranch not in credential lineageUse a credential created on this branch or an ancestor branch. The gateway returns: credential not authorized for this branch
503 Service UnavailableAuth store temporarily unavailableRetry the request

Rotating credentials

To rotate a credential: create a new one, update your environment variables, then revoke the old one.

To revoke from the Console, open the Credentials page and use the action menu (⋮) next to the credential. To revoke via the API:

curl -X DELETE "https://console.neon.tech/api/v2/projects/{project_id}/branches/{branch_id}/credentials/{token_id}" \
  -H "Authorization: Bearer $NEON_API_KEY"

Need help?

Join our Discord Server to ask questions or see what others are doing with Neon. For paid plan support options, see Support.

Was this page helpful?
Edit on GitHub