npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

apitrap

v1.1.4

Published

Express middleware that captures API traffic and sends it to your monitor dashboard — turn real requests into living API documentation.

Downloads

77

Readme

apitrap

Turn your Express routes into living API documentation — automatically.

Most teams write their API docs manually, or forget to update them after changes.
apitrap captures real API traffic as it happens and sends it to your monitor dashboard, so your collection always reflects what your API actually does.

npm install apitrap

How it works

Add one middleware per route group. Every time a request hits that route, the library captures the method, path, body, query, response, status code, and duration — then sends it to your monitor server in the background.

No manual effort. No extra tools. Just traffic → collection.


Quick start

1. Initialize (once, in your entry file)

const { initApiCapture } = require("apitrap");

initApiCapture({
  appName: "my-app",
  monitorUrl: "https://your-monitor-server.com/api/capture",
  monitorApiKey: process.env.MONITOR_API_KEY,
});

2. Add to your routes

const { getClient } = require("apitrap");

const router = express.Router();
const auth = getClient().createMiddlewareFactory("Authentication");

router.post(
  "/login",
  auth.capture("User login", "Login page"),
  async (req, res) => {
    // your logic here
    res.json({ success: true });
  },
);

router.post(
  "/register",
  auth.capture("New user registration", ["Login page", "Onboarding"]),
  async (req, res) => {
    res.json({ userId: "..." });
  },
);

That's it. Both routes are now tracked in your dashboard under the Authentication group.


TypeScript

import { initApiCapture, getClient } from "apitrap";

initApiCapture({
  appName: "my-ts-app",
  monitorUrl: process.env.MONITOR_URL,
  monitorApiKey: process.env.MONITOR_API_KEY,
});

const api = getClient().createMiddlewareFactory("Products");

router.get("/products", api.capture("List all products"), handler);

Try it without a monitor server

Skip monitorUrl entirely. The library switches to debug mode and prints captured data to your console — perfect for development.

initApiCapture({
  appName: "local-test",
  // no monitorUrl needed
});

Output:

--- [ApiCapture] [200] 12ms ---
[POST] /api/login
Desc: User login
Body: { "email": "[email protected]", "password": "[REDACTED]" }
Response: { "success": true }
---------------------------

Save to a local file

Useful for offline inspection or building your initial API collection before setting up a monitor server:

initApiCapture({
  appName: "my-app",
  saveLocal: true,
  localPath: "./data/api-capture.json",
});

Sensitive data is always masked

Passwords, tokens, and secrets are automatically redacted before leaving your server. You can add custom keys too:

initApiCapture({
  sensitiveKeys: ["ssn", "tax-id", "card-number"],
});

The following keys are masked by default (case-insensitive): password, token, secret, creditcard, pin, auth, authorization, cookie.


Graceful shutdown

If you need to make sure all captured events are flushed before your server stops:

process.on("SIGTERM", async () => {
  await getClient().shutdown();
  process.exit(0);
});

Configuration

| Option | Type | Default | Description | | :-------------- | :--------- | :------------------------ | :------------------------------------------------------ | | appName | string | "Unknown App" | App name shown in the monitor dashboard | | monitorUrl | string | — | Endpoint of your monitor server | | monitorApiKey | string | — | API key for authenticating with the monitor server | | enabled | boolean | true | Master switch — set to false to disable all capturing | | debug | boolean | true if no monitorUrl | Print captured data to console instead of sending | | saveLocal | boolean | false | Append captured events to a local JSON file | | localPath | string | ./captured-apis.json | Path for the local JSON file | | sensitiveKeys | string[] | See above | Additional keys to redact from bodies and queries | | batchSize | number | 10 | Max events per HTTP batch to the monitor server | | batchInterval | number | 3000 | How often (ms) to flush the event queue |


What gets captured per request

| Field | Description | | :----------- | :--------------------------------------------- | | route | Full URL path including query string | | method | HTTP method (GET, POST, etc.) | | body | Request body (sensitive keys redacted) | | query | Query parameters | | response | Response body (sensitive keys redacted) | | statusCode | HTTP status code | | durationMs | Request processing time in milliseconds | | desc | Your description for this endpoint | | menus | Menu/page labels for grouping in the UI | | routeName | Group name (set via createMiddlewareFactory) | | capturedAt | ISO timestamp |


Changelog

v1.1.0

  • Response captureres.json() is now intercepted to capture response body
  • Status code + duration — every captured event includes HTTP status and response time
  • Async local save — file I/O is now non-blocking
  • Batch sender — events are queued and sent in batches to reduce HTTP overhead
  • Deep masking fix — nested sensitive keys are now correctly redacted
  • enabled config — replaces openGen (still supported for backward compatibility)
  • shutdown() method — flush pending events before process exit

License

ISC