What is Statvisor?

Statvisor is a backend API monitoring platform. Install a lightweight SDK into your existing backend, and every HTTP route is automatically instrumented β€” you get real-time latency percentiles, error rates, request volume, and status code distributions without writing any custom telemetry code.

⚑

One-line setup

One middleware call instruments every route automatically.

πŸ“Š

Real-time analytics

P50/P95/P99 latency, error rates, and volume charts.

πŸ”’

Privacy-first

No request/response bodies. No end-user IP addresses.

Up and running in 2 minutes

The flow is the same regardless of framework: create a project, grab your API key, install the SDK, add one line. Here's the generic version:

1

Create a project in the dashboard

Go to statvisor.com/dashboard β†’ click New project β†’ enter your project name and the full URL of your backend (e.g. https://api.example.com). This is the origin where your API is hosted β€” scheme and host only, no path.
2

Copy your API key

After creating the project, your API key is shown exactly once. Copy it β€” it starts with vl_. Store it securely (e.g. in an environment variable).
3

Install the SDK

npm install @statvisor/sdk
4

Add the middleware

See the framework-specific guides below for the exact one-liner.
5

Verify it's working

Make any HTTP request to your API. Within a few seconds you should see it appear in the dashboard with route, method, status code, and latency.

Under the hood

The SDK wraps your framework's request lifecycle using standard middleware hooks. It records the wall-clock time before your handler runs and after it completes, capturing:

  • Route path (normalised β€” e.g. /users/:id, not /users/123)
  • HTTP method (GET, POST, PUT, PATCH, DELETE…)
  • Response status code
  • Duration in milliseconds
  • Timestamp (UTC)

Events are queued in memory and flushed to https://statvisor.com/api/ingest asynchronously in the background. Your request handlers are never blocked.

Statvisor never captures request bodies, response bodies, query parameters, headers, or any end-user PII. Only the metadata listed above is sent.

Node.js

Express.js Integration

Works with Express 4 and 5. Register the middleware before your routes so every request is captured.

1

Install the SDK

npm install @statvisor/sdk
2

Add the middleware

app.js
import express from "express";
import { express as statvisor } from "@statvisor/sdk";

const app = express();

// Add Statvisor BEFORE your routes
app.use(statvisor({ apiKey: process.env.STATVISOR_API_KEY }));

// Your routes
app.get("/users", (req, res) => {
  res.json({ users: [] });
});

app.listen(3000);
3

Set your environment variable

.env
STATVISOR_API_KEY=vl_your_api_key_here

The middleware must be registered before your route handlers. Place app.use(statvisor(…)) at the top of your middleware stack, before any app.use(router) calls.

Node.js

Fastify Integration

Works with Fastify v4 and v5. Register as a plugin with fastify.register().

1

Install the SDK

npm install @statvisor/sdk
2

Register the plugin

server.js
import Fastify from "fastify";
import { fastify as statvisor } from "@statvisor/sdk";

const app = Fastify({ logger: true });

// Register Statvisor plugin
await app.register(statvisor, {
  apiKey: process.env.STATVISOR_API_KEY,
});

// Your routes
app.get("/users", async (request, reply) => {
  return { users: [] };
});

await app.listen({ port: 3000 });
3

Set your environment variable

.env
STATVISOR_API_KEY=vl_your_api_key_here
Node.js

NestJS Integration

Coming soon. Native NestJS support is on the roadmap. In the meantime, you can instrument a NestJS app by using the Express adapter β€” NestJS uses Express under the hood by default, so registering the Express middleware in your main.ts works today.

main.ts
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import { express as statvisor } from "@statvisor/sdk";

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // Register Statvisor before any other middleware
  app.use(statvisor({ apiKey: process.env.STATVISOR_API_KEY }));

  await app.listen(3000);
}
bootstrap();
Node.js

Hono Integration

Works with Hono on any runtime β€” Node.js, Bun, Deno, Cloudflare Workers.

1

Install the SDK

npm install @statvisor/sdk
2

Add the middleware

index.ts
import { Hono } from "hono";
import { createMiddleware } from "@statvisor/sdk";

const app = new Hono();

// Add Statvisor before your routes
app.use("*", createMiddleware({ apiKey: process.env.STATVISOR_API_KEY }));

app.get("/users", (c) => {
  return c.json({ users: [] });
});

export default app;
3

Set your environment variable

# Node.js / Bun
STATVISOR_API_KEY=vl_your_api_key_here

# Cloudflare Workers β€” use wrangler.toml
[vars]
STATVISOR_API_KEY = "vl_your_api_key_here"
Node.js

Next.js Integration

Because Next.js API routes are serverless functions, Statvisor uses a route wrapper pattern. You initialise the SDK once in a shared file and use the returned route helper to wrap each route file's handlers.

