APISpy is a full‑stack developer tool that captures network traffic in the browser and streams it to a live dashboard. It combines a Chrome MV3 extension, a Node/Express + WebSocket backend, and a React dashboard to help you debug API calls in real time with full request/response context.
- Real‑time interception of
fetch()andXMLHttpRequest - WebSocket live updates to the dashboard
- Multi‑tenant authentication with API keys
- Request replay with latency measurement
- One‑click cURL generation
- Persistent storage in PostgreSQL
- Frontend: React (JS), Vite, react-window (virtualized lists)
- Backend: Node.js, Express, WebSockets
- Database: PostgreSQL, Prisma ORM
- Extension: Chrome Extension API (Manifest v3)
- Deployment: Railway (backend), Vercel (dashboard)
APISpy uses a three‑tier design: extension → backend → dashboard.
flowchart LR
A[Chrome Extension] -->|POST /api/requests| B[Node.js + Express]
B -->|Stores in PostgreSQL| C[(Postgres)]
B -->|WebSocket broadcast| D[React Dashboard]
Flow:
- Extension injects interception logic into the page context.
- Captured requests are relayed to the extension UI and backend.
- Backend stores requests and streams updates over WebSockets.
- Dashboard renders live and historical traffic with filtering and replay.
- Node.js 18+
- PostgreSQL database
- Chrome browser
cd backend
npm install
# Create .env with DATABASE_URL
npx prisma migrate dev
npm startcd dashboard
npm install
npm run dev- Open chrome://extensions
- Enable Developer mode
- Click Load unpacked and select the project root
- Register an API key (see below)
- Add your API key to extension requests (see Usage)
- Register for an API key
curl -X POST http://localhost:3001/api/auth/register \
-H 'Content-Type: application/json' \
-d '{"email":"you@example.com"}'Response:
{ "apiKey": "...", "email": "you@example.com", "message": "User registered successfully" }- Configure the extension to send the API key
The backend requires x-api-key on all /api/requests calls. Update content.js:
await fetch(`${BACKEND_URL}/api/requests`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": "YOUR_API_KEY"
},
body: JSON.stringify(request),
});- Connect the dashboard WebSocket with API key
WebSocket auth is via query param:
wss://YOUR_BACKEND_URL?apiKey=YOUR_API_KEY
- View and replay requests
Open the dashboard, select a request row to see headers/bodies, and use Replay Request to re‑issue the call and compare responses.
- POST /api/auth/register — register user and return API key
- GET /api/auth/validate — validate API key via x-api-key
- GET /api/requests — fetch latest requests (requires auth)
- POST /api/requests — ingest a request (requires auth)
- DELETE /api/requests — clear requests (requires auth)
- User: id, email, apiKey, timestamps
- Session: userId, browserId, timestamps (indexed)
- Request: sessionId, url, method, status, duration, headers/bodies, timestamp Prisma provides type‑safe queries and automatic migrations.
- Backend (Railway): https://apispy-production.up.railway.app
- Dashboard (Vercel): https://api-spy-inky.vercel.app/
- DATABASE_URL (required) Railway uses Nixpacks via railway.json + nixpacks.toml.
- Run backend: cd backend && npm start
- Run dashboard: cd dashboard && npm run dev
- Load extension in Chrome as unpacked
- backend/ — API + WebSocket server
- dashboard/ — React dashboard
- content.js, injected.js — interception + relay logic