Documentation · Node.js SDK 0.1.0

Add InflowAPM to an Express application.

Install the SDK, add a project key, instrument Express, and send your first request. Reliability and architecture details follow the quickstart.

Getting started

From install to first telemetry

Use Node.js 24 or newer. Express 4.18 and Express 5 are supported. Express is an optional peer dependency, so non-Express applications can still use the manual event API.

Available on npm: Install the public @inflowapm/node package with the command below.

terminalShell
npm install @inflowapm/node

1. Create a project key

Registration, sign-in, session refresh, sign-out, and password recovery are connected to the current authentication API. After signing in, create a project and copy the api_key from the creation response. It is returned in raw form only when the project is created.

project-key.shShell
# You can create a project in the dashboard or through the API.
curl -X POST http://127.0.0.1:5002/api/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{"email":"dev@example.com","password":"replace-me","first_name":"Developer","last_name":"Example"}'

curl -X POST http://127.0.0.1:5002/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"dev@example.com","password":"replace-me"}'

curl -X POST http://127.0.0.1:5002/api/v1/projects \
  -H "Authorization: Bearer USER_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"Checkout API"}'

2. Configure the service

.envEnvironment
INFLOWAPM_API_KEY=iapm_project_key
INFLOWAPM_ENDPOINT=http://127.0.0.1:5002
INFLOWAPM_SERVICE=checkout-api
INFLOWAPM_ENVIRONMENT=development
INFLOWAPM_SERVICE_VERSION=1.4.0

3. Instrument Express

server.jsNode.js
import express from "express";
import { InflowAPM } from "@inflowapm/node";

const app = express();
const inflow = new InflowAPM({
  apiKey: process.env.INFLOWAPM_API_KEY,
  endpoint: process.env.INFLOWAPM_ENDPOINT,
  service: process.env.INFLOWAPM_SERVICE,
  environment: process.env.INFLOWAPM_ENVIRONMENT,
  serviceVersion: process.env.INFLOWAPM_SERVICE_VERSION ?? "1.4.0",
});

app.use(inflow.express());
app.get("/health", (_request, response) => response.send("ok"));

app.listen(3000);

4. Run and verify

Start the application, send a request with a browser, curl, or Postman, then call await inflow.flush() while testing. Inspect the flush result or inflow.getStats(). The current analytics API is GET /api/v1/telemetry/analytics/dashboard?project_id=PROJECT_ID&range=24h and uses the user access token.

Using the SDK

Configuration reference

Pass configuration explicitly at startup. The SDK validates it without throwing into application startup; invalid configuration disables telemetry and appears in getStats().configurationIssue.

OptionDefaultPurpose
apiKeyrequiredProject API key. Keep it on the server.
endpointrequiredHTTP(S) InflowAPM base URL; the SDK appends the ingestion path.
servicerequiredStable service name, such as checkout-api.
environmentrequiredDeployment name, such as development, staging, or production.
serviceVersionoptionalRelease version attached to telemetry.
enabledtrueDisable capture without removing instrumentation.
batchSize100Maximum events in one backend-compatible batch.
maxBufferSize1000Bounded in-memory event capacity.
flushThresholdbatch sizeBuffered event count that schedules delivery.
flushIntervalMs5000Background delivery interval.
requestTimeoutMs5000Timeout for each ingestion request.
maxAttempts3Total delivery attempts for retryable failures.
shutdownTimeoutMs5000Bound for the final shutdown drain.
debugfalseSafe lifecycle diagnostics without payloads or keys.

The endpoint must be an HTTP(S) base URL without credentials, query parameters, or a fragment. If it includes a path, the SDK preserves it and appends /api/v1/telemetry/ingest.

Using the SDK

Express integration

Install inflow.express() before the routes you want to observe. The middleware records the matched route template after the response finishes, avoiding high-cardinality raw URLs.

mounted-router.jsNode.js
const api = express.Router();

api.use(inflow.express({ routePrefix: "/api" }));
api.get("/orders/:orderId", getOrder);
app.use("/api", api);

Mounted routers can provide routePrefix. Requests with no matched route are recorded as /__unmatched__. Supported methods are GET, POST, PUT, PATCH, DELETE, OPTIONS, and HEAD.

