A mock endpoint returns a response you defined, at a URL you chose, with the status code and headers you set. It exists so a front end can be built against an API that does not exist yet, and so a failure path can be tested without arranging a real failure.
https://api.apiverve.com/v1/mockserver/<server-id>/<your-path>
Every account gets one mock server, derived from your account rather than created — there is nothing to provision. Endpoints are paths on it, and how many you can have is a plan limit:
| Plan | Mock endpoints | Max response |
|---|---|---|
| Free | 1 | 100 KB |
| Starter | 10 | 5,000 KB |
| Pro | 50 | 5,000 KB |
| Mega | 100 | 5,000 KB |
The second column matters more than it looks: the response body is stored as a file, and a body
over your plan's ceiling is rejected at save time with a 413 naming both sizes.
Creating one
VerveKit → Mock endpoints in the dashboard. Four things define an endpoint:
| Path | What you call — /api/users. Must start with / |
| Method | GET, POST, PUT, PATCH or DELETE. One method per endpoint |
| Status | What it returns — 200, or a 500 if that is the point |
| Response body | The JSON (or text) it answers with |
A name is required too, purely for your own list.
JSON is validated before it saves. A malformed body is rejected with Invalid JSON in response
body rather than stored and discovered later. If what you store is not JSON at all it is kept and
served as text/plain, which is the right behaviour for mocking something that returns CSV, XML
or a plain string.
Response headers are optional, as JSON key/value pairs, for when the thing you are building reads
one — an x-total-count for pagination, a retry-after on a 429. They are merged into the
response before the CORS and cache headers are applied.
You can also start from a real endpoint: the API browser can pre-fill a mock from a catalog endpoint, which gives you a realistic shape to build against and to diverge from deliberately rather than by accident.
Calling one
curl 'https://api.apiverve.com/v1/mockserver/YOUR_SERVER_ID/api/users' \
-H 'x-api-key: YOUR_API_KEY'The response is exactly what you configured — your status code, your headers, your body. It is
not wrapped in the API's status/error/data envelope, because the point is to look like
the service you are pretending to be, not like this one. That also means your normal response
handling does not apply to a mock; treat it as a foreign API, which is what it is imitating.
Three headers are always set on the way out, whatever you configured:
| Header | |
|---|---|
Access-Control-Allow-Origin: * | Any origin. A browser front end can call a mock directly |
Access-Control-Allow-Methods | The one method this endpoint accepts |
Cache-Control: no-store, no-cache, must-revalidate, private | Nothing between you and the mock keeps a stale body |
The open CORS is the one place in the platform where a browser may call api.apiverve.com
directly, and it exists because mocks are a development tool. The real API stays closed — see
CORS — so a front end built against a mock still needs a backend before it can call the
live endpoint.
A request costs one credit. A test suite that hammers a mock endpoint spends credits at the same rate as real calls, which is worth knowing before you point a load test at one.
Method matters
An endpoint answers one method. Calling /api/users with POST when it is defined as GET gets
a 405 naming both:
Method not allowed. Expected GET, got POST
That is usually a feature — it catches a client using the wrong verb — but note the constraint it
implies. Paths are unique regardless of method, so you cannot define GET /api/users and
POST /api/users as two endpoints; the second is refused with An endpoint with this path already
exists. Where a real API would use one path with two verbs, a mock needs two paths —
/api/users and /api/users-create is the usual workaround, with the client's base path swapped
back when the real service lands.
An undefined path is a plain 404.
Request rules
On Pro and above, an endpoint can declare what a valid request looks like and reject one that does not match. Under Request rules:
- Expected query parameters for a
GETorDELETE - Expected body payload for a
POST,PUTorPATCH
Both are written as a JSON object; only the keys are read.
This is what turns a mock from a stub into something you can test against. Your error handling only gets exercised if something produces errors, and arranging that against a real API means sending deliberately bad data and hoping it fails the way you expect. Here you decide.
The check is presence, not shape: a declared key that is absent fails, a declared key that is present passes whatever its value. That is enough for "did the client send what it promised", which is the question a mock is well placed to answer. The rejection names the offending key — Missing required query parameter: userId — so a failing test says which field the client forgot.
The dropdown offers 400, 404 and 422 as the response to a mismatch. In the current server,
only 400 is acted on — an endpoint set to 404 or 422 serves its normal response and never
checks the rules. If you are relying on rules to fail a test, set the action to 400.
Rules are a paid feature at both ends: saving them on a free plan is refused with Request configuration requires Pro or Mega plan, and at serve time the check is skipped entirely for an account that is not Pro or above. So rules saved while on Pro stop being applied if the account later drops to free — silently, with the endpoint still serving its normal response. Worth knowing before you conclude a test broke for some subtler reason.
What to use it for
Building ahead of the backend. The classic case. Agree the contract, mock it, build both sides in parallel, swap the base URL when the real service lands.
Testing failure paths. A mock that returns 500, or 429 with a retry-after header, is the
cheapest way to find out whether your retry logic works. See error handling.
Reproducing a bug. Pin the exact payload that broke your parser to a mock endpoint and it stops being a story about what the upstream did last Tuesday. This is the use worth reaching for first — a bug with a URL attached is a bug someone else can look at.
Demos and documentation. A prototype that calls something real, on a plane, without a backend — and live examples in your own docs that keep working whether or not your service is up.
Third-party stand-ins. Mocking the payment provider or the CRM you integrate with, so your CI does not depend on their sandbox being available. It also lets you rehearse their outage, which their sandbox will never do on request.
Managing them over the API
Mock endpoints can be listed, read and updated through the API, but not created or deleted —
those return a 403 pointing you at the dashboard:
Create endpoints via the APIVerve Dashboard
The same protection JSON bins have, and for the same reason: a leaked key should not be able to reshape or wipe your development tooling. Update is allowed because it is the operation worth scripting — keeping a mock in step with a schema in CI, for instance — and it cannot create anything that was not already there.
Limits worth knowing
One endpoint per path. As above; two verbs on the same resource need two paths.
Fixed responses. A mock returns what you stored. There are no templates, no request echoing, no generated data and no sequencing; if you need the response to vary, define several paths and have the client choose.
No request inspection. Requests are served, not recorded — there is no log of what a client sent. A mock tells you what your code received, not what it sent, so pair it with your own client-side logging when you are debugging a payload.
Endpoint count and body size are plan limits. Both are in the table at the top, and both are enforced at save time rather than at call time.
Not a staging environment. Mocks are for shaping and testing a client. Once the real service exists, point at the real service — a mock that has quietly drifted from the thing it imitates is worse than no mock at all. The failure mode is a green test suite over an interface that no longer exists.
Next
JSON bins serve a single document rather than a set of endpoints, and are the better fit for configuration. Error handling covers the failure shapes worth mocking, and VerveKit covers the rest of the toolkit.