---
title: "How to call OpenAI, Claude, or Gemini without API keys | Netlify Knowledge Base"
description: "Guides and articles to help you get the most out of the Netlify platform."
source: "https://www.netlify.com/knowledge-base/how-to-call-openai-claude-or-gemini-without-api-keys/"
last_updated: "2026-09-23T19:52:08.000Z"
---
## Key takeaways

Install the provider’s official SDK, instantiate the client with **no arguments**, and call it from a Netlify Function. Netlify injects the API key and base URL that the SDK already looks for, so there’s no provider account to create and no key to store. Works with OpenAI, Anthropic, Google Gemini, and OpenRouter. One prerequisite catches everyone: the gateway doesn’t activate until your project has had **at least one production deploy**, even for local development.

-   **Not browser-callable.** The gateway lives in Functions and Edge Functions only.
-   **Runtime-only credentials.** Build scripts, prerendering, SSG, and build plugins get no credentials and fail.
-   **60-second sync timeout.** Stream long generations or use a background function.
-   **Don’t hardcode model lists.** Availability changes; check the live providers endpoint.
-   **Zero Data Retention only.** The gateway routes only to ZDR providers, so some catalog models aren’t served.
-   **$1 USD of usage = 180 credits**, with per-minute rate limits by plan.

## The part of adding AI that isn’t the interesting part

Wiring up a model call involves one interesting decision (what to ask it) and several tedious ones. Which provider account. Where the key lives. How it reaches production without ending up in your repo. Who rotates it. What happens when a teammate needs to run the thing locally.

AI Gateway removes that whole layer. You write the SDK call you were going to write anyway, instantiate the client with no arguments, and the credentials are already there at runtime. Netlify never overrides keys you’ve set yourself, so if you’d rather bring your own provider account, that still works and takes precedence.

Here’s the setup, then the constraints that matter for cost and latency.

## When to use the gateway, and when not to

Use it for server-side AI calls from a deployed Netlify project: a chatbot endpoint, a completion route, summarizing form submissions, generating images or text, any LLM-backed API route.

Don’t use it when:

-   **The call needs to happen in the browser.** It isn’t browser-callable. Put the call in a Function and fetch that route from the client.
-   **The work happens at build time.** Prerendering, SSG, and build plugins get no gateway credentials and will fail. Do the AI work at request time, and if the output needs to look precomputed, cache it to Netlify Blobs (see How to store files and objects with Netlify Blobs).
-   **You need a proprietary header-gated feature.** No request headers pass through.
-   **You need batch inference or OpenAI priority processing.** Neither is supported.
-   **You’re on a legacy plan.** Credit-based plans only: Free, Personal, Pro, with Enterprise via an Account Manager.

## Worked example

Create `netlify/functions/joke.js` (`mkdir -p netlify/functions` first) and `npm install openai`.

```
import process from "process";import OpenAI from "openai";
export default async () => {  const client = new OpenAI(); // reads OPENAI_API_KEY + OPENAI_BASE_URL  try {    const res = await client.responses.create({      model: "gpt-5-mini",      input: [{ role: "user", content: "Give me a random short dad joke" }],      reasoning: { effort: "minimal" },    });    return Response.json({      joke: res.output_text?.trim() || "Out of jokes",      model: res.model,      tokens: { input: res.usage.input_tokens, output: res.usage.output_tokens },    });  } catch (e) {    return Response.json({ error: `${e}` }, { status: 500 });  }};
export const config = { path: "/api/joke" }; // route, local + deployed
```

The client-side half is a plain fetch to your own route:

```
const res = await fetch("/api/joke");const data = await res.json();
```

Note that `new OpenAI()` takes no arguments. That’s the whole trick: the SDK reads `OPENAI_API_KEY` and `OPENAI_BASE_URL` from the environment, and Netlify has already put them there.

### The four providers

```
// Anthropic — npm i @anthropic-ai/sdkimport Anthropic from '@anthropic-ai/sdk';const anthropic = new Anthropic(); // ANTHROPIC_API_KEY + ANTHROPIC_BASE_URLawait anthropic.messages.create({  model: 'claude-sonnet-4-5-20250929',  max_tokens: 1024,  messages: [{ role: 'user', content: 'Hello!' }],});
```

```
// OpenAI — npm i openaiimport OpenAI from 'openai';const openai = new OpenAI(); // OPENAI_API_KEY + OPENAI_BASE_URLawait openai.chat.completions.create({  model: 'gpt-5',  messages: [{ role: 'user', content: 'Hello!' }],});
```

```
// Google Gemini — npm i @google/genaiimport { GoogleGenAI } from '@google/genai';const genAI = new GoogleGenAI({}); // GEMINI_API_KEY + GOOGLE_GEMINI_BASE_URLawait genAI.models.generateContent({  model: 'gemini-2.5-pro',  contents: 'Hello!',});
```