Using the SDK

Automatic HTTP monitoring

The middleware records the normalized route, method, response status, duration, timestamp, service, environment, and optional service version. It also marks a response that closes before completion. It does not automatically capture thrown error objects or stack traces.

  • Stable route templates
  • Response status
  • Request duration
  • Premature close metadata

Using the SDK

Manual events

Use captureEvent() for supported application work that is not represented by an HTTP request. Application event routes are currently query, error, and timeout.

manual-event.jsNode.js
const result = inflow.captureEvent({
  type: "event",
  route: "query",
  durationMs: 87,
  metadata: { operation: "load_checkout" },
});

if (!result.accepted) {
  console.warn(result.reason);
}

The return value reports whether the event was accepted into the local buffer. It does not claim that the backend has persisted the event.

Development

Localhost and debugging

Use http://127.0.0.1:5002 when the application and InflowAPM backend run directly on the same machine. From a container, use a hostname reachable from that container instead of assuming its own localhost points to the host.

Browser / curl / Postman

send request

localhost:3000

your Express app

InflowAPM :5002

receives telemetry

Set debug: true only while diagnosing. Debug output covers lifecycle classifications and never logs the project key or event payload.

Deployment

Staging, production, and self-hosting

Keep one stable service name across deployments and change the explicit environment value. Point endpoint at the reachable InflowAPM base URL for each environment. Environment filtering is not yet present in the frontend, so the configuration distinction is captured in telemetry rather than advertised as a dashboard control.

shutdown.jsNode.js
process.once("SIGTERM", async () => {
  await inflow.shutdown();
  server.close();
});

The host application owns process signals. Call shutdown() from its existing shutdown path; the SDK does not install signal handlers or keep the process alive solely for telemetry.

Reliability

Bounded, retrying, and fail-open

The middleware performs validation and a bounded in-memory append after the response lifecycle. Background delivery starts at the threshold, on the interval, after an explicit flush(), or during shutdown().

Buffering
The default buffer holds 1,000 events. New events are dropped when it is full; memory does not grow without a bound.
Retry
Network failures, timeouts, 408, 429, and 5xx responses retry with full-jitter backoff. Retry-After is respected.
Permanent failures
400, 401, 403, 413, 422, and other non-retryable 4xx responses are classified without an endless retry loop.
Fail-open
Capture and delivery errors do not throw through the application request path.
Rate limiting
Backend 429 responses are counted and retried within the configured attempt limit; the SDK does not bypass server limits.

Security & privacy

Keep credentials and payload data out

Server-side only. Never embed a project API key in browser, mobile, or other distributed client code. Treat it as a secret and rotate it if exposed.

Automatic Express instrumentation records route templates and timing data. It does not read the raw URL, query values, route parameter values, headers, authorization, cookies, or request and response bodies. It does not collect stack traces automatically. Manual identity fields and metadata are opt-in, so review them before sending sensitive or regulated data.

Architecture

Request path and telemetry path

Request path

Client → Express middleware → route handler → application response

Telemetry path

Lifecycle callback → bounded buffer → retrying batch delivery → ingestion API → BullMQ → PostgreSQL analytics

The SDK is responsible through authenticated ingestion. The backend accepts batches, processes them asynchronously through BullMQ, stores project-scoped events in PostgreSQL, and exposes analytics through the current API.

Reference

Troubleshooting and current limits

No events are visible

Inspect getStats(), verify the project key and server-reachable endpoint, install middleware before routes, and call await inflow.flush() while testing.

Dynamic IDs appear in routes

Confirm Express matched a declared route and that the middleware can observe it. Use routePrefix for mounted routers. Raw unmatched paths intentionally become /__unmatched__.

The process exits before delivery

Await flush() in short-lived tasks or shutdown() in the host shutdown path. Unreferenced timers do not guarantee delivery after a serverless runtime freezes an invocation.

Current limitations

The SDK does not patch Express globally, capture stack traces automatically, persist its local buffer to disk, install process signal handlers, or provide browser/mobile instrumentation. Python support is not implemented yet.

For exact option ranges, typed return values, and package engineering notes, read the package README and source.