A cassette holds one true response per request you happened to make, captured from a real account. It is the most realistic fixture anybody can get, and it is also the one that goes stale, that only covers the paths you walked, and that puts your production data in your repository. This page is about that trade.
01 / What record and replay are good at
Recording is the most realistic fixture anybody can get, and nothing on this page beats it on that axis. The bytes in a cassette are bytes a real API really sent, including the header you would never have thought to fake and the field the documentation forgot. For debugging one specific broken interaction, a recording is exactly right.
These are also mature, careful tools. VCR named the category and has been at it since 2010. Polly.JS covers five JavaScript runtimes and writes standard HAR. Hoverfly is a proxy rather than a library, so it works for a client in any language. Proxyman decrypts traffic from a phone and hands the same capture to an AI agent over MCP.
The trade they all make is the same one, and their own documentation is where it is stated best. VCR's docs put it plainly: over time, your cassettes may get out of date, because APIs change and sites you scrape get updated. That, plus the fact that a recording only ever holds the requests you happened to make, is the whole difference below.
VCR
The Ruby original, and the tool that named the category. In its own words it records your test suite's HTTP interactions and replays them during future test runs for fast, deterministic, accurate tests. Cassettes are YAML by default, and requests match on method and URI unless you say otherwise. Licensed under the Hippocratic License 2.1 rather than a conventional permissive licence.
Polly.JS
From Netflix, Apache-2.0. A standalone, framework-agnostic JavaScript library for recording, replaying and stubbing HTTP interactions. Adapters cover fetch, XHR, Node's http, Puppeteer and Playwright; recordings are written as HAR files. Matching is strict by default: method, headers, body and order all count.
Nock
MIT, and in its own words an HTTP server mocking and expectations library for Node.js. It works by overriding Node's http.request and http.ClientRequest. Its recorder emits JavaScript source code you paste into a test rather than a cassette file, and Nock Back adds fixture modes: wild, dryrun, record, update and lockdown.
Hoverfly
Apache-2.0, a lightweight open source API simulation tool. Unlike the libraries above it is a real proxy, so it is language-agnostic: it sits between your client and the service, records in Capture mode and answers in Simulate mode, where no traffic ever reaches the real API. Simulations are JSON you can export, edit and re-import.
Proxyman
Commercial, from $89 for a single-device licence or $12 per seat per month on a team subscription. A native capture-and-decrypt debugger for macOS, Windows, Linux, iOS and Android that imports and exports HAR 1.2, with Map Local and Map Remote for serving a captured body back. It is also the only tool on this page that ships an MCP server.
02 / Side by side
Every cell below describes what each approach does by definition, not what any one product happens to ship this quarter. Our column says where we lose: we are read-only, we replicate a fixed set of services rather than every API, and a pinned host never changes while the live hosts re-roll every day. Check any vendor's own docs against the sources at the foot of this page.
| Dimension | Record and replay | SandboxAPIs |
|---|---|---|
| Setup time | Fast to install, and then blocked on the thing you were avoiding: to record, you need a real account on the real API, with a real token, holding data worth recording. The first cassette costs whatever that account costs. | Our winOne base URL, no account, no capture step. The data set is already there and you never point anything at a real vendor. |
| Realism of the data | Their winUnbeatable, and this is their honest win: the bytes are the bytes the real API really sent. The cost is on the same line, because those bytes are your account's real data, sitting in your repository. VCR documents filter_sensitive_data for exactly this and warns that the value you are scrubbing may already have been escaped or encoded. | Generated rather than captured, which means it is coherent and detailed but it is not any real company's. There is nothing to redact because nothing real was ever there, and a repro case is safe to paste into a public issue. |
| Coherence across services | Whatever you recorded, and nothing else. A recorded pull request names an author, but the author is not a user you can then fetch unless you happened to fetch them during the capture. Follow a link out of a cassette and you fall off the recording. | Our winEvery reference resolves, by construction. One canon is compiled into every service's dialect, so the same incident is a Slack thread, a ticket, an issue and a merge request, and both git hosts agree on the head SHA. |
| Determinism over time | BothYes while the file is untouched, and VCR and Polly both put the word deterministic in their own description. The asterisk is theirs too: the file is a snapshot of an API that keeps moving, and nothing in the replay path can tell you it has diverged. | BothYes, and checked. A pinned host stores no bytes at all: it regenerates them from a recipe, and CI proves byte-identity on every run by generating, deleting and regenerating. |
| Write support | Their winBetter than ours. You can record a POST and replay its response, so a client that writes gets a plausible answer back. It is a replay rather than a state machine, so a subsequent read does not see the write. | No. Every write is refused with the vendor's own status and error body naming what was attempted. Deliberate: nothing can mutate a pinned host, which is what makes it safe in CI a year from now. |
| Rate-limit and error realism | BothGenuinely strong: a capture preserves the real headers and the real error body verbatim, because it did not have to understand them. Limited to the responses you actually provoked, so the 429 you never triggered is not in the cassette. | BothThe vendor's real pagination and rate-limit headers on every response, validated against the vendor's own published spec on every CI run. A header lets a caller ask any host for a rate-limit, server-error, timeout or latency response on demand, including the ones you could never provoke on purpose. |
| Cost | BothThe libraries are free: Polly.JS and Hoverfly are Apache-2.0, Nock and mitmproxy are MIT, and VCR is under the Hippocratic License 2.1, which is worth reading if your legal review cares about licence conventions. Proxyman is commercial, from $89 for one device or $12 per seat per month. The hidden cost is the real API quota you burn recording and re-recording. | BothFree with no account at 60 requests an hour, free with a key at 600, and paid plans from $5 a month. No vendor quota is consumed at any point, because no vendor is involved. |
| Maintenance burden | The category's defining problem, and its own docs say so: over time your cassettes may get out of date, because APIs change. Refreshing means running the capture against the real account again, then re-scrubbing whatever came back with it. | Our winOurs. Every covered response is validated against the vendor's vendored, sha-pinned specification on every CI run, and when a vendor retires an endpoint the live hosts drop it while pins frozen before it keep serving. |
| Works for AI-agent tests | Poorly, and not through any fault of the design. An agent asks for things nobody anticipated, and an unrecorded request is exactly what these tools are built to refuse: VCR's default record mode raises an error for a request with no match, and Polly's default mode is replay. | Our winThe whole read surface answers, so the agent can wander. Where we do not cover something it gets the vendor's own 404 plus a coverage header, never a silent null and never an invented value. |
| Works in CI | Their winTheir strongest row. The recording is a file in your repository, so the test runs offline, in process, with no third party in the path and no network at all. | Yes, against a pinned host that returns identical bytes in a year, but it is a network call to a service we operate. That is a real dependency and the honest mitigation is the pin, not a promise. |
03 / Run it yourself
Two things a recording cannot do, in one paste. First, answer a request nobody thought to record. Second, prove it will answer the same way next year. Both run against a pinned host, with no key and no account.
GH=https://gh-2026-03-g6.snap.sandboxapis.dev
# 1. A path you would never have captured: the comment thread on one issue.
curl -s "$GH/repos/olympus-labs/parthenon/issues/79/comments" \
| jq '[.[] | {user: .user.login, created_at, body}]'
# 2. The same request twice. A cassette is a file; this is a recipe.
curl -s "$GH/repos/olympus-labs/parthenon/pulls/47" | shasum -a 256
curl -s "$GH/repos/olympus-labs/parthenon/pulls/47" | shasum -a 256[
{
"user": "icarus",
"created_at": "2026-07-19T15:43:04Z",
"body": "This might regress the bundle size of the settings page - did you check?"
},
{
"user": "clio",
"created_at": "2026-07-20T08:43:04Z",
"body": "Consider using the retry helper here instead of hand-rolling the loop."
}
]
f3d42cb6b397378f1dffef45bdfa1e8cd828ea6f0f3cec9189fe209be5ba0067 -
f3d42cb6b397378f1dffef45bdfa1e8cd828ea6f0f3cec9189fe209be5ba0067 -Nobody recorded issue 79's comments, and nobody wrote them either. They exist because two simulated engineers reviewed a change during the ninety days the generator modelled, and both of them are users you can fetch. The two hashes are the second half: a pinned host does not store the response, it regenerates it, so the bytes are the same bytes after a cache eviction, on another machine, and in two years. A cassette gives you the second property and not the first.
That host is a pinned snapshot, so those bytes are the bytes you get next year too. The live hosts re-roll daily with new activity, which is the right choice for a demo and the wrong one for an assertion. See versioning and pinning.
04 / Picking one
When to choose the other thing
Choose record and replay
When to choose SandboxAPIs
Choose SandboxAPIs
05 / Sources
17 sources, each read on the date beside it. If one of these pages has changed since and a cell above is now wrong, that is a bug in this page: tell us and we will fix it.
Mocking and stubbing libraries
WireMock, Prism, Mockoon, MSW and Postman mock servers. They give you any endpoint you can describe. We give you 21 real ones you did not have to describe.
The vendors' own sandboxes
Atlassian developer instances, Slack developer sandboxes, HubSpot test accounts, Stripe's test mode. The real software, every time. Empty, every time, and one signup per vendor.
Agent twins and simulated services
Arga Labs, WonderTwin, FetchSandbox and Reqres build simulated services for agents too. Where they are better, where we are, and what each one costs.
Prove it: seven requests, both sides
A spec-derived mock of GitHub and our replica of GitHub, asked the same eight questions. Both sets of output were captured by us and both are rerunnable.