Documentation

MockServer · Everything you need to mock your APIs

Getting Started

MockServer lets you create live HTTP mock endpoints in seconds — no backend code, no servers, no config files. There are two ways to get started:

Option A — Quick Mocks (no signup)

  1. Go to /quick — no account needed.
  2. Configure your response: method, status code, JSON payload, optional delay and fail rate.
  3. Click Generate Mock — you get a live URL instantly, valid for 72 hours.

Option B — Full account (persistent mocks + traffic logs)

  1. Sign in with Google or GitHub. We create your account and a unique slug automatically.
  2. Create a mock — pick a method, set a path, paste your JSON, choose a status code.
  3. Hit your endpoint from Postman, cURL, your frontend — wherever you need it.
  4. Watch traffic flow in via the real-time logs page.

Quick Mocks — No Signup Required

Quick Mocks let you create a live, hittable endpoint in seconds — no account, no dashboard, no sign-in needed. Paste your JSON, configure options, and get a URL back instantly.

How to create a Quick Mock

  1. Go to /quick
  2. Choose a method and status code, paste your JSON response.
  3. Optionally configure delay range and fail rate (see Latency Simulation and Intermittent Failures).
  4. Click Generate Mock — your URL is live immediately.
Your Quick Mock URL
https://mockserver.in/m/{shortId}

# Example
https://mockserver.in/m/x4t9rn2k

Editing a Quick Mock

After creation, you'll receive an edit URL containing a secret token. Bookmark it or save it — this is the only way to update your mock:

Edit URL format
https://mockserver.in/m/{shortId}/edit?token={editToken}

Your browser stores the edit URL automatically so you can return to it without a bookmark.

Expiry

Quick Mocks expire after 72 hours. After that, the endpoint returns a 410 Gone response. Sign up for a free account to get permanent mocks.

Quick Mocks respond to any HTTP method regardless of the method you set during creation — the method field is informational only.

Limits

  • Payload size: up to 200,000 characters
  • Expires: 72 hours after creation
  • Custom headers: up to 20 per mock

Your API URL

Every MockServer account gets a unique URL slug (e.g., dark-storm-3765). All your mocks are served under:

Endpoint format
https://mockserver.in/api/{your-slug}/{path}

You can find your slug in the Dashboard or the sidebar footer. It is globally unique and permanent.

Your slug is shown in the left sidebar (e.g., dark-storm-3765). All your mock paths live under it.

Fake REST API — Overview & Base URL

The Fake REST API is a free, hosted API with ready-made sample data. Unlike your own mocks, you don't create or configure anything — the endpoints and data already exist and are the same for everyone. Use it when you just need an API that works: tutorials, prototypes, UI development, interview exercises, or testing an HTTP client.

Base URL
https://mockserver.in/fake-api/v1/{resource}

# Example — try it right now in your terminal:
curl https://mockserver.in/fake-api/v1/users
  • No signup, no API key — every endpoint is public.
  • CORS enabled — call it directly from any browser app.
  • Stable data — the datasets never change, so your tests are deterministic.
  • JSONPlaceholder-compatible — same pagination and write conventions.
Want to see the data before writing code? Browse every record visually in the Data Explorer.

Fake API — Available Resources

Five datasets are available. Each row links to a dedicated reference page with live "try it" examples:

ResourceRecordsFiltersNested routes
/users 60?username= /users/{id}/posts · /users/{id}/todos
/posts 100?userId= /posts/{id}/comments
/comments 300?postId=
/todos 150?userId= · ?completed=
/products 100?category= · ?brand=

The datasets are relational: every post has a userId, every comment a postId, every todo a userId — so you can build master-detail UIs exactly like against a real backend.

Fake API — Reading Data, Case by Case

Case 1 — Get a whole collection

GET /fake-api/v1/posts
curl https://mockserver.in/fake-api/v1/posts

// Returns a JSON array of all 100 posts:
[
  {
    "id": 1,
    "userId": 56,
    "title": "How to Learn a New Language Without Losing Your Mind",
    "body": "I kept a simple log of what worked and what did not...",
    "tags": ["tech"]
  },
  ...
]

Case 2 — Get a single record by id

GET /fake-api/v1/users/1
curl https://mockserver.in/fake-api/v1/users/1

// Returns one object (404 JSON error if the id doesn't exist):
{
  "id": 1,
  "name": "Jared Roob",
  "username": "jared.roob",
  "email": "jared.roob@example.org",
  "address": { "city": "...", "geo": { "lat": ..., "lng": ... } },
  "company": { "name": "...", "catchPhrase": "..." }
}

