getting started
Quickstart
Two paths to a first request. Bring-your-own-key keeps your existing provider account and proxies through the gateway; managed mode calls a catalog model with nothing but your Understudy key. Both produce the same captures and respond in the same wire format your code already speaks.
Prerequisites
An Understudy sk_* key, minted on the dashboard's API keys page. The plaintext value is shown exactly once at creation — save it then. New workspaces also receive a starter key during onboarding.
Path A — bring your own key
Your code keeps calling the Anthropic or OpenAI API shape; the gateway forwards each request to that provider using the provider key you attach per request. Understudy never stores your provider key — it rides the x-understudy-upstream-key header and is used for that one upstream call.
export UNDERSTUDY_API_KEY="sk_live_..."
export ANTHROPIC_API_KEY="sk-ant-..."curl https://api.understudylabs.com/v1/messages \
-H "x-api-key: $UNDERSTUDY_API_KEY" \
-H "x-understudy-upstream-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{"model":"claude-haiku-4-5","max_tokens":32,"messages":[{"role":"user","content":"Say ok."}]}'import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
apiKey: process.env.UNDERSTUDY_API_KEY ?? "",
baseURL: "https://api.understudylabs.com",
defaultHeaders: {
"x-understudy-upstream-key": process.env.ANTHROPIC_API_KEY ?? "",
},
});OpenAI works the same way: Authorization: Bearer carries your Understudy key, x-understudy-upstream-key carries your OpenAI key, and the base URL becomes https://api.understudylabs.com/v1.
Path B — managed models
Catalog models are served from Understudy's own supply. Send the model's public id as body.model on the OpenAI-compatible endpoint — no provider account, no upstream key header. Discover ids with GET /v1/modelsor on the dashboard's Models page.
curl https://api.understudylabs.com/v1/chat/completions \
-H "Authorization: Bearer $UNDERSTUDY_API_KEY" \
-H "content-type: application/json" \
-d '{"model":"glm-5.1","max_tokens":32,"messages":[{"role":"user","content":"Say ok."}]}'Managed catalog calls are all-or-nothing by design: if the model can't be served there is no silent fallback to a frontier provider — you get an error, never a surprise bill.
Verify
Every response carries legibility headers — x-understudy-route tells you which arm served the request and x-understudy-effective-model which model actually ran (see response headers). If the workload that received the request has capture enabled, the request appears in the project's capture stream on the dashboard within seconds.