Pricing

Start free with no account and no card. Upgrade when you need to rehearse failures, generate realistic data, or mirror an API too big for the free limits.

Free

No account needed

$0

Create a project
  • One endpoint per project
  • Any status code, headers and body
  • Response delay up to 5s
  • Instant public URL
  • Built-in test client — send a request, set headers, copy it as curl
  • 10,000 requests a month
  • Projects expire after 7 days

Account

Free, forever

$0

Create free account
  • Everything in Free
  • Projects saved permanently
  • Up to 3 projects, 10 endpoints each
  • Endpoints grouped by resource
  • Response delay up to 10s
  • Basic conditional responses
  • Saved test variables and default headers — capture a token once, send it with every request (kept in your browser)
  • Request log: 25 recent calls
  • 50,000 requests a month

Teams

Share with your team

US$25/month

Flat — not per seat. Or US$250/year — 2 months free. Prices in US dollars.

One price however many people you add.

  • Everything in Pro
  • An unlimited crew — add anyone, no extra charge
  • Shared projects: endpoints, scenarios and logs
  • Read-only crew — an Observer can look and flip a scenario, but not edit
  • 1 million requests a month, per project

What Pro actually gives you

The free tiers are a real product — projects, endpoints, saved responses. Pro is for rehearsing the things that go wrong, and for mirroring an API large enough to matter.

Make an API fail, on purpose

Name a set of responses — "outage", "rate limited", "expired token" — and flip your whole project into it. Your error handling finally gets exercised, without editing a single endpoint or waiting for the real API to have a bad day.

curl https://apipreflight.io/m/abc123/orders \
  -H "X-Mock-Scenario: outage"

Switch from the dashboard, or per request from a test — so two people can drive different scenarios against the same project at once.

A different answer on each call

A scenario can be an ordered sequence: the first call times out, the second returns 500, the third succeeds. That is the retry-and-backoff path you cannot test against a real API, and the reason this product exists.

call 1 → 408 Request Timeout
call 2 → 500 Server Error
call 3 → 200 OK   ← holds here

Holds on the last step so a failure stays reproducible. ?_reset=1 starts over.

Save the arrangement, not just the scenario

A real rehearsal is rarely one endpoint failing. Pin several to different scenarios — payments timing out while search is fine — then save that whole arrangement under a name and put the project back into it whenever you want. A batch is the set of pins, not a copy of the responses, so editing a response afterwards changes what the arrangement plays.

payments → "timeout"
search   → base
auth     → "expired token"
        save as "checkout down"

Apply it from the dashboard or from a test, and everything moves together.

Write a response once, use it everywhere

The same 429, the same expired-token body, the same empty-list shape — every project grows a handful of responses it uses again and again. Save them to a reusable library and drop one into any endpoint instead of retyping it, or worse, retyping it slightly differently. A free account gets a few; Pro is unlimited.

rate limited   → 429 {"retryAfter":30}
expired token  → 401 {"error":"expired"}
empty list     → 200 []

Applying one fills the form, so you can still change it for this endpoint.

The agent writing your code can drive the mock

Connect Claude, Cursor or VS Code to a project and it can read what the endpoints return, create new ones, flip a scenario mid-test and read the request log — while it writes the code that calls them. It is the difference between describing your mock to an assistant and handing it the controls.

you   → "make /orders fail, then test"
agent → set_mock_scenario("outage")
agent → runs your suite, sees it fail
agent → read_request_log()
        ← what your code really sent

Over MCP, the protocol these tools already speak. Each project has its own URL and a connection reaches that project only: add the URL in claude.ai and approve a sign-in screen — no token to paste — or paste a token into Claude Code, Cursor, VS Code or a CI job. Connections are listed on the project page and can be cut off there at any time.

Your build can make its own mock

Create a mock at the start of a CI run, define exactly the endpoints your suite needs, flip a scenario to exercise the retry path, assert what your code actually sent, then throw it away. No shared fixture drifting between branches, and no two builds fighting over one mock.