Statvisor monitors your API routes (app/api/), not page routes or Server Actions. If your Next.js app proxies to a separate backend, instrument that backend directly with the Express or Fastify integration.

1

Install the SDK

npm install @statvisor/sdk
2

Initialise once in a shared lib file

Create a file that initialises the SDK and exports the helpers. Import from this file in every API route.

lib/statvisor.ts
import { nextjs } from "@statvisor/sdk";

export const { route, monitor } = nextjs({
  apiKey: process.env.STATVISOR_API_KEY!,
});
3

Wrap your route handlers

Use route() in each API route file. Pass the route path and an object of handlers β€” the returned object has the same keys ready to export.

app/api/users/route.ts
import { NextResponse } from "next/server";
import { route } from "@/lib/statvisor";

export const { GET, POST } = route("/api/users", {
  GET: async (request) => {
    const users = await db.query("SELECT * FROM users");
    return NextResponse.json({ users });
  },
  POST: async (request) => {
    const body = await request.json();
    const user = await db.create(body);
    return NextResponse.json({ user }, { status: 201 });
  },
});
4

Dynamic route segments

Pass the route pattern with the dynamic segment. The SDK records it as the pattern (e.g. /api/users/:id), not the actual URL, so routes are properly grouped in your dashboard.

app/api/users/[id]/route.ts
import { NextResponse } from "next/server";
import { route } from "@/lib/statvisor";

export const { GET } = route("/api/users/:id", {
  GET: async (request, { params }) => {
    const { id } = await params;
    const user = await db.findById(id);
    if (!user) return NextResponse.json({ error: "Not found" }, { status: 404 });
    return NextResponse.json({ user });
  },
});
5

Set your environment variable

.env.local
# Keep this server-side only β€” do NOT prefix with NEXT_PUBLIC_
STATVISOR_API_KEY=vl_your_api_key_here

The API key must stay server-side. Never prefix it with NEXT_PUBLIC_ β€” that would expose it in your client bundle.

Python

FastAPI Integration

Coming soon. A Python SDK with FastAPI / Starlette support is on the roadmap. You can follow progress or sign up for updates at hello@statvisor.com.

Python

Django Integration

Coming soon. Django support is planned as part of the Python SDK. Reach out at hello@statvisor.com to be notified when it's available.

Configuration reference

All options are the same across Express, Fastify, Hono, and Next.js integrations.

OptionTypeDefaultDescription
apiKeystringβ€”Required. Your project API key (starts with vl_).
enabledbooleantrueSet false to disable tracking (useful for local dev).
flushIntervalnumber5000How often (ms) the SDK flushes buffered events.
batchSizenumber50Max events to include in a single flush.
ignoreRoutesstring[][]Route paths to exclude from tracking (e.g. ["/health"]).
debugbooleanfalseLog SDK activity to console for troubleshooting.

Example with all options

app.js
import { express as statvisor } from "@statvisor/sdk";

app.use(statvisor({
  apiKey: process.env.STATVISOR_API_KEY,
  enabled: process.env.NODE_ENV === "production",
  flushInterval: 3000,
  batchSize: 50,
  ignoreRoutes: ["/health", "/ping", "/_internal"],
  debug: false,
}));

Using the dashboard

Once your SDK is sending data, the dashboard shows it in real time.

Projects list

The projects page shows all your monitored APIs. Each card displays the project name, domain, and a quick summary. Click a project to open its analytics dashboard. Use the copy button on a project card to copy the API key to your clipboard.

Analytics dashboard

Summary cards
The four cards at the top show total requests, error rate, median latency, and active route count for the selected time range.
Time range selector
Switch between 1h, 6h, 24h, and 7d. All charts and the route table update to match.
Volume chart
Bar chart showing request count and error count over time. Hover a bar to see the exact counts for that interval.
Latency chart
Line chart showing P50, P95, and P99 latency over time. Pro plan required to see all three percentiles.
Route table
Sortable table of every route. Columns: route, method, requests, avg latency, P50/P95/P99, error rate. Click any column header to sort.
Error rate vs health error rate
Error rate counts all 4xx and 5xx. Health error rate excludes your configured 'expected' codes (401, 403, 404 etc.) β€” it's the signal you actually care about.

Plans & limits

FeatureFreePro
Projects1Unlimited
Data retention7 days30 days
Latency percentilesP50 onlyP50 / P95 / P99
Custom expected codesβ€”βœ“
Volume chartβœ“βœ“
Route tableβœ“βœ“
SupportCommunityPriority
Price$0 / mo$19 / mo

Upgrade or manage your plan from the Settings β†’ Plan page. Billing is handled by Stripe. Cancel anytime.

Ready to start monitoring?

Free forever. No credit card required.

Create your free account