Mock any API / from the browser
Create one, or load the sample set.
02 Why a switchboard for your API
Front-end work should not wait for back-end endpoints. ApiSimul plugs a mock operator into your browser: it answers the calls your app already makes, with the data shape you decide.
Real interception, zero code changes
One click registers a Service Worker at the browser level. Your fetch() and XMLHttpRequest calls keep their real URLs — the operator answers before the network is ever touched. Uninstall it and everything returns to normal instantly.
Path params like a real router
Define routes such as /api/users/:id or /posts/:slug/comments. Captured segments feed back into the response through {{param.id}}, so the mock behaves like a resource-aware endpoint, not a static file.
Dynamic fake data, every call
Placeholders render fresh on each request: names, emails, UUIDs, integers in range, timestamps, avatars, and {{#repeat 5}} blocks that build whole JSON arrays. Your UI gets realistic lists and detail pages to lay out against.
Latency and status you control
Set 0–3000 ms of simulated delay and any status from 100 to 599. Reproduce the slow endpoint that breaks your spinner, the 404 that tests your empty state, or the 500 that exercises your error handling.
A live call log on the board
Every intercepted call is written to the log with time, method, URL, status, and whether it was mocked or passed through. Watch the switchboard light up as your app runs — debugging the request flow becomes reading a tape.
Rules travel with your team
Rules live in your browser's IndexedDB — nothing is uploaded. Export the whole board as JSON, commit it next to your front-end code, and teammates import the exact same mock set in one click.
03 Placeholder cheat sheet
Drop these into any response body. Unknown placeholders pass through untouched, so your templates never break.
| Placeholder | Returns | Example output |
|---|---|---|
| {{random.name}} | Full name from a seeded pool | Grace Hopper |
| {{random.email}} | Email built from the name pool | alan.turing@test.dev |
| {{number.int 1 100}} | Integer between min and max | 42 |
| {{number.float 0 1 2}} | Float with given decimals | 0.37 |
| {{number.bool}} | Literal true / false | true |
| {{string.uuid}} | UUID v4 | 3f8a1c… |
| {{string.lorem 12}} | N lorem words | lorem ipsum dolor… |
| {{string.id}} | Short random identifier | k3x9qz1a |
| {{date.iso}} | Current time, ISO 8601 | 2026-08-23T09:41:07Z |
| {{date.timestamp}} | Current time in milliseconds | 1755938467000 |
| {{image.avatar}} | SVG avatar as data URI (offline) | data:image/svg+xml,… |
| {{image.url 640 480}} | Photo URL at the given size | https://picsum.photos/… |
| {{param.id}} | Value captured from :id in the route | 42 |
| {{index}} | Iteration index inside a repeat block | 0, 1, 2… |
| {{#repeat 5}} … {{/repeat}} | Repeats the block N times as a JSON array | [{…},{…},…] |
04 Questions on the line
How does the interception actually work?
Which requests can be intercepted?
How do I make a list endpoint return 20 items?
{{#repeat 20}}{"id": {{index}}, "name": "{{random.name}}"}{{/repeat}}. Each iteration gets fresh random data and an {{index}} counter, and the block renders as a valid JSON array you can assign to a key in your response body.