A local proxy that catches API contract drift while you develop — not in code review, not in production.
api-watch sits between your HTTP client and your local dev server, transparently proxies every request, and validates each request/response pair against your OpenAPI spec. When you stop it, it hands you a self-contained HTML report of every contract violation it saw — plus ready-to-paste spec stubs for every endpoint you forgot to document.
During local development, your API and your contract drift apart silently.
You add an endpoint and forget to document it. A response gains a field that was never in the spec. A price that was a number quietly becomes a string. A required field stops being returned. None of this errors. None of it warns you. Your tests pass, the feature works, and the spec — the thing other teams, client generators, and your gateway all trust — is now a lie.
You find out later. In code review, if you're lucky. In production, if you're not.
The spec and the server look fine in isolation. The drift only shows up when you compare them on live traffic — which nobody does locally.
api-watch compares them on live traffic, locally, with zero config.
Point it at your spec and your dev server, then use the proxy port instead of your server's port. It validates everything that flows through and says nothing unless something is wrong:
api-watch start --spec openapi.yaml --target http://localhost:3000 --port 8080
api-watch: proxying localhost:8080 → http://localhost:3000
api-watch: validating against openapi.yaml
api-watch: use Ctrl+C to stop and generate report
✓ GET /api/products 200
✓ GET /api/products/123 200
✗ POST /api/orders undocumented endpoint
✗ GET /api/products/123 2 violations
^C
api-watch: session ended. 47 requests captured.
api-watch: 47 requests · 3 undocumented · 8 violations → api-watch-report.htmlOpen the report and you get every violation, grouped by endpoint, with the exact field that broke — and a generated OpenAPI stub for each endpoint you never documented, ready to paste into your spec.
npm install -g api-watchRequirements: Node.js 18+.
That's it. No agent, no CI setup, no config file. api-watch is a proxy you run on demand.
api-watch start \
--spec openapi.yaml \
--target http://localhost:3000 \
--port 8080| Option | Required | Default | Description |
|---|---|---|---|
--spec |
✅ | — | Path to your OpenAPI spec (YAML or JSON). |
--target |
✅ | — | URL of the local dev server to proxy to. |
--port |
8080 |
Port for the proxy to listen on. | |
--output |
api-watch-report.html |
Path to write the HTML report. |
Point your frontend, your curl, your Postman, your integration tests — whatever drives your API — at http://localhost:8080 instead of http://localhost:3000. api-watch forwards everything to your real server and captures both sides in memory.
You'll see one line per request as it happens:
✓ GET /api/products 200 # documented, valid
✗ GET /api/orders 3 violations # documented, but drifted
✗ POST /api/refunds undocumented # not in your spec at all
Hit Ctrl+C. api-watch validates everything it saw, generates stubs for undocumented endpoints, writes the HTML report, and prints a one-line summary:
47 requests · 3 undocumented · 8 violations → api-watch-report.html
For every request/response pair that flows through the proxy:
Is the endpoint documented?
The request's method + path are matched against your spec's paths, with full path-parameter support — /api/products/123 matches the documented /api/products/{id}. No match means the endpoint is undocumented, and a stub is generated for it.
Request validation (for documented endpoints):
- Are required query parameters present?
- Are required body fields present?
- Do body field types match the spec?
Response validation (for documented endpoints):
- Is the returned status code one the spec actually defines?
- Are all required response fields present?
- Do response field types match the spec?
- Are there extra fields the spec doesn't mention? (flagged as a warning, not an error)
Violations are typed and severity-tagged so the report can separate "this will break clients" (error) from "you might want to look at this" (warning):
| Type | Severity | Meaning |
|---|---|---|
missing_required_field |
error | A required field was absent. |
wrong_type |
error | A field's type didn't match the spec. |
wrong_status_code |
error | The response returned an undocumented status code. |
missing_request_param |
error | A required request parameter was missing. |
undocumented_endpoint |
error | The endpoint isn't in the spec at all. |
extra_field |
warning | A response field that isn't documented. |
A single self-contained HTML file — no external CSS, no JS, nothing to host. Dark theme, terminal aesthetic, safe to open straight from disk or attach to a PR.
It has four parts:
- Header — session duration, the target and spec used, and four stat cards: Total Requests · Documented · Undocumented · Violations.
- Summary table — one row per unique endpoint, with call count, documented/undocumented status, and violation count.
- Violations detail — an expandable section per endpoint, each violation showing its severity badge, type, message, and exact location (e.g.
response.body.price). - Generated stubs — for every undocumented endpoint, a copy-pasteable OpenAPI path stub with a one-click copy button.
api-watch doesn't just tell you an endpoint is undocumented — it writes the first draft for you. From the actual traffic it saw, it infers path parameters, a best-effort request body schema, and a best-effort response schema:
# Auto-generated by api-watch — review before committing
/api/orders/{id}/cancel:
post:
summary: Auto-generated stub — update before committing
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: SuccessPaste it into your spec, tighten the types, and the drift is closed.
api-watch is deliberately small — a local dev tool, not a platform.
- No persistent storage — session data lives in memory and is gone when you stop.
- No CI/CD mode — this is for local development.
- No dashboard or web UI — the HTML report is the whole interface.
- No HTTPS proxying.
- No WebSocket support.
- No request replay or spec-vs-spec diffing.
If you need contract enforcement in CI, that's a different (heavier) class of tool. api-watch is the one you run while you're actually writing the code.
api-watch shares a thesis with its sibling tool proto-lock:
API contracts should be enforced automatically, not by hand.
- proto-lock enforces contract stability — it pins protobuf field numbers so OpenAPI → gRPC generation never silently breaks the wire format.
- api-watch enforces contract compliance — it catches your HTTP implementation drifting from its OpenAPI spec during local development.
Same problem domain, opposite ends of the contract lifecycle.
MIT