Visual API scenario runner with a chaos fuzzer, auth lifecycle simulator, and contract drift detector
Features · Getting started · How it works · Deploy · Roadmap
Dispatch is a browser-based API testing tool built with Next.js. Instead of a flat list of requests, you build visual scenario graphs — nodes wired together with edges, where each node is an HTTP request. Data flows between nodes automatically: a token captured from login feeds into the Authorization header of the next request without any manual scripting.
On top of that, Dispatch ships three primitives that Postman doesn't have:
- Chaos fuzzer — auto-generates malformed payloads and classifies anomalies
- Auth lifecycle simulator — tests the full token lifecycle including concurrent refresh races and post-logout token reuse
- Contract drift detector — snapshots your API's response schema and alerts when it silently changes
- Drag-and-drop canvas — add Request nodes, wire them together
- Branching execution — if a node fails, its entire downstream branch halts. Sibling branches continue independently
- Variable extraction — pull values from any response using JSONPath (
$.token,$.data[0].id,$..email) and inject them into subsequent requests as{{varName}} - 6 assertion operators —
eq,neq,contains,exists,gt,lt - Abort mid-run — stop any in-flight scenario instantly
- Single-node fire — run just the selected node against current environment variables
- Scenarios persist to
localStorage— no account required
8 mutation strategies fired against your endpoint:
| Strategy | What it probes |
|---|---|
| Null fields | Crashes from unguarded null access |
| Empty strings | Missing server-side validation |
| Boundary numbers | Integer overflow, off-by-one bugs |
| XSS strings | Reflected XSS, unsanitized echo |
| SQL injection | ' OR 1=1--, UNION SELECT, DROP TABLE |
| Type confusion | String where number expected, vice versa |
| Extra fields | Mass assignment — admin: true, role: "superuser" |
| Missing fields | Unhandled missing required fields |
Anomalies classified: unexpected 2xx on malformed input, stack trace leaks in 500 bodies, server errors, slow responses (>5s).
Runs 7 phases against your auth endpoints:
- Login — captures access + refresh tokens
- Use valid token — hits a protected resource
- Invalid token — expects 401/403; flags if server returns 200
- Refresh token — exchanges refresh token for new access token
- Concurrent refresh race — fires two refresh requests simultaneously via
Promise.all; classifies whether the API enforces single-use - Logout — invalidates the session
- Post-logout reuse — tries the old token after logout; flags as SECURITY RISK if it still works
- Captures a full field-level schema snapshot of any response (paths, types, nullable flags, nested objects, arrays)
- Snapshots persist to
localStorageacross sessions - Drift report classifies every change: field added, field removed, type changed, nullable changed
- Run after every deploy to catch silent breaking changes
- Node.js 18+
- npm
# 1. Clone the repo
git clone https://github.com/YOUR_USERNAME/dispatch.git
cd dispatch
# 2. Install dependencies
npm install
# 3. Start the dev server
npm run devOpen http://localhost:3000.
- Click Load example in the topbar — this loads a 3-node JSONPlaceholder scenario
- Hit Run scenario — watch nodes turn green as they execute
- Click any node → inspect the Response tab to see the live response
- Select a POST node → open the Fuzzer tab → pick strategies → Run fuzzer
src/
├── app/
│ ├── page.tsx # Root — composes Topbar + Sidebar + Canvas + Inspector
│ ├── globals.css # Dark theme, IBM Plex Sans / JetBrains Mono
│ └── api/
│ ├── proxy/route.ts # Server-side proxy — all requests route through here (no CORS)
│ └── scenarios/route.ts # Stub route (persistence is localStorage-based)
├── components/
│ ├── Topbar.tsx # Run, Stop, Save, Load example, Clear
│ ├── sidebar/Sidebar.tsx # Node palette, environment display, tips
│ ├── canvas/
│ │ ├── Canvas.tsx # Drop zone, drag, port wiring, mouse events
│ │ ├── FlowNodeCard.tsx # Individual node — method badge, ports, status dot
│ │ └── EdgeLayer.tsx # SVG bezier edges with status colours + arrow markers
│ └── inspector/
│ ├── Inspector.tsx # 6-tab shell: Config · Response · Fuzzer · Contract · Auth · Log
│ ├── ConfigTab.tsx # Method, URL, headers, body, extracts, assertions
│ ├── ResponseTab.tsx # Status pill, assertion results, response body
│ ├── FuzzerTab.tsx # Strategy picker, progress, anomaly results
│ ├── ContractTab.tsx # Capture baseline, schema viewer, drift report
│ ├── AuthTab.tsx # Auth config form, 7-phase lifecycle runner
│ └── LogTab.tsx # Timestamped run log
├── lib/
│ ├── executor.ts # Shared executeNode() — single source of truth for run logic
│ ├── fuzzer.ts # Mutation generators + anomaly classifier
│ ├── auth.ts # 7-phase auth lifecycle runner
│ ├── contract.ts # Schema inference, snapshot persistence, drift diff
│ └── jsonpath.ts # jsonpath-plus wrapper with bare-path normalisation
├── store/
│ └── flow.ts # Zustand + Immer + persist — all state + BFS runner
└── types/
└── index.ts # Shared TypeScript interfaces
The scenario runner uses BFS (breadth-first search) with a topological node ordering:
- Root nodes (no incoming edges) are queued first
- Each node is executed in order; extracted variables are merged into shared environment immediately
- If a node fails its assertions, its downstream branch is halted — but sibling branches continue
- A
currentRunIdguard prevents overlapping runs if the user hits Run twice
All HTTP requests are routed through /api/proxy (a Next.js Route Handler). This runs server-side, so there are no CORS restrictions — you can test any API regardless of its CORS policy.
Use {{varName}} in any URL, header value, or body. Variables are resolved at execution time from the shared environment. Extraction uses jsonpath-plus — full JSONPath including bracket notation, wildcards, and recursive descent:
$.token → top-level field
$.data[0].id → first element of array
$.items[*].email → all emails in array (returns array)
$..name → recursive descent
- Add nodes — drag from the left sidebar onto the canvas, or double-click a node type
- Wire nodes — hover a node's right port (○), click and drag to another node
- Configure — click any node, edit in the Config tab: method, URL, headers, body
- Extract variables — in Config tab, add an extract: name the variable, write the JSONPath. E.g. key
token, path$.token - Use variables — in downstream nodes, write
{{token}}anywhere in the URL, headers, or body - Add assertions — click "add assertion" in Config: choose a path, operator, and expected value
- Run — hit Run scenario in the topbar
- Select a POST/PUT/PATCH node that has a JSON body configured
- Open the Fuzzer tab
- Select strategies (start with Null fields + Missing fields + Type confusion)
- Click Run fuzzer
- Switch filter to Anomalies only — investigate any flagged results
- Open the Auth tab (no node needs to be selected)
- Fill in your Login URL and login body JSON
- Set the Token JSONPath to wherever the token lives in your login response
- Fill in a Protected URL that requires auth
- Optionally fill Refresh URL and Logout URL
- Click Run auth lifecycle
- Watch each phase — red phases indicate failures worth investigating
- Select a node and run it so it has a live response
- Open the Contract tab
- Click Capture baseline — the full response schema is saved
- Later (after a deploy, after a PR merges) — run the node again, then click Check drift
- Any field-level changes surface in the drift report
| Dispatch | Postman | |
|---|---|---|
| Visual flow canvas | ✅ | ❌ Flat list |
| Branching halt on failure | ✅ | ❌ |
| Chaos fuzzer | ✅ 8 strategies | ❌ |
| Auth lifecycle simulator | ✅ 7 phases + race test | ❌ |
| Contract drift detection | ✅ Field-level | ❌ |
| Full JSONPath support | ✅ jsonpath-plus | ✅ |
| No install / no account | ✅ | ❌ Requires account |
| Team collaboration | ❌ | ✅ |
| Pre/post scripts | ❌ | ✅ JS sandbox |
| CI/CD CLI | ❌ planned | ✅ Newman |
| Mock servers | ❌ | ✅ |
- CLI runner (
dispatch run scenario.json) for CI/CD pipelines - Export scenarios as JSON / import from Postman collections
- Vercel KV integration for cloud persistence and sharing
- Time-travel debugger — replay any past run against the current API
- Collaborative live canvas (Figma-style cursor presence)
- OpenAPI spec import → auto-generate scenario from spec
- Next.js 15 — App Router, Route Handlers
- TypeScript 5 — strict mode throughout
- Zustand + Immer — state management with structural sharing
- jsonpath-plus — full JSONPath evaluation
- Lucide React — icons
- Tailwind CSS — utility classes
MIT — see LICENSE for details.