Incidentary Docs

Node.js

Instrument your Node.js services with the Incidentary SDK.

Node.js Quickstart

This guide gets you from zero to your first captured trace in a Node.js service.

Prerequisites

  • Node.js 20+
  • An Incidentary workspace and API key (from the dashboard under Settings → API Keys)

Install

npm install @incidentary/sdk-node

Initialize the client

import { IncidentaryClient, createExpressMiddleware } from '@incidentary/sdk-node';

const incidentary = new IncidentaryClient({
  apiKey: process.env.INCIDENTARY_API_KEY!,
  serviceName: 'my-service',
});

That's the core setup. The SDK automatically instruments outbound HTTP calls (http, https, and fetch()), supported queue libraries, databases, and gRPC — no additional code needed.

Mount inbound middleware

Pick your framework:

Express

app.use(createExpressMiddleware(incidentary));

Fastify

import { FastifyIntegration } from '@incidentary/sdk-node';
const fastifyIntegration = new FastifyIntegration();
fastifyIntegration.patch(incidentary);
fastify.register(fastifyIntegration.plugin());

Koa

import { KoaIntegration } from '@incidentary/sdk-node';
const koaIntegration = new KoaIntegration();
koaIntegration.patch(incidentary);
app.use(koaIntegration.middleware());

Hapi

import { HapiIntegration } from '@incidentary/sdk-node';
const hapiIntegration = new HapiIntegration();
hapiIntegration.patch(incidentary);
await server.register(hapiIntegration.plugin());

The middleware captures every inbound HTTP request automatically. It writes to an in-memory buffer and flushes to Incidentary in the background. Your request handling is not affected.

Outbound HTTP — automatic

The SDK patches http.request, https.request, and fetch() at initialization. Every outbound HTTP call from your service automatically gets x-incidentary-trace-id and x-incidentary-parent-ce headers injected. This works with any HTTP client — axios, got, node-fetch, undici, or plain http.request.

No code changes needed. If you already use OpenTelemetry's HTTP instrumentation, the SDK detects it and skips its own patching to avoid conflicts.

Queue instrumentation — automatic

If your service uses any of these queue libraries, the SDK auto-patches them at startup:

LibraryProducerConsumer
BullMQQueue.add / addBulkWorker processor
amqplibChannel.publish / sendToQueueChannel.consume callback
kafkajsProducer.send / sendBatchConsumer.run eachMessage

Context flows automatically: the producer injects trace context into the message, the consumer extracts it, and all downstream calls from the consumer inherit the trace.

Database instrumentation — automatic

LibraryWhat's captured
pgClient.prototype.query — SQL text (truncated, no parameters)
ioredisRedis.prototype.sendCommand — command name only (no values)

Database events appear as INTERNAL context events in the trace, helping you see what queries ran during an incident.

gRPC support

import { GrpcIntegration } from '@incidentary/sdk-node';
const grpcIntegration = new GrpcIntegration();
grpcIntegration.patch(incidentary);

// Client-side: add interceptor to inject trace context
const channel = new grpc.Client(addr, creds, {
  interceptors: [grpcIntegration.clientInterceptor()],
});

// Server-side: add middleware
server.addService(serviceDefinition, implementation);
// Use grpcIntegration.serverMiddleware() in your call handling

Recording custom events

Queue, job, and webhook events can also be recorded manually when auto-instrumentation doesn't cover your use case:

incidentary.recordQueuePublish({ eventAttrs: { topic: 'orders.created' } });
incidentary.recordQueueConsume();
incidentary.recordJobStart({ eventAttrs: { worker: 'invoice-sync' } });
incidentary.recordJobEnd();
incidentary.recordWebhookIn();
incidentary.recordWebhookOut({ status: 202 });

Environment variables

VariableRequiredDefaultDescription
INCIDENTARY_API_KEYYesWorkspace API key (sk_...) from the dashboard
INCIDENTARY_SERVICE_NAMENoAlternative to passing serviceName in code
INCIDENTARY_ENVIRONMENTNoproductionEnvironment label (production, staging, etc.)
INCIDENTARY_API_URLNohttps://api.incidentary.comOverride for self-hosted or local dev

Verify capture

After deploying with the SDK installed:

  1. Make a request to your service
  2. Open the Incidentary dashboard → Traces
  3. A trace should appear within a few seconds

If no trace appears within 30 seconds, see the troubleshooting section below.

What happens during an incident

When an alert fires (via Slack, PagerDuty, or OpsGenie), Incidentary assembles the causal chain from events your service has already captured. The SDK continuously maintains a rolling window of recent activity — events from before the alert fired are included in the assembled artifact.

The SDK does not create incidents or page anyone. It is passive until an alert arrives.

Troubleshooting

401 Unauthorized on ingest: You are using a user session token, not a workspace API key. API keys start with sk_ and are found in Settings → API Keys.

No traces in the dashboard: Ensure your process calls flushToBackend() after requests. In serverless environments, you may need to call this explicitly at the end of each invocation.

426 SDK_VERSION_TOO_OLD: Upgrade to @incidentary/sdk-node@0.2.0 or newer.

Services not linked: You are not propagating the x-incidentary-trace-id and x-incidentary-parent-ce headers on outbound calls. See the outbound propagation section above.

On this page