Hand-mocking Claude responses (covered in the mocking article) has one chronic weakness: the fixtures are only as accurate as your memory of the wire format. The VCR pattern fixes that. Named after the videocassette recorder, a VCR library sits at the HTTP layer; the first time a test runs, it lets the real request through and records the request/response pair to a file — the "cassette". Every later run intercepts the same request and replays the recorded response: no network, no API key, no token bill, no model nondeterminism. Your fixtures are real API output by construction.
The tooling by language
The pattern has a mature implementation in every ecosystem the official SDKs cover: vcrpy in Python (with pytest integration via pytest-recording), nock in Node/TypeScript, which can record real traffic and replay it, plus the various VCR ports in Ruby, Go, Java, PHP, and .NET. They all share the same three concepts: a cassette store (usually YAML or JSON files committed to the repo), a record mode (record once then always replay, versus refresh on demand), and matchers that decide when an incoming request "is" a recorded one. These are third-party open-source tools, not Anthropic products — consult each library's own documentation for configuration details.
Rule one: scrub credentials before the cassette hits git
A cassette records the entire request — including authentication headers. Recorded against Claude, that can capture real secrets, and the official documentation is blunt that API keys are long-lived secrets to be revoked when leaked. Configure your VCR library's header-filtering before the first recording, not after, and scrub at minimum:
| What | Where it appears |
|---|---|
API key (sk-ant-api...) | x-api-key request header |
| OAuth / WIF bearer tokens | Authorization: Bearer ... header |
| Cloud-platform signatures (e.g. AWS SigV4 headers and session tokens when recording against Bedrock or Claude Platform on AWS) | Signed request headers |
| Your own data | Request and response bodies — prompts and completions may contain customer content |
That last row deserves emphasis in an enterprise setting: a cassette is a copy of model input and output living in your repository. If the recorded conversation contained personal or confidential data, your repo now contains it too, subject to none of the retention controls you negotiated with your platform. Record against synthetic prompts wherever possible.
Making replay actually match
The default matcher in most VCR tools is method plus URL — too loose for Claude testing, since every call is a POST to the same messages endpoint. Two adjustments make cassettes reliable:
Match on the body. Include the request body (or selected fields like model and messages) in the matcher, so a test that changed its prompt fails loudly instead of replaying a stale answer. This also turns cassettes into a cheap contract test: if a refactor changes your serialized request, replay breaks and tells you.
Pin the nondeterminism. Timestamps, request IDs, and retry jitter vary between runs; either exclude those headers from matching or normalize them in a recorded-response hook.
Cassette lifecycle discipline
Cassettes rot. The API evolves, models are deprecated and retired on a published schedule, and a cassette recorded against a retired model tests a world that no longer exists. Three habits keep the pattern honest: re-record on a schedule (or whenever you bump SDK or model versions) using a record mode that refreshes stale cassettes from a real call with a scoped key; name cassettes after the test and the model so staleness is visible in review; and keep a thin live smoke-test suite alongside, because replay by definition cannot catch changes on the server side. Remember also that replayed tests exercise yesterday's response shape — treat cassettes as plumbing tests, and evaluate answer quality with deliberate live evaluation runs.
Where to go next
Pair this with unit-test mocking strategies for the full testing story, and see the tool-calling loop for the multi-request flows that benefit most from recorded sessions. The quickstart covers getting a scoped key for recording runs.