# Provider keys

> Give a self-hosted Nodaro its model provider keys on /setup or in .env, see which key powers which nodes, and send provider traffic through your own proxy.

Source: https://nodaro.ai/docs/self-hosting/provider-keys

**Provider keys** are the API keys that let a self-hosted Nodaro call AI models. You can paste them in the app or set them in the environment, and both ways are live at once. Instead of keys, or next to them, you can also connect the install to a Nodaro Cloud account: see [Connect to Nodaro Cloud](https://nodaro.ai/docs/self-hosting/cloud-connect).

## Two ways to add a key

| Way | Where the key lives | When it applies | Who can change it |
| --- | --- | --- | --- |
| **Paste it in the app**, on `/setup` in the **Install health** section, or under **Integrations › Model providers** | Your database, encrypted with the instance key. No route ever returns it. | At once. The API uses it immediately, and the workers read it within about 30 seconds. No restart. | Community: any signed-in user. Business: admins. |
| **Set it in the environment**, in `.env` or your platform's variables | Your environment | At the next start | Whoever manages the server |

A **Run** right after you paste a key works: a node that finds no provider reads the keys again once before it fails.

Pasting a key always needs a signed-in session in the app. An API token or an app token can never change a key. The `/setup` health cards need no sign-in, but saving a key there does: complete step 1, **Create your server login**, first.

## Which key wins

**The environment wins.** A key set in the environment is read-only on the screen: its tile shows `set (env)` and names the variable to remove. A pasted key is used only where the environment has none for that provider.

## Manage a key on its tile

Every provider tile can be managed at runtime, including keys that come from `.env`. Changes apply without a restart.

- **A pasted key** shows `key set (app)`. Click **Change key** or **Remove** at any time.
- **A key from `.env`** cannot be edited in place. **Replace .env key** saves a key in the app that overrides the environment one, without editing the file. Or remove the key from `.env` and restart.
- **Disable** stops a provider until you enable it again, whether its key came from `.env` or was pasted. Use it to move generation to another provider, for example to your Nodaro Cloud connection.
- **`missing`** means the provider has no key. **`disabled`** means you switched it off.

Each tile says what its key powers and where to get one.

## Every provider key

| Variable | What it powers |
| --- | --- |
| `NODARO_API_KEY` | Nodaro Cloud as a provider: a personal API token from app.nodaro.ai › **Settings › API**, billed to that account. See [Connect to Nodaro Cloud](https://nodaro.ai/docs/self-hosting/cloud-connect#or-use-an-api-key-like-any-other-provider). |
| `KIE_API_KEY` | The broadest model coverage: image, video, audio and text models, including the Suno music nodes. |
| `REPLICATE_API_TOKEN` | An alternative provider with its own catalog, including the Flux 2 models. |
| `ANTHROPIC_API_KEY` | Claude models for the text nodes, called directly. |
| `GEMINI_API_KEY` | Gemini models, called directly. A Google AI Studio key. See [Gemini models](#gemini-models). |
| `ELEVENLABS_API_KEY` | Speech, voices, dubbing, voice changer and forced alignment. |
| `FAL_KEY` | Optional. Models such as [Sync Lipsync v3](https://nodaro.ai/docs/models/video/sync-lipsync-v3). Without it, those models are unavailable and nothing else changes. |

### Keys used by specific nodes

Leave these empty unless you use the node they name. On a connected install, those nodes run through Nodaro Cloud when their key is empty.

| Variable | Nodes |
| --- | --- |
| `HEYGEN_API_KEY` | [AI Avatar](https://nodaro.ai/docs/nodes/video/ai-avatar) and [Cinematic Avatar](https://nodaro.ai/docs/nodes/video/cinematic-avatar) |
| `BEEBLE_API_KEY` | [Relight & Switch](https://nodaro.ai/docs/nodes/video/relight-and-switch) |
| `APIFY_API_TOKEN` | [Web Scrape](https://nodaro.ai/docs/nodes/automate/web-scrape) |

`GEMINI_API_KEY` is not the same as `GOOGLE_CLIENT_ID` and `GOOGLE_CLIENT_SECRET`. Those two belong to a Google OAuth app, for example for YouTube publishing. See [Social network apps](https://nodaro.ai/docs/self-hosting/configuration#social-network-apps).

## Keys and the Nodaro Cloud connection

- **A connection covers every tile.** On a connected install, image, video, speech and text models, the avatars, Relight & Switch and web scraping run through your Nodaro Cloud account. Paste a key only to call that provider directly.
- **You choose who wins.** When you connect, a dialog asks whether Nodaro Cloud runs everything first or your own keys run first. See [Choose how the connection is used](https://nodaro.ai/docs/self-hosting/cloud-connect#choose-how-the-connection-is-used).
- **The OAuth connection wins over `NODARO_API_KEY`.** When an install has both, it uses the connection and ignores the key.

## Gemini models

Gemini models can run in two ways. Without `GEMINI_API_KEY`, they run on `KIE_API_KEY`. With it:

- **Gemini 3.1 Pro** runs directly on Google first, with `KIE_API_KEY` as the fallback.
- **The Gemini Flash models** stay on `KIE_API_KEY` and use `GEMINI_API_KEY` only when that fails.

Two things to know before you set it:

- **Cost.** Google bills the direct route at its own per-token prices, which can be higher than the same model on `KIE_API_KEY`. Check Google's current prices before you move a high-volume model.
- **Media.** Google's API cannot fetch arbitrary URLs. Nodaro downloads each image, video or audio reference and sends it as inline data when it is small, or through the Gemini Files API when it is large. The Files API keeps files for 48 hours.

## Send provider traffic through your own proxy

Two providers let you change the host, not only the key:

| Variable | Default | What it moves |
| --- | --- | --- |
| `KIE_API_BASE_URL` | The provider's own API host | Every call made with `KIE_API_KEY`: media generation **and** the Claude and Gemini text traffic that runs on it |
| `ELEVENLABS_BASE_URL` | `https://api.elevenlabs.io` | Every ElevenLabs call: text to speech, speech to text, voices, cloning, dubbing and forced alignment |

Leave both unset and nothing changes. Set one, and Nodaro talks to your host instead. The usual reasons are key custody, where the real key lives only on the proxy, an audit log of every outbound generation, and regional routing.

Your proxy must be transparent: the same paths and the same request and response bodies, because Nodaro only replaces the origin. Trailing slashes are removed, so `https://proxy.example.com/models/` and `https://proxy.example.com/models` behave the same.

**KIE_API_BASE_URL also moves text model traffic:** 
The Claude and Gemini traffic behind prompt enhancement, script generation and the other text features runs over the same host. Your proxy must forward these paths, not only the media API:

- `/api/v1/...`, for tasks, polling and the balance check
- `/claude/v1/messages`
- `/<family>/v1/chat/completions`
- `/<family>/v1/responses`
- `/client/v1/userRecord/...`, for credit lookups

A proxy that forwards only the media paths leaves every text feature failing while images and video keep working.

`ANTHROPIC_API_KEY` and `GEMINI_API_KEY` are not affected by the proxy. With them, those models call Anthropic and Google directly.

## Check that a key works

- **In the editor.** Open the Welcome Demo and click **Run** on its **Scene Image** node.
- **From the command line.** Run the probe with `--keyed`. It spends one real generation on the cheapest model for your `KIE_API_KEY` or `REPLICATE_API_TOKEN` and checks that the media lands in your own storage:

```bash
node tools/community-smoke.mjs http://localhost:3000 --keyed
```

A node that fails with `Missing API key` calls a provider that has no key. Add that provider's key on `/setup` or in `.env`.

## The encryption key

Pasted keys need the instance encryption key, `NODARO_ENCRYPTION_KEY`. The bundled compose stack generates it on the first boot. Without one, the tiles show `missing`, and `/setup` shows a red **Encryption** card with the fix. Keys set in the environment keep working. See [Install](https://nodaro.ai/docs/self-hosting/install#2-generate-the-internal-secrets).

## Frequently asked questions

### Where do I add provider keys on a self-hosted Nodaro?

Paste them on /setup, in the Install health section, or in the app under Integrations › Model providers. Or set them in .env and run docker compose up -d. Pasted keys apply at once, without a restart.

### Which wins, a key in .env or a key pasted on the screen?

The key in the environment. Its tile shows set (env) and cannot be edited in place. Remove it from .env and restart, or use Replace .env key on the tile to override it from the screen.

### Who can change the provider keys?

On the Community Edition, any signed-in user, because the edition is made for a single operator. On the Business edition, admins only. API tokens and app tokens can never change them.

### Where are pasted keys stored?

In your own database, encrypted with AES-256-GCM using the instance encryption key. No route ever returns them. Without an encryption key, the tiles show missing and /setup shows a red Encryption card.

### Why do image and video work but every text feature fails?

If you set KIE_API_BASE_URL to a proxy, the proxy must also forward the text model paths, not only the media API. A proxy that forwards only the media paths breaks every feature that uses a text model.
