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.