Zero-dependency Node.js SDK for PeekAPI. Add API analytics to any Node.js framework with one line of middleware.
npm install @peekapi/sdk-nodeimport express from "express";
import { peekapi } from "@peekapi/sdk-node";
const app = express();
app.use(peekapi({ apiKey: "ak_live_xxx" }));
app.get("/api/users", (req, res) => res.json({ users: [] }));
app.listen(3000);import Fastify from "fastify";
import { peekapiFastify } from "@peekapi/sdk-node";
const app = Fastify();
app.register(peekapiFastify, { apiKey: "ak_live_xxx" });
app.get("/api/users", async () => ({ users: [] }));
app.listen({ port: 3000 });import Koa from "koa";
import { peekapiKoa } from "@peekapi/sdk-node";
const app = new Koa();
app.use(peekapiKoa({ apiKey: "ak_live_xxx" }));
app.use((ctx) => { ctx.body = { users: [] }; });
app.listen(3000);import Hapi from "@hapi/hapi";
import { peekapiHapi } from "@peekapi/sdk-node";
const server = Hapi.server({ port: 3000 });
await server.register({ plugin: peekapiHapi, options: { apiKey: "ak_live_xxx" } });
server.route({ method: "GET", path: "/api/users", handler: () => ({ users: [] }) });
await server.start();import { Module } from "@nestjs/common";
import { APP_INTERCEPTOR } from "@nestjs/core";
import { PeekApiInterceptor } from "@peekapi/sdk-node";
@Module({
providers: [
{
provide: APP_INTERCEPTOR,
useFactory: () => new PeekApiInterceptor({ apiKey: "ak_live_xxx" }),
},
],
})
export class AppModule {}import { PeekApiClient } from "@peekapi/sdk-node";
const client = new PeekApiClient({ apiKey: "ak_live_xxx" });
client.track({
method: "GET",
path: "/api/users",
status_code: 200,
response_time_ms: 42,
});
// Graceful shutdown (flushes remaining events)
client.shutdown();| Option | Default | Description |
|---|---|---|
apiKey |
required | Your PeekAPI key |
endpoint |
PeekAPI cloud | Ingestion endpoint URL |
flushInterval |
10000 |
Milliseconds between automatic flushes |
batchSize |
100 |
Events per HTTP POST (triggers flush) |
maxBufferSize |
10000 |
Max events held in memory |
maxStorageBytes |
5242880 |
Max disk fallback file size (5MB) |
maxEventBytes |
65536 |
Per-event size limit (64KB) |
storagePath |
auto | Custom path for JSONL persistence file |
debug |
false |
Enable debug logging |
identifyConsumer |
auto | Custom consumer ID extraction function |
tlsOptions |
undefined |
TLS options for https.Agent |
onError |
undefined |
Callback for background flush errors |
- Middleware intercepts every request/response
- Captures method, path, status code, response time, request/response sizes, consumer ID
- Events are buffered in memory and flushed in batches on a timer or when
batchSizeis reached - Flushes are async and non-blocking — <1ms overhead per request
- On network failure: exponential backoff with jitter, up to 5 retries
- After max retries: events are persisted to a JSONL file on disk
- On next startup: persisted events are recovered and re-sent
- On SIGTERM/SIGINT: remaining buffer is flushed or persisted to disk
By default, consumers are identified by:
X-API-Keyheader — stored as-isAuthorizationheader — hashed with SHA-256 (stored ashash_<hex>)
Override with the identifyConsumer option to use any header or request property:
app.use(peekapi({
apiKey: "ak_live_xxx",
identifyConsumer: (req) => req.headers["x-tenant-id"],
}));| Field | Description |
|---|---|
method |
HTTP method (GET, POST, etc.) |
path |
Route path (no query strings) |
status_code |
Response status code |
response_time_ms |
Time to respond in ms |
request_size |
Request body size in bytes |
response_size |
Response body size in bytes |
consumer_id |
API consumer identifier |
timestamp |
ISO 8601 timestamp |
- Node.js >= 18
Bug reports and feature requests: peekapi-dev/community
- Fork & clone the repo
- Install dependencies —
npm install - Run tests —
npm test - Submit a PR
If you find PeekAPI useful, give this repo a star — it helps others discover the project.
Show that your API is monitored by PeekAPI:
[](https://peekapi.dev)MIT