mock → observe → enforce

Paste an OpenAPI document.
Get a live URL.

That URL mocks your API before it exists. Point it at the real thing later and it validates every request and response against the contract - and tells you where production has drifted from what you publish.

No account. No card. The URL lives for 24 hours - sign up free to keep it.

We fetch it once, now, and keep the bytes - the mock does not go back to that address, so it works whether or not the URL stays up.

Or start from one of ours

The canonical one. A list, a fetch, a create, and the error shape - enough to see every part working.
Money, enums, nested objects and a bearer token: closer to a real API, and to a real contract.
One operation, in YAML. A good place to start from, and a good thing to break on purpose.
# paste a spec, get a URL - no account, gone in 24 hours
curl -s https://openapi-proxy.com/specs -T openapi.json
https://amber-heron.openapi-proxy.com

# every operation answers from your schema, immediately
curl https://amber-heron.openapi-proxy.com/pets/42
{ "id": 42, "name": "string", "tag": "string" }

Three steps, each one optional

  1. mock

    A live URL for an API that does not exist yet

    Paste the spec and every operation answers immediately, generated from your schemas: examples honoured, required fields present, content types negotiated. Frontend unblocked, SDK tested, partner demo booked - before the backend has a repository.

  2. observe

    Proof the implementation matches the document

    Point the same URL at your real upstream. Conforming traffic passes through untouched; every request and response is checked against the contract, and the drift report shows what your API actually does versus what your docs claim - per operation, per field, with when it started.

  3. enforce

    The contract, enforced at the edge

    When you trust what observe shows you, turn it round: a non-conforming request is rejected with RFC 7807 problem+json naming the exact schema pointer, and never reaches your upstream at all.

The docs say one thing. Production says another.

Every published API drifts: a field goes nullable after a migration, an enum grows a value the spec never heard of, a deploy changes a date format and three partners' SDKs quietly break. You find out when a customer emails.

A proxy that validates responses - sampled, off the hot path, never touching the client's bytes - sees the drift the day it ships, not the week it is reported. Retention turns it into a time series: not just what is wrong, but when it started and what shipped that day.

{
  "type":   "https://openapi-proxy.com/problems/request-validation",
  "title":  "request does not match the published contract",
  "status": 422,
  "violations": [
    { "pointer": "/paths/~1pets/post/requestBody",
      "error":   "required property 'name' is missing" }
  ]
}

Fast enough to sit in the request path

request validated against the contract, in C
~3.2µs
added to a round trip your upstream dominates
≈0
conforming responses forwarded
byte-identical
requests a validator failure may drop
zero

The gateway is C end to end - the event loop, the proxy, the JSON Schema validation - which is why validation costs microseconds where a scripting runtime spends milliseconds. Conforming traffic is forwarded byte-identical, headers included. And an unmatched path is forwarded, not rejected: a spec that does not cover everything is the normal case, and a gateway that 404s your uncovered routes is one you cannot install.

Measured on the published harness: request validation through a mounted OpenAPI operation, schema checks included. The capacity model behind our pricing is the same number - see the docs for how it is produced.

What leaves your network

Violation fingerprints and one redacted example per fingerprint per window. Never a full request or response body. That sentence is in our security page and our DPA, in that order - and if it is still too much, the data plane runs in your network and ships only the fingerprints you have already read about.

The whole gateway is a file

Hosted, nothing to run: paste the spec, set the upstream, done. Or self-hosted as a container with one YAML file - the same gateway, apip check as your pre-deploy CI gate, secrets referenced from the environment and never written down.

Fail-open is the design, not a hope: if the validator dies, the spec is broken, or our reporting pipeline stalls, your traffic still flows. We test it by injecting exactly those failures under load - the chaos harness is a supported switch, not a private test.

# maat.yml - the whole gatewayspec:     openapi.jsonupstream: https://api.internal:8443mode:     observe            # record drift; enforce rejects itlisten  - port: 443    tls_cert: /etc/maat/tls.crt    tls_key:  /etc/maat/tls.key  - port: 80    redirect_https: 443

Priced on traffic, not seats

Metered on requests proxied, because that is what costs us. Seat pricing punishes exactly the team-wide adoption we want.

FreeStarter £29Team £99Business £399
1 proxy
10k req/mo
3 proxies
1M req/mo
10 proxies
10M req/mo
enforce mode
unlimited proxies
100M req/mo
SLA, SSO, self-hosted

On paid plans, going over your ceiling never fails a request - it raises an alert and bills the overage. A gateway that stops passing traffic because of an invoice is a gateway nobody puts in production.