Case 3 — Get related (nested) records

Nested routes return the children of a record, joined by the foreign key:

GET /fake-api/v1/posts/1/comments
curl https://mockserver.in/fake-api/v1/posts/1/comments
# → all comments where postId = 1

curl https://mockserver.in/fake-api/v1/users/5/posts
# → all posts where userId = 5

curl https://mockserver.in/fake-api/v1/users/5/todos
# → all todos where userId = 5

Fake API — Pagination & Filtering

Case 4 — Paginate a collection

Use ?_page= and ?_limit= (the same convention as JSONPlaceholder). The total record count always arrives in the X-Total-Count response header, so you can render page controls:

GET /fake-api/v1/posts?_page=2&_limit=10
curl -i "https://mockserver.in/fake-api/v1/posts?_page=2&_limit=10"

HTTP/1.1 200 OK
X-Total-Count: 100
Access-Control-Expose-Headers: X-Total-Count

[ ...posts 11–20... ]

# total pages = ceil(X-Total-Count / _limit)
  • _limit — between 1 and 100 (defaults to 10 when only _page is given)
  • _page — starts at 1; pages past the end return an empty array []
  • Without _page/_limit the full collection is returned

Case 5 — Filter a collection

Each resource supports simple equality filters on selected fields (see the resources table):

Filter examples
# Posts written by user 7
curl "https://mockserver.in/fake-api/v1/posts?userId=7"

# Only unfinished todos of user 3
curl "https://mockserver.in/fake-api/v1/todos?userId=3&completed=false"

# Products in one category
curl "https://mockserver.in/fake-api/v1/products?category=electronics"

Case 6 — Combine filters with pagination

Filters apply first, then pagination
curl -i "https://mockserver.in/fake-api/v1/todos?completed=true&_page=1&_limit=5"

# X-Total-Count reflects the FILTERED total,
# so your pager stays correct.
Boolean filters take the literals true / false; numeric filters take plain integers. Unknown filter parameters are ignored.

Fake API — Simulated Writes

All write methods respond realistically but never persist anything — the datasets are immutable, so everyone always sees the same data. This is exactly how JSONPlaceholder behaves and is perfect for testing form submissions and optimistic UI updates.

Case 7 — Create a record (POST)

POST /fake-api/v1/posts → 201 Created
curl -X POST https://mockserver.in/fake-api/v1/posts \
  -H "Content-Type: application/json" \
  -d '{"title": "My new post", "userId": 1}'

// Response — your body echoed back with the next free id:
{
  "title": "My new post",
  "userId": 1,
  "id": 101
}

Case 8 — Update a record (PUT / PATCH)

PUT or PATCH /fake-api/v1/posts/5 → 200 OK
curl -X PATCH https://mockserver.in/fake-api/v1/posts/5 \
  -H "Content-Type: application/json" \
  -d '{"title": "Updated title"}'

// Response:
{
  "title": "Updated title",
  "id": 5
}

Case 9 — Delete a record (DELETE)

DELETE /fake-api/v1/posts/5 → 200 OK
curl -X DELETE https://mockserver.in/fake-api/v1/posts/5

// Response:
{}
A GET after any write returns the original data — nothing was stored. Every write response carries the header X-MockServer-Note: Fake API writes are simulated — data is not persisted as a reminder. If you need writes that persist, create your own mock instead.

Fake API — Using It From Code

Case 10 — Browser fetch (CORS)

All endpoints send Access-Control-Allow-Origin: * and answer OPTIONS preflights, so this works from any origin — a local file, CodePen, or your dev server:

JavaScript — fetch with pagination
const res   = await fetch('https://mockserver.in/fake-api/v1/products?_page=1&_limit=12');
const total = res.headers.get('X-Total-Count');   // "100"
const items = await res.json();

console.log(`Loaded ${items.length} of ${total} products`);

Case 11 — React data loading

React — useEffect example
useEffect(() => {
  fetch(`https://mockserver.in/fake-api/v1/todos?userId=${userId}`)
    .then(res => res.json())
    .then(setTodos);
}, [userId]);

Case 12 — axios / Node.js

axios — works in Node and the browser
const { data, headers } = await axios.get(
  'https://mockserver.in/fake-api/v1/posts',
  { params: { userId: 7, _page: 1, _limit: 10 } }
);
const total = headers['x-total-count'];

