Skip to main content
Core

API Keys

Give agents model access with your own provider keys, from the environment or in code.

An agent calls the model from your worker, so its keys stay in your backend and never enter the sandbox. It looks for a key in this order:

  1. The apiKeys option passed to pi().
  2. The credentials Actor, when your users bring their own subscriptions.
  3. The worker’s environment.
YOUR BACKEND1apiKeys2credentials Actor3EnvironmentAgentModel providerSandboxmodel callstool calls,no keys

The agent never reads Pi’s local ~/.pi/agent/auth.json or models.json.

Environment variables

Set the key for your model provider in the environment of the process that runs your Actors:

ANTHROPIC_API_KEY=sk-ant-...

Pi reads the provider-named variable, such as ANTHROPIC_API_KEY, OPENAI_API_KEY, XAI_API_KEY, DEEPSEEK_API_KEY, GROQ_API_KEY, or OPENROUTER_API_KEY. See Pi’s provider list for the rest.

Keys in code

Pass apiKeys to set keys by provider id in code, for example when they come from a secret manager or differ per deployment. The keys stay in the Actor’s memory and win over every other source.

import { pi } from "@rivet-dev/pi";
import { e2bProvider } from "@rivet-dev/sandbox-adapter/e2b";
import { setup } from "rivetkit";

const anthropicKey = process.env.MY_ANTHROPIC_KEY;
if (!anthropicKey) throw new Error("MY_ANTHROPIC_KEY is not set.");

const agent = pi({
	model: "anthropic/claude-opus-5-5",
	sandbox: e2bProvider(),
	apiKeys: { anthropic: anthropicKey },
});

export const registry = setup({ use: { agent } });

registry.start();

Custom providers

To use a provider Pi does not know, register it with providers, in the shape of Pi’s models.json, and give it a key the same way.

Next: Sandboxes, where the agent’s tool calls run.