How to
Authenticate Providers
API keys from the environment, OAuth login, and reusing a Claude Code or Codex subscription
- Setting up credentials for any provider
- Logging in with a subscription instead of an API key
Start with an API key unless your application needs OAuth.
The three paths differ only in where the credential comes from. After the provider exists, every layer above works the same way.
Use API keys
Set one of these variables before your process starts.
ANTHROPIC_API_KEYOPENAI_API_KEYOPENROUTER_API_KEYGOOGLE_API_KEYANTHROPIC_OAUTH_TOKENorOPENAI_OAUTH_TOKEN
msg, err := pi.GenerateText(ctx, "openai-completions/gpt-5-mini", prompt)pkg/pi detects environment credentials on first use. Use a full model spec when
several providers are present.
Log in with OAuth
cfg := openai.LoginConfig(clientID)cfg.DisplayURL = func(url string) error { fmt.Println("Open this URL:", url) return nil}
creds, err := oauth.Login(ctx, cfg) // blocks until the callback arrives
provider := openairesponses.NewForCodexOAuth(clientID, "", creds)model := ai.NewLanguageModel(openairesponses.GPT5Mini, provider)The SDK returns the credentials to your application, and never stores them. The
cmd/pi CLI keeps its own at ~/.pigo/auth.json.
Reuse a Claude Code or Codex login
provider, ok := anthropic.DetectClaudeCLI()if !ok { log.Fatal("run Claude Code login first")}
model := ai.NewLanguageModel(anthropic.ClaudeHaiku45, provider)Use openairesponses.DetectCodexCLI for a Codex login. On refresh, the provider
reads the credential store of the official CLI again.
Headless machines
If the browser cannot reach the localhost callback, add a paste fallback.
cfg := anthropic.LoginConfig(clientID)
cfg.ReadCode = func(ctx context.Context) (string, error) { // Read one line from stdin. Select on ctx.Done() so a cancelled // login does not block on the scanner. // ...}Paste a bare code or the full redirect URL. The login flow uses the first valid callback or pasted code.
Next: OAuth concepts.