SDK Documentation
Introduction
VantaTrace is a real-time error tracking, telemetry, and observability SDK for Node.js applications and microservices. It captures exceptions, runtime metrics, and request context, then streams them to your centralized VantaTrace dashboard.
Zero Blocking
All payloads are dispatched asynchronously via setImmediate — no request latency added.
Smart Batching
Events are batched and flushed every 500 ms, or immediately for critical severity.
Fail-Safe
SDK errors are caught internally — it will never crash your host application.
Auto Deduplication
Duplicate error objects are filtered via WeakSet to prevent double-reporting.
Installation
Install the SDK from npm. It has zero runtime dependencies and works with any Node.js framework.
npm install @vantatrace/sdk@types/ package needed.Initialization
Create a single VantaTrace instance in your main entry file (e.g. app.js or server.ts) and export it for use across your service.
import { VantaTrace } from '@vantatrace/sdk';
const vantaTrace = new VantaTrace({
apiKey: 'ep_live_xxxxxxxxxxxxxxxxxxxxxxxx', // Your project API key
serviceName: 'my-api-service',
debug: false, // Enable verbose SDK logs in development
});Configuration Options
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
| apiKey | string | Yes | — | Your project API key from the VantaTrace dashboard. Prefix determines environment (ep_live_ → live, ep_test_ → test). |
| serviceName | string | Yes | — | Human-readable identifier for this service. Appears in the dashboard as the error source. |
| debug | boolean | No | false | When true, the SDK prints verbose logs to stdout (trace IDs, payloads, transport status). |
Environments & API Keys
VantaTrace derives the environment directly from your API key — no manual environment config needed:
ep_live_…liveep_test_…testGlobal Handlers
Call initGlobalHandlers() once after initialization to register a safety net that automatically captures:
- Synchronous uncaught exceptions — process.on('uncaughtException') — runtime crashes, typos, undefined refs.
- Unhandled promise rejections — process.on('unhandledRejection') — re-thrown errors inside async catch blocks.
- console.error() calls — Auto-patched — any Error passed to console.error is forwarded.
- Winston logger errors — Auto-patched at runtime if the winston package is installed.
- Pino logger errors — Auto-patched at runtime if the pino package is installed.
// Call once, right after initialization
vantaTrace.initGlobalHandlers();
// This registers:
// 1. process.on('uncaughtException', ...) – synchronous crashes
// 2. process.on('unhandledRejection', ...) – async/await rejections
// 3. console.error patch – errors via console.error
// 4. Winston auto-patch (if installed)
// 5. Pino auto-patch (if installed)Express Middleware
VantaTrace provides two Express middlewares that work together to capture full HTTP request context alongside every error.
requestHandler()
Mount this at the very top of your middleware stack, before any routes or body parsers. It seeds an AsyncLocalStorage context with request metadata (route, method, IP, sanitized headers, sanitized body).
password, token, and headers such as authorization and cookie are automatically redacted before being stored or transmitted.errorHandler()
Mount this at the very bottom of your middleware stack, after all routes and controllers. It intercepts any error passed to next(err) and forwards it to VantaTrace while calling next(err) so your own error handler still runs.
import express from 'express';
import { VantaTrace } from '@vantatrace/sdk';
const app = express();
const vantaTrace = new VantaTrace({
apiKey: process.env.VANTATRACE_API_KEY!,
serviceName: 'checkout-service',
});
// ① Mount requestHandler FIRST — before any routes or body parsers
app.use(vantaTrace.requestHandler());
app.use(express.json());
// ... your routes ...
app.get('/api/orders', async (req, res) => {
const orders = await fetchOrders(); // any thrown error is auto-captured
res.json(orders);
});
// ② Mount errorHandler LAST — after all routes and controllers
app.use(vantaTrace.errorHandler());
// Your own error response handler (still called via next(err))
app.use((err, req, res, next) => {
res.status(500).json({ message: 'Internal Server Error' });
});
app.listen(3000);Capturing Errors
captureException(error, context?)
The primary method for manual error capture. Use inside try/catch blocks to send errors with rich business context.
try {
await chargeCard(userId, amount);
} catch (error) {
vantaTrace.captureException(error, {
userId: 'user_482',
route: '/api/checkout',
method: 'POST',
severity: 'critical',
metadata: {
amount: 29.99,
currency: 'USD',
},
});
throw error; // re-throw if needed
}Severity Helpers
Convenience wrappers that set the severity field automatically:
// Equivalent to captureException with severity: 'critical'
vantaTrace.captureCritical(error, { userId: 'user_42' });
// Equivalent to captureException with severity: 'warning'
vantaTrace.captureWarning(error, { route: '/api/webhook' });
// Equivalent to captureException with severity: 'info'
vantaTrace.captureInfo(error, { metadata: { source: 'scheduler' } });| Option | Type | Required | Default | Description |
|---|---|---|---|---|
| captureCritical() | method | No | — | Forwards error with severity: "critical". Dashboard shows a red badge. |
| captureWarning() | method | No | — | Forwards error with severity: "warning". Dashboard shows an amber badge. |
| captureInfo() | method | No | — | Forwards error with severity: "info". Dashboard shows a blue badge. |
Context Object
The optional second argument to all capture methods accepts a VantaTraceContext object:
// The full VantaTraceContext object you can pass to captureException:
{
userId?: string; // Authenticated user ID
route?: string; // API route (e.g. '/api/checkout')
method?: string; // HTTP method (e.g. 'POST')
ip?: string; // Client IP address
headers?: Record<string, any>; // Sanitized HTTP headers
severity?: 'critical' | 'warning' | 'info';
metadata?: Record<string, any>; // Any custom key-value payload
}userId, route, method, ip, and headers are auto-populated from the request via AsyncLocalStorage — you only need to pass additional metadata.Logger Integrations
When initGlobalHandlers() is called, VantaTrace automatically detects and patches popular loggers. No additional configuration is required.
Winston
A custom winston-transport is injected at runtime. Any Error object logged via logger.error() is forwarded to VantaTrace.
import winston from 'winston';
import { VantaTrace } from '@vantatrace/sdk';
const vantaTrace = new VantaTrace({
apiKey: process.env.VANTATRACE_API_KEY!,
serviceName: 'my-service',
});
// Auto-patches Winston when initGlobalHandlers() is called.
// Any logger.error(error) call where the argument is an Error
// will be automatically forwarded to VantaTrace.
vantaTrace.initGlobalHandlers();
const logger = winston.createLogger({
transports: [new winston.transports.Console()],
});
// This error will appear in your VantaTrace dashboard:
logger.error(new Error('Database connection refused'));Pino
Pino's write() prototype method is patched. Errors passed directly or inside { err } / { error } objects are captured.
import pino from 'pino';
import { VantaTrace } from '@vantatrace/sdk';
const vantaTrace = new VantaTrace({
apiKey: process.env.VANTATRACE_API_KEY!,
serviceName: 'my-service',
});
// Auto-patches Pino when initGlobalHandlers() is called.
vantaTrace.initGlobalHandlers();
const logger = pino();
// Any of these patterns will forward errors to VantaTrace:
logger.error(new Error('Connection timeout'));
logger.error({ err: new Error('DB query failed') }, 'Database error');
logger.error({ error: new Error('Payment failed') }, 'Payment error');console.error Patch
console.error is monkey-patched to intercept any Error argument. The original console.error is still called — VantaTrace only adds its own capture on top.
Trace ID Correlation
Every captured error is tagged with a unique 32-character hex Trace ID. You can retrieve the ID bound to the current async request context using the static method VantaTrace.getActiveTraceId().
This allows you to correlate your own log lines (Winston, Pino, or custom) with the exact error event visible in the VantaTrace dashboard.
import { VantaTrace } from '@vantatrace/sdk';
// Get the active trace ID bound to the current async request context.
// Use this to correlate your own log entries with the VantaTrace dashboard event.
const traceId = VantaTrace.getActiveTraceId();
// Example: attach traceId to your response headers for distributed tracing
app.use(vantaTrace.requestHandler());
app.get('/api/orders', (req, res) => {
const traceId = VantaTrace.getActiveTraceId();
res.setHeader('X-Trace-Id', traceId ?? '');
// ...
});Ready to get started?
Create a free account