Last Tuesday I had a Swagger spec, a frontend kanban board UI to build, and a backend team who promised the API would be ready "by Thursday for sure this time".
Forty-something endpoints. No real backend yet. Standup in four hours.
I've been here before — usually I spin up json-server, hand-write a routes file, deal with CORS, copy each endpoint's URL into a .env, and so on. By the time mocks are "done" I've spent more time on plumbing than on the UI I was supposed to be working on.
This time I did something different. I pasted the spec into a tool called MockBolt, clicked one button, and got back 40 live public URLs — one per operation, each returning the example response from the spec.
Total time: about two seconds.
This is the story of that two seconds, what it actually does behind the scenes, and the couple of gotchas you should know about.
What I pasted
Here's a trimmed-down version of the spec — same shape as what you'd get out of FastAPI's /openapi.json, NestJS's Swagger module, or any tool that follows the OpenAPI 3.x format:
openapi: "3.0.0"
info:
title: Kanban API
version: "1.0.0"
paths:
/boards:
get:
summary: List all boards
responses:
"200":
content:
application/json:
example:
boards:
- { id: 1, name: "Sprint 12", cards: 18 }
- { id: 2, name: "Backlog", cards: 47 }
post:
summary: Create a board
responses:
"201":
content:
application/json:
example:
id: 3
name: "New Board"
cards: 0
/boards/{id}/cards:
get:
responses:
"200":
content:
application/json:
schema:
$ref: "#/components/schemas/Card"
components:
schemas:
Card:
type: object
properties:
id: { type: integer }
title: { type: string }
assignee: { type: string }
Nothing special — just a normal OpenAPI 3.0 spec in YAML. Real one had 40 operations across 12 paths. I'll show three here so this article fits on one page.
What happened when I pasted
[Screenshot 1: the MockBolt /openapi-import page with the spec pasted into the editor, "Parse spec" button visible at the bottom right]
I hit Parse spec. The page switched to a preview list:
[Screenshot 2: the preview list with each endpoint as a checkbox row — METHOD, path, status code, "synthesised" badge on the one that fell back to schema]
Three rows for three operations. Each one shows:
- The HTTP method (with a colour-coded badge)
- The original path from the spec
- The status code the mock will return (matches the response code from the spec —
201for POST,200for GET, etc.) - A small
synthesisedbadge on any row where the response had to be generated from the schema because the spec didn't include a literal example
I left all three selected, hit Create 3 mocks →, and a couple of seconds later got the result page:
[Screenshot 3: the "Done" page with the three URLs listed, each with a Copy button and a Manage link]
GET /boards → https://mockbolt.com/b/8e47…
POST /boards → https://mockbolt.com/b/3f91…
GET /boards/{id}/cards → https://mockbolt.com/b/c2a8…
Each URL is live, public, and returns the example I defined in the spec. I tested the first one immediately:
$ curl https://mockbolt.com/b/8e47…
{
"boards": [
{ "id": 1, "name": "Sprint 12", "cards": 18 },
{ "id": 2, "name": "Backlog", "cards": 47 }
]
}
Same JSON I put in the spec. Open CORS, so my React app could hit it directly from localhost:3000 with no proxy. I dropped the URLs into .env, pointed my fetches at them, and went back to building the actual UI.
How it figures out the response
This is the part I dug into, because I was curious what happens when a spec doesn't have an explicit example field (which is, honestly, most specs).
The parser walks each response with a fallback chain. For OpenAPI 3.x:
-
Direct example:
responses: "200": content: application/json: example: # ← takes this foo: "bar" -
Named examples map (it picks the first one):
content: application/json: examples: happy_path: # ← takes .value of the first value: { foo: "bar" } -
Schema-level example:
content: application/json: schema: type: object example: # ← takes this foo: "bar" -
Synthesised from schema shape:
schema: type: object properties: id: { type: integer } # → 0 title: { type: string } # → "string" assignee: { type: string } # → "string"$refis resolved recursively (with a depth limit to prevent infinite loops on circular references), and the resulting JSON is what the mock returns. It's not pretty data, but it's structurally valid — your TypeScript types won't complain. Fallback to
{}if there's no schema either.
Mocks created from steps 4 and 5 get the synthesised badge in the preview list, so you know which ones to either (a) live with, (b) edit on the mock's manage page after import, or (c) go back and add real examples to your spec.
Swagger 2.0 follows a similar fallback (examples["application/json"] → schema.example → synthesis), just with different field names.
Two gotchas worth knowing
The mock URL is not your spec path.
Every mock gets a random /b/{uuid} URL. The path from your spec (/boards/{id}/cards) is shown as a label so you can map them mentally, but if your client code expects /boards/... you need to either rewrite it to point at the mock URL, or set up a local proxy that maps spec paths to mock URLs. Most of the time the rewrite is fine for dev work.
Request body and query params are ignored by default.
The mock always returns the same example response. It doesn't check that you sent the right query params, didn't validate your POST body against the schema, doesn't return a different shape for /boards?archived=true. If you need that, every mock has a manage page where you can configure error-rate simulation, header-triggered errors, response delays, dynamic variables ({{uuid}}, {{timestamp}}), and so on — but you're configuring it per mock, by hand.
Honestly, for most "frontend dev wants to start before backend is ready" cases, that's fine. You want representative data, not contract enforcement.
When NOT to use this
-
You need contract testing. Use something like Prism (
@stoplight/prism-cli) which actually validates requests against the spec. - You're testing complex multi-route behaviours with conditionals, state, scripted responses. Mockoon's desktop app or a real local mock server is closer to what you want.
- You can't have your mocks on a public URL. MockBolt URLs are public (unlisted, but anyone with the URL can hit them). If you need private mocks, run something local.
For everything else — sharing mock URLs with the team, demos, mobile dev where localhost is painful, CI integration tests that need a stable HTTPS endpoint — public mocks are exactly right.
Try it
Open https://mockbolt.com/openapi-import, hit Use sample if you don't have a spec handy, and watch your endpoint count go from 0 to N in a couple of seconds.
No signup, free, up to 50 mocks per import.
If you find yourself coming back to it (or want the mocks to outlive their 7-day free window), each one has a $2 one-time → permanent button on its manage page. I upgraded the three I built the kanban board against, because by the time the real backend shipped, the mock URLs were in three Slack threads and a doc, and I didn't want them disappearing.
Curious to hear what specs people import — especially the weird-shaped ones the parser hasn't seen yet. Drop a comment if anything breaks.
Top comments (0)