Course · Pi · Getting started
Bring your own key to Pi
Pi has no bundled plan, no free tier, and no subscription of its own to sell you. Every session runs against a model you pay for directly - bring-your-own-key, in the fullest sense. That’s a deliberate consequence of the same minimalism the loop lesson walks through: Pi doesn’t want to be in the business of managing your billing relationship with a model provider, any more than it wants to carry a bloated standing system prompt you didn’t ask for.
The two ways in
Section titled “The two ways in”Inside the running prompt - with Pi installed and launched in your project - /login walks you through the options:
> /loginYou’ve got two shapes of authentication, and they’re not interchangeable:
- An API key, exported as an environment variable before you launch Pi -
ANTHROPIC_API_KEY,OPENAI_API_KEY, and so on, depending on the provider. You pay that provider per token, directly, at their published rate. - OAuth into a subscription you already have -
/loginsupports signing in against a handful of subscription-based providers this way, including Anthropic’s Claude Pro/Max plans, OpenAI’s ChatGPT plans, and GitHub Copilot.
A third case appears in the table below and fits neither shape: a local model (Ollama and its kin) needs no credential at all. It is configured where providers are defined, in models.json, and the local-models lesson covers it properly - noted here only so the table has no orphan row. The aggregator row, by contrast, belongs to the API-key shape: OpenRouter issues you a key of its own, and Pi treats it like any other provider’s - that row exists because the billing cushion and the extra hop differ, not the authentication mechanism.
Here’s what “per token” means on a concrete example from this course: the first-fix lesson closes its fix in five tool calls - two reads, of stash/extract.py (stash is the course’s running example, a small FastAPI feed reader) and tests/test_extract.py; one edit, to the first of those files; and two pytest runs, the focused file first and then the full suite. Every one of those five is a fresh round trip that resends the whole growing conversation back to whichever provider you picked.
Under API-key billing, all five round trips are metered at that provider’s published rate - check it before you rely on a long session, because it compounds with every read you ask for. stash itself doesn’t care which path you choose: pytest still runs locally, free, on your own machine, either way. What changes is only what you pay to have the model read the files, propose the diff, and re-check its own work.
For stash, either path gets you to a working session. What matters is which provider you pick, and how:
| Path | Who pays | Billing unit | Predictability |
|---|---|---|---|
| API key (Anthropic, OpenAI, others) | You, directly to the provider | Per token, at that provider’s published rate | Fully metered - cost scales with what you send and receive |
| OAuth into Claude Pro/Max | You, through your existing subscription | Per token, from “extra usage” - Pi’s own provider docs describe third-party harness calls as billed this way, not against your plan’s included usage | Same metering as an API key, despite the subscription login - verify against Anthropic’s current terms before you count on it |
| OAuth into ChatGPT or Copilot plans | You, through your existing subscription | Provider-specific and not detailed in Pi’s docs | Unknown until you read that provider’s current terms yourself |
| Local model via Ollama | Nobody, per call | None - your own compute | Free, with trade-offs you’ll weigh properly in a later module |
| Aggregator (OpenRouter) | You, via the aggregator | Full per-token API rate, no subscription cushion underneath | Same as a direct API key, plus one extra hop |
What this means for today
Section titled “What this means for today”None of this blocks you from working on stash right now. Either of the two paths above gets you a working session today - pick the one whose terms you’re already comfortable with, not the one this page recommends by default. The table’s remaining rows are paths their own lessons map out.
Pick whichever path gets a model responding, and confirm it landed:
> what model am I talking to right now?You’re authenticated, and Pi has a model to call. Before you hand it the actual bug, spend two minutes watching how a single request through Pi actually behaves - because the shape of that loop is the one piece of trust you need before the real fix. Next: understand one turn of the loop.