The argument on the other comparison pages is that a specification gives you shapes and shapes are not data. This page is that argument as a script. Seven requests, run against a public spec-derived mock of GitHub and against a pinned SandboxAPIs host, with both sets of real output pasted below.
01 / What spec-derived mock are good at
This page is not an argument that WireMock is bad. WireMock is an excellent tool, it is Apache-2.0, it has been maintained since 2011, and for defining the responses you want it is the right answer. Its GitHub template is also generated from GitHub's own OpenAPI description and covers far more paths than we serve.
It is an argument that an endpoint count and a data set are different products, and WireMock itself says so on the page: its shared sandbox returns simulated example data only, and the responses are fixed success cases. That sentence is easy to miss next to a figure like 1,222 endpoints, which is why this page exists.
Both columns below were captured by us on 16 September 2026, against the free public sandbox WireMock publishes and against our own pinned host. Every request is in the script. Run it and you should get what we got, because one side is frozen and the other is a fixed stub.
WireMock Cloud's GitHub template
A mock advertised at 1,222 endpoints and 1,275 stubs, with a free public sandbox anybody can call. Its own page states that it is not an official GitHub sandbox and that it returns simulated example data only; the sibling GitLab page adds that shared-sandbox responses are fixed success cases. Everything below is consistent with both sentences.
GitHub's own OpenAPI description
Version 1.1.4, which is what the template is generated from, and the reason its shapes are right. A specification defines what a field is called and what type it holds. It does not say who opened the pull request, so no tool generated from one can either.
The SandboxAPIs pin
gh-2026-03-g12.snap.sandboxapis.dev, a frozen snapshot host on the current data set. No key, no account, and byte-identical on every request, so the output printed below is the output you get when you run it.
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 | Spec-derived mock | SandboxAPIs |
|---|---|---|
| Endpoints covered | Their winMore than us, and this is their row outright. The template advertises 1,222 endpoints and 1,275 stubs, generated from GitHub's published OpenAPI description version 1.1.4. If your measure is how many paths answer at all, it wins and we do not. | Fewer paths, each carrying data. Our GitHub coverage is published endpoint by endpoint on the coverage manifest, and anything we do not serve returns GitHub's own 404 with a coverage header rather than a plausible empty object. |
| Does the repository you asked for come back | No. GET /repos/olympus-labs/parthenon answers with name "example-name" and full_name "octocat/Hello-World". The path parameters are not resolved, so every repository you ask for is the same repository. | Our winYes. The same request answers with name "parthenon", full_name "olympus-labs/parthenon", owner "olympus-labs". |
| Are there any pull requests in it | No. GET /repos/{owner}/{repo}/pulls returns an empty array, on every call we made. A client that lists and then walks finds nothing to walk. | Our winFive on the first page, the first being number 85, "Support graceful upstream draining in the API gateway", opened by jason. |
| Does a listed issue have a title and an author | The issues list answers, and its first entry has the literal title "example issue" with user null. A triage rule reading that list has nothing to triage on. | Our winIssue 85 carries the same title as the pull request that addresses it, and user "jason", who is a person you can fetch. |
| Is an organization lookup an organization | Partly. The type field does say "Organization", but the login is "octocat", which is a user, and the url on the object points at /orgs/github. The node_id is the same base64 string on repositories, organizations and commits alike, and it decodes to a user id. | Our winlogin "olympus-labs", type "Organization", and a node_id that decodes to this entity rather than to a user. |
| Is a commit SHA a commit SHA | No, and this is the clearest single result on the page. The first commit's sha is 42 characters long; a git SHA is 40. The object's own url names a different SHA entirely, commit.author is an empty object, and parents is an empty array. | Our win40 hexadecimal characters, the object's url names that same SHA, commit.author carries a name, an email and a date, and parents names the commit before it. |
| Does an author resolve to the right user | No. GET /users/jason returns login "octocat", company "GitHub". It answers, which is the point of a stub, but it answers with somebody else, so following a reference goes nowhere you asked to go. | Our winGET /users/jason returns jason, company "@olympus-labs", which is the same person the pull request and the issue name. Every reference resolves the same way. |
| Are the headers the vendor's headers | No. A listing returns matched-stub-name, plus vary and content-type. There is no link header, no x-github-api-version and no x-ratelimit family, so a client that paginates or backs off has nothing to read. | Our winA link header carrying rel="next", rel="first" and rel="last", plus x-github-api-version, x-github-media-type, x-github-request-id and the full x-ratelimit set. |
03 / Run it yourself
Seven requests against each host, no key and no account on either side, and nothing that writes. Paste the whole thing. The output underneath is exactly what this script printed for us on 16 September 2026, unedited.
WM=https://1k3k3.wiremockapi.cloud # WireMock Cloud's public GitHub template
SB=https://gh-2026-03-g12.snap.sandboxapis.dev # a frozen SandboxAPIs pin
for HOST in "$WM" "$SB"; do
echo "== $HOST"
# 1. the repository you actually asked for
curl -s "$HOST/repos/olympus-labs/parthenon" | jq -c '{name, full_name, owner: .owner.login}'
# 2. is there anything in it
curl -s "$HOST/repos/olympus-labs/parthenon/pulls" | jq -c 'length'
# 3. does a listed issue have a title and an author
curl -s "$HOST/repos/olympus-labs/parthenon/issues" | jq -c '.[0] | {number, title, user: .user.login}'
# 4. is an organization lookup an organization
curl -s "$HOST/orgs/olympus-labs" | jq -c '{login, type}'
# 5. is a commit SHA a commit SHA
curl -s "$HOST/repos/olympus-labs/parthenon/commits" \
| jq -c '.[0] | {sha_len: (.sha|length), sha, url_sha: (.url|split("/")|last), author: .commit.author}'
# 6. does an author resolve to the person you asked for
curl -s "$HOST/users/jason" | jq -c '{login, company}'
# 7. are the headers the vendor's headers
curl -s -D - -o /dev/null "$HOST/repos/olympus-labs/parthenon/issues?per_page=2" \
| grep -iE '^(link|x-ratelimit-limit|x-github-api-version|matched-stub-name)' | tr -d '\r'
echo
done== https://1k3k3.wiremockapi.cloud
{"name":"example-name","full_name":"octocat/Hello-World","owner":"octocat"}
0
{"number":1406266365,"title":"example issue","user":null}
{"login":"octocat","type":"Organization"}
{"sha_len":42,"sha":"abc123def456abc123def456abc123def456abc123","url_sha":"6dcb09b5b57875f334f61aebed695e2e4193db5e","author":{}}
{"login":"octocat","company":"GitHub"}
matched-stub-name: List repository issues
== https://gh-2026-03-g12.snap.sandboxapis.dev
{"name":"parthenon","full_name":"olympus-labs/parthenon","owner":"olympus-labs"}
5
{"number":85,"title":"Support graceful upstream draining in the API gateway","user":"jason"}
{"login":"olympus-labs","type":"Organization"}
{"sha_len":40,"sha":"6da56bead49874592a691b7a22eee0b59d3b72c3","url_sha":"6da56bead49874592a691b7a22eee0b59d3b72c3","author":{"name":"Athena","email":"athena@users.noreply.sandboxapis.dev","date":"2026-07-25T16:06:09Z"}}
{"login":"jason","company":"@olympus-labs"}
link: <https://gh-2026-03-g12.snap.sandboxapis.dev/repos/olympus-labs/parthenon/issues?per_page=2&page=2>; rel="next", <https://gh-2026-03-g12.snap.sandboxapis.dev/repos/olympus-labs/parthenon/issues?per_page=2&page=1>; rel="first", <https://gh-2026-03-g12.snap.sandboxapis.dev/repos/olympus-labs/parthenon/issues?per_page=2&page=20>; rel="last"
x-github-api-version: 2026-03-10
x-ratelimit-limit: 60Read the two blocks as one sentence: the left-hand host answers every request and knows nothing, and the right-hand host answers every request and knows who jason is. Both are legitimate products, and WireMock's own page says which one it is. Only the right-hand column supports a test that asserts on a value, follows a reference, or paginates.
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 the spec-derived mock
When to choose SandboxAPIs
Choose SandboxAPIs
05 / Sources
7 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.
Record and replay
VCR, Polly.JS, Nock, Hoverfly and recording proxies. A recording is the realest data there is, right up until the API moves or your test asks for something you never recorded.
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.