Case 13 — Postman / HTTP clients

Paste any endpoint URL straight into Postman, Insomnia, HTTPie or Thunder Client — no auth tab, no headers required. For POST/PUT/PATCH set the body type to raw → JSON.

Fake API — Errors & Limits

Case 14 — Record not found (404)

GET /fake-api/v1/users/9999
HTTP/1.1 404 Not Found

{
  "error": "Not found",
  "message": "No users record with id 9999."
}

Useful on purpose: point your error-state UI at a non-existent id to test the "not found" path.

Case 15 — Rate limit (429)

Endpoints are limited to 120 requests per minute per IP. Beyond that you receive 429 Too Many Requests with a Retry-After header — which also makes it a handy way to test your client's retry/backoff logic.

Reference — every response includes

Standard Fake API headers
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
Access-Control-Expose-Headers: X-Total-Count
X-Total-Count: <total>          # on collection responses
Cache-Control: public, max-age=300   # on GET responses
Outgrown the fixed datasets? Your own mocks give you custom paths, payloads, status codes, latency and failure simulation — keep reading below.

Creating a Mock

Go to My Mocks → New Mock and fill in:

  • Method — GET, POST, PUT, PATCH, DELETE, or OPTIONS
  • Path — the URL path (e.g., /products or /users/{id})
  • Status Code — any valid HTTP status (200, 201, 404, 500…)
  • Response Body — your JSON payload
  • Delay (min/max ms) — optional fixed or random latency range
  • Fail Rate — percentage of requests that should return an error response
  • Response Headers — optional custom headers

Each combination of method + path must be unique within your account.

Dynamic Path Parameters

Wrap any path segment in curly braces to make it a dynamic parameter:

Path pattern
/users/{id}
/orders/{orderId}/items/{itemId}
/products/{slug}/reviews

MockServer will match any real value in that position. For example, a mock path of /users/{id} will match:

  • /users/1
  • /users/42
  • /users/abc123

Using params in the response body

The captured value is automatically substituted into your JSON payload wherever you use the same placeholder:

Mock path: /users/{id}  |  Request: GET /users/42
{
  "id": "{id}",
  "name": "John Doe",
  "email": "john@example.com"
}

// Response returned:
{
  "id": 42,
  "name": "John Doe",
  "email": "john@example.com"
}
For a string value, wrap the placeholder in quotes: {id}. For a number, use it bare: {id}.

Response Body

MockServer returns the response body exactly as you entered it. The Content-Type is always set to application/json unless you override it with a custom header.

MockServer does not validate your JSON. If your payload is malformed, the client will receive it as-is. Always verify your JSON is valid before saving.

Custom Response Headers

You can add any number of custom headers to a mock. Common use cases:

Example headers
Content-Type: application/json
Access-Control-Allow-Origin: *
X-Rate-Limit-Remaining: 99
X-Request-ID: abc-123

Headers defined on the mock are merged with the default headers (Content-Type, Access-Control-Allow-Origin, X-MockServer-Slug, X-MockServer-Path). If you define a header with the same name, yours takes precedence.

Dynamic Response Variables

Enable the Dynamic Response toggle on any mock to activate variable interpolation. Variables written as {{variable}} are resolved at request time before the response is sent — letting you echo back request data, generate unique IDs, and more.

Dynamic variables work in both regular account mocks and Quick Mocks. Unknown variables (typos, unsupported names) are left as-is in the response.

Request — Query Parameters

VariableReturns
{{request.query}}All query parameters as a JSON object
{{request.query.key}}Single query parameter value
Request: GET /users?page=2&limit=10
{
  "pagination": "{{request.query}}",
  "current_page": "{{request.query.page}}"
}

// Response:
{
  "pagination": {"page": "2", "limit": "10"},
  "current_page": "2"
}

Request — Body Fields

VariableReturns
{{request.body}}Entire request body as a JSON value (object, array, or string)
{{request.body.key}}Single field from JSON body — dot notation supported for nesting
Request body: {"user": {"name": "Alice", "age": 30}}
{
  "received": "{{request.body}}",
  "name": "{{request.body.user.name}}",
  "age": "{{request.body.user.age}}"
}

// Response:
{
  "received": {"user": {"name": "Alice", "age": 30}},
  "name": "Alice",
  "age": 30
}
Use dot notation to reach nested fields: {{request.body.address.city}} reads body.address.city. Missing keys return null. Integer and boolean types are preserved.

