understudydocs

guides

Scope with projects

Scoping is two headers, but where you draw the lines determines whether your captures are actionable. The working rule: a project per product surface, a workload per stable call site, a key per environment.

Drawing the lines

Project = product surface.The concierge bot is one project; the internal search tool is another. Captures, routing, and dashboard pages are all project-scoped, so this is the boundary you'll browse by.

Workload = stable call site.One prompt shape, one job. If two calls would be evaluated by different criteria — relevance scoring vs copywriting — they are different workloads even if they live in the same file. Routing operates here: you'll replace the model behind one call site at a time, never the whole app at once.

Key = environment. Captures record which key sent each request, so separate keys keep production evidence clean of staging noise — and tags can slice further (see Tag requests).

Wiring it up

Create the project on the dashboard (its slug is permanent), create workloads on the project's Workloads page, then send both headers as SDK defaults so every call site declares itself:

sdk defaults
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 ?? "",
    "x-understudy-project": "concierge",
    "x-understudy-workload": "ad-copy",
  },
});

Sites with multiple workloads per process typically build one client per workload, or set the workload header per call.

What unscoped traffic does

Requests without headers resolve to the default project (rehearsal) and its mainworkload. That's a feature for day one — traffic flows before any setup — and a smell later: a busy mainworkload means call sites haven't declared themselves yet, and their captures can't be told apart.