REST API Playground & Mock Server
Send requests to a simulated server or your own API, then break things on purpose: inject errors and timeouts and watch how retries behave. Runs in your browser, or as a mock API on your machine with npx tinypdf-mock.
Local server
- In a terminal, run
npx tinypdf-mock. It needs Node.js 18 or newer and installs nothing else. - Paste the address it prints. It looks like
http://localhost:4747/#k=…
The server runs on your own machine and this page talks to it directly; nothing passes through TinyPDF. If your browser refuses the connection, open the control page the server prints (http://localhost:4747/__mock/): it is this same page, served from your machine.
The mock API is at
- To call your own API: type its address in the request form below, for example
http://localhost:8080/users, and press Send. It can be on any port. Your API needs no changes and no CORS headers. - To give your app a mock API: point your app or service at the address above. Each request it makes shows up under Requests received, and Server behavior and Mock routes change what the mock answers, straight away.
1. Request
Simulator paths: /items /items/1 /secure /status/503 /delay/1500 /headers, plus your own mock routes. Press Ctrl+Enter to send.
The local server sends this request for you, so any address works: the mock itself, or your own API on another port, such as http://localhost:8080/users. There are no CORS limits and no blocked headers. Press Ctrl+Enter to send.
Your browser sends the request straight to this address, so the server must allow cross-origin requests (CORS). Nothing is saved, but do not paste secrets you would not type into any web page. Response headers the server does not expose to browsers will not appear, and that can include Retry-After.
Headers
Body
2. Server behavior
These settings change the mock API on this server, for every program that calls it. They do not affect other addresses you send requests to, such as your own API.
3. Retry policy
Used when you press Send here. Your own app keeps its own retry code; use this to try a policy before you write it.
Retry on
4. Mock routes
Your own endpoints, checked before the demo routes. A path can hold parts like :id. A body can use {{params.id}}, {{query.q}}, {{body.name}}, {{now}} and {{uuid}}.
To serve these routes to a real app, download mock.json and run npx tinypdf-mock in the same folder.
Requests received
Nothing yet. Call the server from your app, a terminal or the request form and each request appears here.
| Time | Request | Answer | Took |
|---|
Result
| # | Starts | Took | Result | Then |
|---|
Final response
Request as the server saw it
Compare retry strategies
Copy as code
The simulator is a model of how APIs fail, not a benchmark of any real server. It lives inside this page, so other programs cannot call it; for that, run the local server with npx tinypdf-mock.
About this REST API playground
Most API client bugs show up only when something goes wrong: a 503 during a deploy, a 429 from a rate limiter, a response that never arrives. This playground lets you cause those failures on demand and watch what a client does. Pick a problem to inject, choose a retry policy, and the timeline shows every attempt, every wait and the reason for each decision.
Use Simulator mode to experiment safely with a mock API that runs inside your browser tab. Switch to Local server mode to run the same mock on your own machine, where your app can call it. Switch to Real URL mode to send the request from your browser to your own API.
Use it as a mock API on your machine
The simulator cannot be reached by other programs, because it only exists inside this page. The tinypdf-mock package runs the same mock as a small server on your machine. It needs Node.js 18 or newer and has no other dependencies. It is free and open source: you can read the code on GitHub before you run it.
npx tinypdf-mock # mock API on http://localhost:4747 npx tinypdf-mock init # write a starter mock.json, then edit it npx tinypdf-mock --fault fail-first-n:n=2,status=503
| If you build | Use it to |
|---|---|
| A frontend | Point your app at http://localhost:4747 before the real API exists. Describe the endpoints as mock routes, then switch on slow answers, 500s or a dropped connection and see whether your loading and error screens hold up. CORS headers are sent for you. |
| A backend, to call it | Send requests to your own API from the request form, on any port, with a retry policy and a timeline of each attempt. See Call your own local API from this page. |
| A backend, to test what it depends on | Put it in place of a service your code depends on, such as a payment or email API. Make it answer 429 with Retry-After, fail twice and then succeed, or accept the request and lose the response, and check that your retry code does the right thing. Each request your service sends is listed with its headers and body. |
| Tests | Start it from a test with require('tinypdf-mock'), set a fault, run your client and assert on the requests it received. |
While the server runs, this page (or the copy the server serves at /__mock/) shows each request as it arrives and lets you change routes and faults without a restart. It can also send requests through the local server, which removes the two limits a browser has: CORS and blocked headers such as Cookie.
Mock a flow of several API calls
A checkout, a sign-up or an order often calls several APIs one after another. Give each call its own route in mock.json and one npx tinypdf-mock answers all of them, in the order your code calls them. For example, a token, then a stock check, then a payment:
{ "routes": [
{ "method": "POST", "path": "/auth/token",
"body": { "access_token": "test-{{uuid}}", "expires_in": 3600 } },
{ "method": "GET", "path": "/inventory/:sku",
"body": { "sku": "{{params.sku}}", "inStock": true, "qty": 12 } },
{ "method": "POST", "path": "/payments", "status": 201,
"body": { "id": "{{uuid}}", "amount": "{{body.amount}}", "status": "paid" } }
]}
Run npx tinypdf-mock in the folder with this file and point your service at http://localhost:4747. Values in {{ }} are filled from each request, so answers can carry the id or amount that was sent.
| You want to | Do this |
|---|---|
| Mock three different services at once | Point all three base addresses at the same mock if their paths do not clash. If they do, run one mock per service on its own port: npx tinypdf-mock auth.json -p 4747, npx tinypdf-mock stock.json -p 4748, npx tinypdf-mock pay.json -p 4749. |
| Make one step fail | Add a fault to that route only, for example "fault": "fail-first-n:n=1,status=503" on /payments, and check that your code retries that step and not the whole flow. "delayMs": 3000 makes one step slow. |
| See what your code sent, in order | Open http://localhost:4747/__mock/: every request is listed as it arrives, with its headers, body and the answer it got. In tests, mock.requests() gives the same list. |
| Run the flow in CI | Start the mock in the pipeline with npx, or from the test code with require('tinypdf-mock'), before the tests that call your service. |
Each route gives the same answer every time, apart from the "first N fail" fault. A route that has to answer differently on each call, such as a payment that is pending twice and then paid, is not supported yet.
Call your own local API from this page
If you have an API running on your machine, for example on http://localhost:8080, you can send requests to it from this page in two ways.
| Way | Steps | Needs |
|---|---|---|
| Local server (works with any API) | 1. Run npx tinypdf-mock in a terminal.2. Choose Local server above and paste the address it prints. 3. Type your API's address in the request form, such as http://localhost:8080/users, and press Send. | Node.js 18 or newer. No change to your API. |
| Real URL (nothing to install) | 1. Choose Real URL above. 2. Type your API's address and press Send. | Your API must send CORS headers that allow https://tinypdf.in. Without them the browser reports "Failed to fetch". |
With the local server, the request is sent from your machine, not from the browser, so there are no CORS rules, blocked headers such as Cookie can be sent, and a failed connection shows its real cause. The retry policy applies in both ways. The problems under Server behavior apply to the mock API only; they do not change what your own API answers.
If your API needs a login, token or key
Add the credentials under Headers in the request form, the same way any API client sends them. The page sends the headers you enter and nothing else.
| Your API uses | Add this header |
|---|---|
| Bearer token or JWT | Authorization: Bearer your-token |
| API key | The header your API expects, such as X-API-Key: your-key |
| Basic auth | Authorization: Basic followed by the base64 form of user:password |
| Session cookie | Cookie: session=... Local server mode only; browsers do not let a page set this header, so it is dropped in Real URL mode |
| CSRF token | The token header your API expects, together with the cookie |
| HTTPS with a self-signed certificate | No header. Start the local server with npx tinypdf-mock --insecure, or the certificate is refused |
The page does not log in for you. Get a token the way your app does, for example by calling your login endpoint from the request form and copying the token from the response. Client certificates (mutual TLS) are not supported. Wrong or missing credentials show as your API's 401 or 403, which are not retried, because sending the same request again cannot fix them.
In Real URL mode an Authorization header makes the browser ask your API for permission first, so your API has to allow that header in its CORS settings as well as this site. Local server mode has no such step.
Where your token goes: in Local server mode, from this page to the server on your machine and on to your API; in Real URL mode, from your browser straight to your API. It never passes through TinyPDF and is not saved; reloading the page clears it. Links made with "Copy link to this setup" exist only in Simulator mode, so a token cannot end up in one. "Copy as code" does include the headers you typed, so check a snippet before sharing it.
How the backoff strategies differ
| Strategy | Wait before retry n | Good for |
|---|---|---|
| Fixed | The same every time | Simple scripts and low traffic |
| Linear | Base x n | Gentle growth when outages are short |
| Exponential | Base x 2n-1, up to a maximum | Giving a struggling server room to recover |
| Full jitter | Random between 0 and the exponential value | Many clients that fail at the same moment |
| Equal jitter | Half the exponential value plus a random half | Spreading load while keeping a minimum wait |
Questions
Does this REST API playground call a real server?
In Simulator mode, no. Requests go to a mock server that runs inside your browser tab, so nothing is sent over the network. In Local server mode requests go to the mock server running on your own machine. In Real URL mode your browser sends the request straight to the address you enter.
Can my app or another program call the mock API?
Not the simulator, because it only exists inside the page. Run npx tinypdf-mock and the same mock API, with the same faults and your own routes, listens on http://localhost:4747 where any program on your machine can call it.
Is tinypdf-mock open source? Is it safe to run?
Yes. It is free, MIT licensed, and the full source is on GitHub. It has no dependencies, listens only on localhost, sends no telemetry, and makes an outgoing request only when you press Send. It is a few plain JavaScript files, so you can read it before you run it.
How do I call my own API running on localhost?
Run npx tinypdf-mock, choose Local server and paste the address it prints. Then type the address of your API in the request form, for example http://localhost:8080/users, and press Send. Your API can be on any port and needs no CORS headers, because the request is sent from your machine and not from the browser. Without installing anything, Real URL mode also works if your API allows cross-origin requests from https://tinypdf.in.
Can I call an API that needs a token, API key or login?
Yes. Add the credentials under Headers in the request form, for example Authorization: Bearer your-token or X-API-Key: your-key. Cookie headers work in Local server mode only, because browsers block them. The page does not log in for you, so get a token the way your app does and paste it in. In Local server mode the token goes from the page to the server on your machine and on to your API; it never passes through TinyPDF and is not saved.
How do I mock an API for a frontend that is not built yet?
Add your endpoints under Mock routes, download mock.json, and run npx tinypdf-mock in the folder that holds it. Point your app at http://localhost:4747. CORS headers are sent for you, and you can add delays and errors to see your loading and error states.
How do I mock several API calls that my service makes one after another?
Give each call its own route in mock.json, for example POST /auth/token, GET /inventory/:sku and POST /payments, and run npx tinypdf-mock in that folder. Point your service at http://localhost:4747; the mock answers each call with its route, filling values such as the id or amount from the request. The control page at http://localhost:4747/__mock/ lists every call in order with what was sent and returned.
Can I mock three different services at the same time?
Yes. Point all of their base addresses at one mock if their paths do not clash, or run one mock per service on its own port, for example npx tinypdf-mock auth.json -p 4747, npx tinypdf-mock stock.json -p 4748 and npx tinypdf-mock pay.json -p 4749.
Can one endpoint return a different response on each call?
Only for failures today: the fail-first-n fault makes the first calls fail and then lets the route answer. A list of answers per route, such as pending, pending and then paid for a payment status, is not supported yet.
How do I test how my backend handles a failing third-party API?
Run npx tinypdf-mock, set the base address of the third-party client in your service to http://localhost:4747, and pick a problem under Server behavior, such as 429 with Retry-After or a dropped connection. The page lists every request your service sends, with headers and body, so you can count the retries.
Can the page on tinypdf.in connect to a server on my machine?
Yes. Choose Local server and paste the address the command prints. Your browser may ask for permission to reach devices on your local network. If it refuses, open http://localhost:4747/__mock/ instead, which is the same page served from your machine.
Why does a real request fail with Failed to fetch?
Browsers hide the exact reason. The usual cause is CORS: the server must send an Access-Control-Allow-Origin header that allows this page. Other causes are a wrong address, being offline, or calling an http address from an https page. Local server mode sends the request from your machine instead, so CORS does not apply and you see the real error.
Which headers can I not set from a browser?
Browsers refuse to set forbidden headers such as Cookie, Host, Origin, Referer and Content-Length, and anything starting with Sec- or Proxy-. The simulator marks them and drops them, as a browser would. Local server mode can send them.
What is the difference between exponential backoff and jitter?
Exponential backoff doubles the wait after every failure. Jitter adds randomness so that many clients that failed together do not all retry at the same moment.
Is it safe to retry a POST request?
Only if the server can recognise a repeat. A POST that timed out may already have been processed. Send an Idempotency-Key header so the server returns the first result instead of doing the work twice.
Is my data uploaded to TinyPDF?
No. In Simulator mode nothing leaves your device. In Local server mode everything stays between your browser and the server on your machine. In Real URL mode the request goes directly from your browser to the address you enter, not through TinyPDF. Headers and bodies are not saved.