Request — Headers

VariableReturns
{{request.headers}}All incoming request headers as a JSON object (infrastructure noise filtered out)
{{request.headers.key}}Single incoming header value (case-insensitive)
Request with Authorization: Bearer abc123
{
  "all_headers": "{{request.headers}}",
  "token": "{{request.headers.authorization}}"
}

// Response:
{
  "all_headers": {"authorization": "Bearer abc123", "content-type": "application/json"},
  "token": "Bearer abc123"
}

The following infrastructure headers are filtered from {{request.headers}} to keep the output clean: host, user-agent, accept, accept-encoding, accept-language, connection, content-length, and others. They are still accessible via {{request.headers.key}}.

Request — Method & Path

VariableReturns
{{request.method}}HTTP method of the incoming request (GET, POST, etc.)
{{request.path}}URL path of the incoming request
Request: POST /api/dark-storm/orders/99
{
  "method": "{{request.method}}",
  "path": "{{request.path}}"
}

// Response:
{
  "method": "POST",
  "path": "api/dark-storm/orders/99"
}

Response — Custom Headers

Reference the custom response headers you've configured on the mock itself.

VariableReturns
{{response.headers}}All custom response headers as a JSON object (keys lowercased)
{{response.headers.key}}Single custom response header value (key is case-insensitive)
Mock has custom headers: X-Api-Version: 3, X-Region: us-east
{
  "meta": "{{response.headers}}",
  "version": "{{response.headers.x-api-version}}",
  "region": "{{response.headers.x-region}}"
}

// Response:
{
  "meta": {"x-api-version": "3", "x-region": "us-east"},
  "version": "3",
  "region": "us-east"
}

Date & Time

VariableReturnsExample output
{{now}}Current datetime as ISO 86012026-05-08T10:30:45+00:00
{{today}}Today's date (YYYY-MM-DD)2026-05-08
{{datetime}}Current datetime (YYYY-MM-DD HH:MM:SS)2026-05-08 10:30:45
{{time}}Current time (HH:MM:SS)10:30:45
{{timestamp}}Unix timestamp in seconds1746700245
{{timestamp_ms}}Unix timestamp in milliseconds1746700245123
{{year}}Current year (YYYY)2026
{{month}}Current month, zero-padded (MM)05
{{day}}Current day, zero-padded (DD)08
Example — date & time fields
{
  "created_at": "{{now}}",
  "date": "{{today}}",
  "time": "{{time}}",
  "ts": {{timestamp}},
  "ts_ms": {{timestamp_ms}},
  "year": "{{year}}",
  "month": "{{month}}",
  "day": "{{day}}"
}

// Response:
{
  "created_at": "2026-05-08T10:30:45+00:00",
  "date": "2026-05-08",
  "time": "10:30:45",
  "ts": 1746700245,
  "ts_ms": 1746700245123,
  "year": "2026",
  "month": "05",
  "day": "08"
}

Generators

VariableReturnsExample output
{{uuid}}Random UUID v4 (new on every request)550e8400-e29b-41d4-a716-446655440000
{{random}}Random integer between 1 and 9999947283
Example — generated fields
{
  "id": "{{uuid}}",
  "nonce": "{{random}}"
}

// Response:
{
  "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "nonce": "83241"
}

JSON Embedding Rules

MockServer uses a two-pass approach to keep the response valid JSON regardless of the variable type.

Quoted variables — "{{var}}"

When a variable is the entire value of a quoted JSON field ("{{var}}"), MockServer inspects what the variable resolves to:

  • If the resolved value is a JSON object, array, number, boolean, or null — the surrounding quotes are stripped automatically, so the value embeds as native JSON.
  • If the resolved value is a plain string — it stays quoted and is properly escaped.
Request body: {"name": "Alice", "age": 30, "active": true, "address": {"city": "NY"}}
// Mock payload (Dynamic Response ON):
{
  "name":    "{{request.body.name}}",
  "age":     "{{request.body.age}}",
  "active":  "{{request.body.active}}",
  "address": "{{request.body.address}}",
  "body":    "{{request.body}}"
}

// Response — types are preserved automatically:
{
  "name":    "Alice",
  "age":     30,
  "active":  true,
  "address": {"city": "NY"},
  "body":    {"name": "Alice", "age": 30, "active": true, "address": {"city": "NY"}}
}

Bare variables — {{var}} without quotes