```
// OpenRouter — npm i @openrouter/sdk@1.2.43 or laterimport { OpenRouter } from '@openrouter/sdk';const openRouter = new OpenRouter(); // OPENROUTER_API_KEY + OPENROUTER_BASE_URL auto-injectedawait openRouter.chat.send({  chatRequest: {    model: 'x-ai/grok-4.5',    messages: [{ role: 'user', content: 'Hello!' }],  },});
```

There’s a shortcut worth knowing: you can reach any OpenRouter-served model (xAI, DeepSeek, Meta, Mistral, Qwen) through the plain OpenAI SDK by passing the model ID in OpenRouter notation, with no extra configuration:

```
await openai.chat.completions.create({  model: 'deepseek/deepseek-v4-flash-0731',  messages: [{ role: 'user', content: 'Hello!' }],});
```

The model IDs in these examples are illustrative. The model list is dynamic, so check the live providers endpoint rather than baking IDs into your code.

### Setup and deploy

1.  Be on a credit-based plan (Free, Personal, Pro; Enterprise via an Account Manager). Legacy plans need to switch.
2.  Link the project: `netlify init`.
3.  **Deploy to production at least once.** This is required to activate the gateway: `netlify deploy --prod --open`.
4.  Leave AI Features enabled, and don’t set your own provider keys unless you mean to override.

### Local development

Both paths still require an existing production deploy.

**Netlify CLI**, with full support: `netlify dev`. You’ll need `npm install -g netlify-cli@latest` and `netlify login`.

**Netlify Vite plugin**, which gives gateway access without `netlify dev`:

vite.config.js

```
import { defineConfig } from 'vite'import react from '@vitejs/plugin-react'import netlify from "@netlify/vite-plugin";
export default defineConfig({  plugins: [react(), netlify()],})
```

Then run your normal `npm run dev`.

### Long generations

A synchronous function is killed at 60 seconds, and a real generation can exceed that. Two options.

**Stream it.** Return the provider’s streaming response body as a `ReadableStream` from your function. The mechanics of streaming from a Netlify Function, including a worked OpenAI streaming example, are in How to add a backend API endpoint with Netlify Functions. Streamed responses are capped at 20 MB.

**Or run it in the background.** Set `config.background: true`, which gives you up to 15 minutes, and persist the output somewhere the client can fetch it, typically Netlify Blobs. The client gets an immediate `202`, so you’ll need to poll or notify.

What you should not do is leave a slow generation unstreamed and hope it finishes.

## Common failure modes

**Everything fails locally and you can’t work out why.** The gateway doesn’t activate until the project has at least one production deploy. That applies to local dev too. Run `netlify deploy --prod` once.

**Your calls fail from the browser.** The gateway isn’t browser-callable. Move the call into a Function and fetch that route.

**Your build fails on an AI call.** Gateway credentials are runtime-only. Build scripts, prerendering, SSG, and build plugins get nothing. Move the call to request time and cache the output if it needs to appear precomputed.

**Your function times out at 60 seconds.** Stream it, or move it to a background function.

**Gemini credentials aren’t being injected.** Netlify will **not** inject `GEMINI_API_KEY` or `GOOGLE_GEMINI_BASE_URL` if either `GOOGLE_API_KEY` or `GOOGLE_VERTEX_BASE_URL` is set. That’s deliberate, so you can point at Vertex or your own Google credentials, but it surprises people who set one of those for something else.