POST   /api/mocks          → a mock
POST   …/endpoints         → your API
npm test                   → against it
PATCH  … activeScenario     → outage
DELETE /api/mocks/<id>     → gone

A token reaches the project it was minted in and throwaway mocks it creates itself — it cannot touch your other projects or delete the one it belongs to, which is what makes it safe in a CI secret. Throwaways expire on their own, so a failed run leaves nothing behind. The full OpenAPI spec is published at /api/openapi/management.

Bodies that look like real data

Generate a list instead of copying one row ten times — with names, emails, prices, UUIDs and timestamps that differ every call. Each row is internally consistent, so a person’s email matches their name.

{{#repeat 10}}
{
  "id": "{{uuid}}",
  "name": "{{faker.name.fullName}}",
  "email": "{{faker.internet.email}}",
  "price": {{faker.commerce.price(5,80)}}
}
{{/repeat}}

Click tokens in from a palette rather than memorising them.

A login that really asks for the six digits

Two endpoints: the first hands back a QR code your authenticator app scans, the second checks the digits it shows. It is checked per email — the address someone signs in with is the one the code is verified against — so the enrolment screen, the code screen and the wrong-code path can all be built and exercised before any of it exists for real.

POST /login
  → { "qr": "data:image/png;base64,…",
      "secret": "JBSWY3DP…" }

POST /verify  { "email": "…", "code": "314159" }
  → 200  if that is what the app is showing now
  → 401  { "reason": "wrong" } if it is not

Standard TOTP — 6 digits, 30 seconds, one step of drift allowed either way — so a real authenticator app works. A refusal says which check failed and where it looked, and never echoes the secret or the correct code. For an automated test, {{totp.code}} renders the digits that are valid right now, so there is no phone in the loop.

POST a record, then find it in the next GET

Stateful endpoints. Switch it on for an endpoint and writes stick: a POST is stored, a GET lists it, PUT and PATCH change it, DELETE removes it. A screen that creates something and navigates back to the list finds it there — which is the first thing anyone building against a backend that does not exist yet tries, and the moment a stateless mock stops being able to play along.

POST /products  {"name":"Chair"}
  → 201 {"id":"a1f…","name":"Chair"}
GET  /products
  → [ …, {"id":"a1f…","name":"Chair"} ]
GET  /products/a1f…   → the one you just created
DELETE /products/a1f… → and now it is gone

Pair /products with /products/{id} and they share a collection automatically — there is no field to wire up. The response body you designed seeds it, so a list of five starts as five rather than empty. Each caller gets their own copy, so two people testing against the same project never see each other’s writes.

An AI reply that breaks halfway through, whenever you ask

Streamed responses. Any signed-in plan can stream a reply word by word, then send the product cards and buttons your chat screen renders. Pro adds the failures real AI backends produce at the worst moment — the reply cut off mid-sentence, an error after the third word, a stream that stalls — and can stream in OpenAI or Anthropic format, so the official SDKs read it unchanged.

POST /chat  {"message":"dinner ideas?"}
  → data: {"type":"text","delta":"Here "}
  → data: {"type":"text","delta":"are "}
      … a word every 40ms
  → event: card  {"title":"Lemon chicken"}
  → data: [DONE]
scenario "dies-halfway":
  → the same reply stops after six words

Your app’s Stop button shows up in the request log too: "client stopped after 7 of 12".

Mock only what does not exist yet

Proxy passthrough. Point an endpoint at your real API and it forwards the request — path, query, headers and all — and returns what actually comes back. Mock the two endpoints that are not built; let everything else hit the real thing.

GET /orders/{orderId}
  → mocked, returns your fixture
GET /customers/{id}
  → forwarded to https://api.yourco.com

https only, and private or internal addresses are refused.

Start from your OpenAPI spec, and hand it back

Paste a spec — JSON or YAML — and get a working project, with example bodies built from its schemas when it has no examples of its own. Export any project, or your whole account as one document, to share with the people writing the real API.

Exports are valid OpenAPI 3.1 and carry your scenarios and sequences, so a colleague importing the file rebuilds the whole project — not a hollow copy of its paths.

Your own address, not ours

Serve a project from a subdomain of your own — yourteam.apipreflight.io — or from a domain you own, mock.yourcompany.com. The hostname identifies the project, so the URLs your app calls carry no /m/{id} prefix, and the HTTPS certificate is issued and renewed for you.

every project, free
  https://apipreflight.io/m/abc123/users/1
your subdomain
  https://yourteam.apipreflight.io/users/1
your own domain
  https://mock.yourcompany.com/users/1

Your own domain takes one TXT record to prove it is yours and one CNAME to point it here — both shown in the dashboard with copy buttons, and the status updates itself while you wait.

A request log you can actually review

Every call to your project is recorded: method, path, query, headers (credentials redacted), body, the status returned and how long it took — plus which scenario and which sequence step served it, so a failing test on call 3 is explainable. Pro keeps 500 recent calls instead of 25, and exports them as CSV or JSON.

Kept for 30 days. Response bodies are not stored — see the privacy policy.

Room to work

200 endpoints per project instead of 10, and unlimited projects instead of three — enough to mirror a real API surface rather than a corner of one.

And what Teams adds

Everything above, plus the parts that only matter once more than one person is calling the same mock.

The same project, in more than one pair of hands

Shared projects. Add colleagues to a project by email and they get the whole thing — endpoints, saved responses, scenarios, sequences and the request log. Someone debugging a failing test can read the calls that failed, not a description of them.

Two roles: the owner, and editors who can change anything in the project. There is no read-only role, and no audit trail of who changed what — both are honestly absent rather than quietly implied.

Somebody who can look without being able to break it

Three roles, and the third is the one people ask for: an Observer can open the project, read every endpoint and response, watch the request log, and flip the project into a scenario — and cannot edit anything. That is the shape a QA engineer, a support lead or a contractor usually wants, and giving them an editor seat instead is how a fixture quietly changes under somebody else’s test.

Captain   owns it — billing, crew, domains
Mechanic  edits endpoints and responses
Observer  reads, and flips a scenario

The roles are enforced in the database, not in the screen: an Observer has no write permission on any table, so a request that skips the UI is refused too.

Adding someone is never a billing decision

Teams is US$25 a month flat, for an unlimited crew — not a charge per person. A mock is consumed by machines rather than people, so the cost of running it is requests; charging for colleagues would bill the one axis that is free to serve, and put a decision in front of you every time you wanted to include someone.

A seat is a person, not a membership row: the same colleague on ten of your projects is one person, counted once. Pro already includes a crew of 3, so a pair working together never has to think about this either.

Room for a whole team pointing at it

1 million requests a month per project instead of Pro's 250,000 — enough for everyone's local runs, a CI pipeline and a shared staging build calling the same mock all day.

Counted per project, so one noisy test suite does not spend another project’s allowance.

Questions

Do I need an account to try it? No. You can create a project and call it right now — try it. Projects made without an account expire after 7 days.

What happens if I cancel? Nothing is deleted — your projects, endpoints, scenarios and sequences are all kept, and start working again the moment you resubscribe. Until then your endpoints answer with their default response, scenarios and sequences pause, and your project URLs go back to the apipreflight.io/m/{id}/… form. Your guards keep working — bearer tokens and one-time codes are still checked — but you cannot enrol a new authenticator until you resubscribe, because the tokens that hand out a QR are generated ones. See the Refund & Cancellation Policy.

Is this suitable for production traffic? No — it is a development and testing tool, with no service-level agreement. See the Terms.

Can I put real data in a mock response? Please don't. Mock URLs are public to anyone who has the link. Use test data only — see the Privacy Policy.