Variables used outside of quotes (e.g., as a raw JSON value) are replaced as-is. Use this form when you're already in a non-string JSON position and the variable returns a number, boolean, or object.

Bare variable — result inserted verbatim
// Mock payload:
{
  "count": {{request.body.count}},
  "flag":  {{request.body.flag}}
}

// If body has count=5, flag=false:
{
  "count": 5,
  "flag":  false
}
If a bare variable resolves to a string (e.g., "hello"), it will be inserted without surrounding quotes, producing invalid JSON. In most cases it's safer to use the quoted form "{{var}}" and let MockServer handle the quoting automatically.

Latency Simulation

Simulate slow networks or high-latency backends by adding a server-side delay before the response is sent. You can set a fixed delay or a random range.

Fixed delay

Set Delay (ms) to a single value. Every request will wait exactly that long before responding.

Example — 500 ms fixed delay
Delay (min): 500
Delay (max): — (leave blank)

Random delay range

Set both Delay (min) and Delay (max). MockServer picks a random value in that range on each request — great for simulating realistic jitter.

Example — random 100–800 ms
Delay (min): 100
Delay (max): 800

# Each request independently rolls a delay in [100, 800] ms
  • Minimum: 0 ms
  • Maximum: 30,000 ms (30 seconds)
  • Max must be ≥ Min if both are set
The delay is applied server-side, before sending the response. Make sure your client-side timeout is greater than the max delay or you'll see a timeout error before the response arrives.

Intermittent Failure Simulation

Configure a percentage of requests to return a deliberate error response. This lets you test how your application handles flaky dependencies — retries, fallbacks, error UI states — without needing to break anything for real.

How it works

Set a Fail Rate (0–100 %) and a Fail Status Code. On each request MockServer rolls a random number — if it falls within the fail rate, the error response is returned instead of your payload.

Example — 30 % failures as 503
Fail Rate: 30%
Fail Status Code: 503

# ~30 out of every 100 requests return:
{
  "error": "Simulated failure",
  "message": "This request was intentionally failed by MockServer.",
  "fail_rate": "30%"
}

Available fail status codes

Any 4xx or 5xx status code is accepted: 400, 401, 403, 404, 429, 500, 502, 503, 504, and more.

Failure is checked before delay is applied — so even with a 30-second delay configured, failed requests return immediately without waiting.
Failure simulation is statistical, not guaranteed. With a 30 % rate you may occasionally get several successes or failures in a row — that's intentional randomness, matching real-world flaky services.

Response headers on simulated failures

Failed responses include two extra headers you can inspect in your client or traffic logs:

Extra headers on failure
X-MockServer-Simulated-Failure: true
Access-Control-Allow-Origin: *

Traffic Logs

Every request to your mock endpoints is logged. Navigate to Traffic Logs in the sidebar to see:

  • Request method and path matched
  • Timestamp of the request
  • Client IP address
  • Request headers and body

The log feed auto-refreshes based on your configured poll interval (30s / 60s / 3min / 5min), set in Settings.

Log retention

  • Free tier: Logs are kept for 24 hours
  • Paid tier: Logs are kept for 30 days

Sharing Mocks

You can generate a read-only public share link for any mock. Go to My Mocks, click the share icon on a mock, and copy the URL.

The share link shows the mock's method, path, status code, response headers, and payload — without requiring the recipient to sign in. It does not expose your API slug or other mocks.

Share links are permanent. If you delete the mock, the share link will return a 404.

Supported HTTP Methods

GET POST PUT PATCH DELETE OPTIONS

CORS preflight OPTIONS requests are handled automatically for all endpoints — you don't need to create a mock for them. MockServer responds with the appropriate CORS headers.

Status Codes

Any valid HTTP status code between 100 and 599 is accepted. Common examples:

  • 200 OK · 201 Created · 204 No Content
  • 400 Bad Request · 401 Unauthorized · 403 Forbidden · 404 Not Found · 422 Unprocessable Entity
  • 429 Too Many Requests · 500 Internal Server Error · 503 Service Unavailable

Limits

FeatureFreePaid
Mock endpoints20Unlimited
Quick Mocks (no signup)Unlimited · 72h expiry · no account needed
Log retention24 hours30 days
Response delayUp to 30sUp to 30s
Latency simulation (range)Free users: locked
Intermittent failuresFree users: locked
Custom headersUnlimitedUnlimited
Share linksUnlimitedUnlimited
AdsYesNo
Paid plans are coming soon. Stay tuned for announcements.