**A model in the OpenRouter directory returns nothing.** The gateway routes **only to Zero Data Retention providers**. A model listed in the directory isn’t served if no ZDR host offers it. Browse the ZDR-filtered catalog at [openrouter.ai/models?zdr=true](https://openrouter.ai/models?zdr=true).

**A model ID that worked last month doesn’t now.** Availability changes. Don’t hardcode; check the live providers endpoint at runtime.

**You hit a rate limit.** Limits are per team, across all projects, per minute, measured in credits: Free 90, Personal 450, Pro 1,800, Enterprise 9,000.

**Your credit usage spiked from visitor traffic.** An unprotected AI endpoint is an expensive thing to leave open. Set up [rate limiting rules](https://docs.netlify.com/manage/security/secure-access-to-sites/rate-limiting/) on AI functions.

**Your prompt was truncated.** Input is capped at **200k tokens**.

**Prompt caching isn’t behaving as you’d expect.** Anthropic gets only the default 5-minute ephemeral cache. OpenAI has a per-account `prompt_cache_key` set for you. Gemini explicit context caching isn’t supported.

**Your own provider key seems to be ignored.** It isn’t. Netlify only injects credentials if you have **not** already set them at the project or team level. Netlify never overrides your keys.

## Reference

### Injected environment variables

Set in all Netlify compute contexts at function init, **only if you haven’t already set them** yourself.

Provider

Variables

OpenAI

`OPENAI_API_KEY`, `OPENAI_BASE_URL`

Anthropic

`ANTHROPIC_API_KEY`, `ANTHROPIC_BASE_URL`

Google Gemini

`GEMINI_API_KEY`, `GOOGLE_GEMINI_BASE_URL`

OpenRouter

`OPENROUTER_API_KEY`, `OPENROUTER_BASE_URL`

Two more are **always injected and never collide** with your provider variables: `NETLIFY_AI_GATEWAY_KEY` and `NETLIFY_AI_GATEWAY_BASE_URL`.

Use the SDK path with the per-provider variables as your default. Reach for the `NETLIFY_AI_GATEWAY_*` pair only when a third-party or unsupported library needs credentials passed explicitly. That’s the case they exist for.

### SDK instantiation

Provider

Package

Client

OpenAI

`openai`

`new OpenAI()`

Anthropic

`@anthropic-ai/sdk`

`new Anthropic()`

Google Gemini

`@google/genai`

`new GoogleGenAI({})`

OpenRouter

`@openrouter/sdk` (v1.2.43+)

`new OpenRouter()`

### Limits and constraints

Constraint

Value

Plans

Credit-based only (Free, Personal, Pro; Enterprise via Account Manager)

Context window

200k input tokens

Rate limit (per team, per minute, in credits)

Free 90 · Personal 450 · Pro 1,800 · Enterprise 9,000

Credit cost

Tokens → USD at provider published rates → credits. **$1 USD = 180 credits.**

Sync function timeout

60s

Request headers passed through

None

Batch inference

Not supported

OpenAI priority processing

Not supported

Data retention

Zero Data Retention providers only

Prompt storage

The gateway does not store prompts or outputs

### Prompt caching by provider

Provider

Support

Anthropic

Default 5-minute ephemeral cache only

OpenAI

Per-account `prompt_cache_key` is set

Gemini

Explicit context caching not supported

## FAQs

**How do I add an AI model call to my Netlify site?** Install the provider’s official SDK, create a Netlify Function, and instantiate the client with no arguments. Netlify injects the API key and base URL at runtime. Deploy to production once to activate the gateway.

**Do I need an OpenAI or Anthropic account to use AI Gateway?** No. The gateway injects credentials for OpenAI, Anthropic, Google Gemini, and OpenRouter. If you do set your own provider keys, Netlify won’t override them.

**Can I call AI Gateway from the browser?** No. It’s available in Functions and Edge Functions only. Put the call in a Function and fetch that route from your client code.

**Why isn’t AI Gateway working locally?** The gateway doesn’t activate until the project has at least one production deploy, which applies to local development too. Run `netlify deploy --prod`, then use `netlify dev` or the Netlify Vite plugin.

**What does AI Gateway cost?** Token usage converts to USD at the provider’s published rates, then to credits, where $1 USD of usage equals 180 credits. Per-minute rate limits run from 90 credits on Free to 9,000 on Enterprise.

**Can I use AI Gateway during the build or in SSG?** No. Credentials are runtime-only, so build scripts, prerendering, and build plugins get nothing. Do the work at request time and cache the result to Netlify Blobs if it needs to look precomputed.

**How do I handle a generation that takes longer than 60 seconds?** Stream the response using the SDK’s streaming mode returned as a `ReadableStream`, or run it in a background function with `config.background: true` and persist the output for the client to fetch.

**Which models can I use?** Anthropic, OpenAI, and Gemini models served directly, plus OpenRouter-served models like xAI, DeepSeek, Meta, Mistral, and Qwen using OpenRouter notation. The list is dynamic, so check the live providers endpoint instead of hardcoding IDs. Only Zero Data Retention hosts are routed to.

**Does Netlify store my prompts?** No. The gateway does not store prompts or outputs.

## Related

-   [AI Gateway overview](https://docs.netlify.com/build/ai-gateway/overview.md)
-   [AI Gateway quickstart](https://docs.netlify.com/build/ai-gateway/quickstart-for-ai-gateway.md)
-   [Rate limiting](https://docs.netlify.com/manage/security/secure-access-to-sites/rate-limiting/)
-   [Buy credit packs](https://docs.netlify.com/manage/accounts-and-billing/billing/billing-for-credit-based-plans/buy-credit-packs/)
-   [Configure auto-recharge](https://docs.netlify.com/manage/accounts-and-billing/billing/billing-for-credit-based-plans/configure-auto-recharge/)

This article is generated from Netlify’s open-source agent guidance at [netlify/context-and-tools](https://github.com/netlify/context-and-tools), the same reference our AI coding agents use.

* * *

Ready to build something with a model in it? Start at [netlify.new](https://netlify.new).