OpenAPI Mock Server Generator
Generate example responses from an OpenAPI spec and export a mock you run locally — MSW handlers, an Express server or plain fixtures. Reproducible from a seed.
OpenAPI spec
YAMLhandlers.ts
4 operations// Generated from Pet Store. Runs entirely in your project — nothing was uploaded.
import { http, HttpResponse } from "msw";
export const handlers = [
// List all pets
http.get("https://api.example.com/v1/pets", () =>
HttpResponse.json([
{
"id": 8095,
"name": "bravo",
"status": "sold",
"createdAt": "2026-07-30T09:14:22Z"
},
{
"id": 1465,
"name": "foxtrot",
"status": "available",
"createdAt": "2026-07-30T09:14:22Z"
}
], { status: 200 }),
),
// Add a pet
http.post("https://api.example.com/v1/pets", () =>
HttpResponse.json({
"id": 9586,
"name": "bravo",
"status": "sold",
"createdAt": "2026-07-30T09:14:22Z"
}, { status: 201 }),
),
// Fetch one pet
http.get("https://api.example.com/v1/pets/:petId", () =>
HttpResponse.json({
"id": 2224,
"name": "delta",
"status": "pending",
"createdAt": "2026-07-30T09:14:22Z"
}, { status: 200 }),
),
// Remove a pet
http.delete("https://api.example.com/v1/pets/:petId", () =>
new HttpResponse(null, { status: 204 }),
),
];
Preview a response
https://api.example.com/v1[
{
"id": 8095,
"name": "bravo",
"status": "sold",
"createdAt": "2026-07-30T09:14:22Z"
},
{
"id": 1465,
"name": "foxtrot",
"status": "available",
"createdAt": "2026-07-30T09:14:22Z"
}
]Generated values come from a seeded PRNG, so the same spec and seed always produce the same fixtures — which is what makes them safe to commit and assert against. An example in the spec is always used verbatim in preference to anything generated.
Not checked
the limits of a local validator- Request validation. The mock answers any request to the path, whatever the body or query string.
- Authentication. Security schemes in the spec are not enforced by the generated server.
- Stateful behaviour. A POST does not change what a later GET returns.
- Response selection. One status per operation is mocked; the others are listed but not served.
Generated in your browser — the spec is never uploaded, and nothing is hosted. To check the spec itself first, use the OpenAPI Validator; for a typed client rather than a mock, use the TypeScript Client Generator.
About the OpenAPI Mock Server Generator
This OpenAPI mock server generator turns a spec into example responses and a mock you run locally — MSW handlers for a front end, an Express file for anything else, or plain JSON fixtures. Paste the spec, pick an operation to preview what it would return, and copy the code.
It generates a mock rather than hosting one, and that is a deliberate trade. A hosted mock means running a server that accepts an uploaded spec and serves arbitrary user-defined responses from our origin, which is an open relay by another name. A generated mock avoids all of it — and is better for the usual case anyway, because a mock running inside your own test suite works offline, adds no network round trip, and can be committed alongside the code that depends on it.
Where the spec carries an example, that value is used verbatim. A spec author's example is real; substituting a plausible-looking generated value for it would discard the most accurate thing in the document. Generation only fills what the spec left unspecified, and every response says which of the two it is.
Generated values come from a seeded PRNG, so the same spec and seed always produce the same fixtures. That is the product rather than an implementation detail: a mock whose values change on every run cannot be committed and cannot be asserted against.
Scalar generation is format-aware. A field declared as date-time gets an ISO timestamp, not the word "string" — because a fixture that fails the consumer's own parsing is worse than no fixture at all.
- Three outputs from one spec: MSW handlers, an Express server, or raw JSON fixtures
- Spec examples used verbatim; generation only fills what the spec left out
- Seeded and reproducible, so fixtures can be committed and diffed
- Format-aware scalars — date-time, email, uuid, uri, ipv4 and more
- Respects enums, numeric bounds, allOf merging and $ref resolution
- Depth-limited, so a recursive schema terminates instead of hanging
- Per-operation preview, showing which statuses are mocked and which are not
How to use it
- Paste an OpenAPI 3.x document in YAML or JSON.
- Click through the operations to preview what each would return. The badge tells you whether the body came from the spec's own example or was generated.
- Change the seed if you want different values. The same seed always gives the same output.
- Pick your target: MSW if you are mocking fetch in a browser or test runner, Express if you need a real HTTP server, fixtures if you are wiring it up yourself.
- Copy the code into your project. MSW handlers go in your test setup; the Express file runs with node after npm i express.
- Add examples to your spec for anything that matters. They are used verbatim, so they are the way to make the mock realistic.
Real-world use cases
Frontend & client developers
Generate MSW handlers straight from the spec so UI work can start against a realistic mock before the backend endpoint exists, instead of hand-writing fixtures that drift from the actual contract.
Backend developers
Spin up the Express output as a stand-in for a service another team owns, so local development and integration work is not blocked on that service being reachable.
QA & test engineers
Commit the seeded fixtures alongside a test suite so assertions run against stable, reviewable values instead of data that changes shape on every run.
API product & platform teams
Use the per-operation preview to see, at a glance, which responses a spec would actually mock and which are left out — a quick way to spot gaps before publishing the specification.
DevOps & CI/CD engineers
Run the generated Express server in a CI job as a dependency stand-in for end-to-end tests, without provisioning or maintaining a real staging instance of the upstream API.
Examples
An MSW handler
GET /pets returning an array of Pet
http.get("https://api.example.com/v1/pets", () =>
HttpResponse.json([...], { status: 200 }),
),The full server URL from the spec is used, so the handler intercepts the same URL your client will call.
A 204 gets no body
delete: responses: { "204": { description: Deleted } }new HttpResponse(null, { status: 204 })HttpResponse.json always writes a body, including a literal null, which makes a 204 invalid. This is the case a naive generator gets wrong.
Formats are honoured
createdAt: { type: string, format: date-time }"createdAt": "2026-07-30T09:14:22Z"
A generated "string" here would fail every consumer that parses the field, which is most of them.
The declared success status is used
post: responses: { "201": {...} }status 201, with 400 listed as not mocked
The lowest 2xx is mocked, not always 200, and the statuses that were not mocked are listed rather than silently ignored.
Common errors
| Message | Cause | Fix |
|---|---|---|
| The mock returns null for a whole object | A $ref that could not be resolved — usually an external file reference, which is not available here. | The warnings panel names the ref. Bundle the spec into a single document first; most OpenAPI toolchains have a bundle command for exactly this. |
| Every string field says "alpha" or "bravo" | The schema declares type: string with no format, enum or example, so there is nothing to generate from. | Add an example to the schema. It is used verbatim, and it improves your documentation at the same time. |
| MSW does not intercept the request | The handler URL and the request URL differ — usually the spec's server URL is not the base URL the client actually uses. | Check the servers entry in the spec against your client's base URL, and edit the generated handlers if they differ between environments. |
| A field is missing from the mock response entirely | It is not in the schema's properties. The generator emits what the schema declares and nothing else. | That is a finding about the spec rather than the mock: your API returns a field it does not document. Add it to the schema. |
| Nesting was cut off at 6 levels | A recursive schema — a Node whose children are Nodes. Legal, common, and non-terminating for a naive generator. | Expected behaviour. Edit the generated fixture if you need a deeper example; the depth limit is what stops the page hanging. |
Frequently asked questions
›Why does this not host a mock server for me?
Because it would mean accepting an uploaded spec and serving arbitrary user-defined responses from our origin — a request-forwarding open relay with a real abuse surface, and the only thing on this site that would transmit your input. A mock you run locally also works offline, has no network latency in tests, and can be committed. The hosted version is worse for most uses, not just riskier for us.
›Is my API spec uploaded anywhere?
No. It is parsed and the mock generated entirely in your browser. That matters for an unreleased API, which is exactly the kind of spec you want to mock against.
›Does the generated mock validate requests?
No, and the "not checked" panel says so. It answers any request to the path with the mocked response, whatever the body, query string or authentication. It is a stub for shaping your client against, not a contract test.
›Why is the output the same every time?
Because the randomness is seeded. That is the point — a fixture whose values change on every run cannot be committed to a repository or asserted against in a test. Change the seed to get a different but equally stable set.
›Can it mock error responses?
One status per operation is mocked, and it is the lowest 2xx because that is what a client's happy path expects. The other declared statuses are listed in the preview so you know what was left out — edit the generated code to add them, which is usually a one-line change per case.
›What is the difference between the MSW and Express output?
MSW intercepts requests inside the browser or your test runner, so there is no server and no port. Express is a real HTTP server on localhost, which is what you want if the consumer is not JavaScript, or if you need something a colleague can point a tool at.
›Should I commit the generated fixtures?
Yes, that is what the seeding is for. A committed fixture makes the mock reviewable in a diff, and it means a change to your spec shows up as a change to the fixtures rather than as an intermittent test failure.
›Is this a replacement for a hosted mocking service?
Not for every use — it is a generator, not a hosted server, so there is no shareable URL to hand a non-technical stakeholder and no persistent mock running between visits. What it replaces is the step of hand-writing MSW handlers or an Express stub from a spec you already have. If you need a mock reachable from outside your own machine or CI job, that is a different category of tool.
Last updated