> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vendo.run/llms.txt
> Use this file to discover all available pages before exploring further.

# Model credentials: naming a model and paying for it

> Pass your own AI SDK model, keep your agent loop's model separate from Vendo's, or leave the seat unset and let VENDO_API_KEY fill it. Plus why a provider key in the environment selects nothing.

Vendo runs on any AI SDK `LanguageModel`. `createVendo`'s `models` slot is
optional, and what you do with it decides which key gets spent.

One rule explains most of this page: **env keys are credentials, config
selects.** A provider key sitting in your environment does not pick a model.
`models` on `createVendo` does. `ANTHROPIC_API_KEY` is what the
`@ai-sdk/anthropic` provider *you* pass authenticates with, nothing more.

Model credentials are real keys only. A coding-agent login (Claude Code, Codex)
can help at *init* time, but it never serves product turns.

## Bring your own model

Pass it. An explicit model always wins, in development and production alike, and
the key its provider reads (`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`,
`GOOGLE_GENERATIVE_AI_API_KEY`, …) is the provider's business, not Vendo's:

```ts theme={null}
import { anthropic } from "@ai-sdk/anthropic";
import { createVendo } from "@vendoai/vendo/server";

const vendo = createVendo({
  models: { default: anthropic("claude-sonnet-4-6") },
  catalog: registry,
});
```

Install the matching `@ai-sdk/*` provider and put its key in `.env.local`. That
is the whole setup, and no Vendo key is involved.

## Two models, two credentials

If you already ship your own agent loop, you have two model seats, and they do
not share a key.

Your loop keeps its own model and key. No Vendo key replaces it. Vendo's
internal turns (micro-app builds, the delegate) need a model of their own, and
they will not borrow your loop's.

* Name Vendo's model in the composition with `models: { default: … }`, and
  Vendo's builds ride exactly that, whatever your loop uses.
* Or leave the seat unset and set `VENDO_API_KEY`, which fills it with the Vendo
  Cloud gateway.
* With neither, Vendo's internal turns fail on first use and say so. An
  `ANTHROPIC_API_KEY` sitting in the environment for your loop does **not**
  quietly become Vendo's model. That used to happen, and it meant your Cloud key
  was shadowed by a key you set for something else.
* If your loop's own model has no key on this machine, either set one or point
  your `model` at `vendoModel()` from `@vendoai/vendo/server` to ride the same
  ladder Vendo does.

The done-criterion for a BYO-agent install is a real chat turn that renders a
Vendo tool output. `vendo doctor` cannot check your loop's model.

## Leaving the seat unset

Omit `models` and the runtime resolves one through `vendoModel()` (formerly
`devModel()`, which remains as a deprecated alias). It walks two rungs and stops
at the first one that resolves.

<Steps>
  <Step title="Vendo Cloud key">
    `VENDO_API_KEY` delegates to the Vendo Cloud model gateway (Anthropic
    Messages wire, served through the stock `@ai-sdk/anthropic` provider,
    which Vendo ships — the key alone suffices, and your app's own install
    wins when present). On this rung the default model is `vendo`
    (the console maps it to a concrete model server-side); pin a different
    id with `VENDO_MODEL`. No key on hand? `npx vendo login` mints a free
    metered API key.
  </Step>

  <Step title="None">
    No credential resolves, and the first turn says exactly that:

    ```
    Vendo has no model. Pass one — models: { default: anthropic("claude-sonnet-4-6") }
    in createVendo — or set VENDO_API_KEY for the Vendo Cloud gateway (`vendo login`
    mints a free dev key). A provider key alone no longer selects a model; Vendo
    never picks a provider for you.
    ```
  </Step>
</Steps>

Two rungs, and `ANTHROPIC_API_KEY` is not one of them.

`VENDO_DEV_CREDENTIAL` pins a ladder rung, including the `env-key` rungs that
nothing else can reach any more. It is **internal** — Vendo's own E2E rung matrix
and escape hatch, not a host knob, and it can change without notice. Pinning a
rung that cannot resolve produces the same honest error as the `none` case.

## The generated composition

The route init scaffolds calls `createVendo()` without a `model`, so the runtime
resolves the ladder above on every turn. Init does not scaffold a model file. To
pin a provider, add `models` to the composition with any AI SDK `LanguageModel`:

```ts theme={null}
import { createVendo, vendoModel } from "@vendoai/vendo/server";

// Omit the seat to keep the VENDO_API_KEY rung, or pass a model to pin a
// provider — that is the only thing that selects one. A provider key in the
// environment selects nothing on its own.
const vendo = createVendo({ models: { default: vendoModel() }, catalog: registry });
```

The [handler](/reference/handler-options) contract does not change either way.

## Verifying the model

Init does not run a live turn. `vendo doctor` sends one real model turn through
the same ladder, so doctor and runtime agree on what is wired:

```bash theme={null}
npx vendo doctor
```

Exit 0 means a real user would have gotten an answer. A failed turn reports
[`E-TURN-001`](/deploy/troubleshooting#E-TURN-001).

## Related

* [vendo init](/reference/vendo-init): the scaffold command and its flags.
* [Environment variables](/reference/environment-variables): every `VENDO_*`
  variable Vendo reads.
* [Vendo Cloud](/deploy/vendo-cloud): what a key covers and what it costs.
