βββββββ βββββββ βββββββ βββββββ
βββββββββββββββββββββββββββββββββ
βββββββββββββββββββ ββββββ βββ
βββββββ βββββββββββ ββββββ βββ
βββ βββ ββββββββββββββββββββ
βββ βββ βββ βββββββ βββββββ
βββββββ βββ ββββββ ββββββββββββββββ
βββββββββββ ββββββ ββββββββββββββββ
βββββββββββ ββββββ ββββββββββββββ
βββββββ βββ ββββββ ββββββββββββββ
βββ βββββββββββββββββββββββββββββββββ
βββ βββββββ ββββββββββββββββββββββββ
The official Node.js SDK for ProdPulse.AI
AI-powered production monitoring. Understand and fix errors instantly β with full context, zero guesswork.
- Overview
- What's New in v2.0.0
- Installation
- Quick Start
- Get Your API Key
- Configuration
- Express & Fastify Middleware
- Database Monitoring
- Manual Error Capture
- Security & Auto-Sanitization
- Offline Queue & Resilience
- Debug Mode
- Context Snapshot
- API Reference
- Support
prodpulse-node-sdk gives your Node.js applications a complete observability layer. Every error is captured with deep context β not just a stack trace, but the exact git commit that introduced it, the system state at the time, the HTTP request that triggered it, and a security-scrubbed snapshot of your environment.
Built for production. Designed to be invisible until you need it.
your app β prodpulse sdk β context engine β prodpulse.ai dashboard
β
βββββββββββββββββ
β git context β which commit, branch, author
β sys context β cpu, memory, uptime
β app context β version, env, framework
β req context β method, url, sanitized headers
β dedup engine β once per hour, max
β offline queueβ never lose an error
βββββββββββββββββ
v2.0.0 ships a fully rewritten context engine. Every error event now carries a 360Β° diagnostic payload so you can reproduce and fix issues without ever asking "what was the state of the system?"
| # | Feature | Description |
|---|---|---|
| 1 | π§© Rich Context Capture | File path, line number, and function name on every error β no sourcemaps needed |
| 2 | πΏ Git Context | Commit SHA, branch name, and author of the offending code, auto-detected |
| 3 | π» System Context | CPU usage, total/free memory, and process uptime at moment of error |
| 4 | π¦ App Context | App version, environment, and auto-detected framework (Express, Fastify, Koa, NestJS) |
| 5 | π Request Context | HTTP method, URL, sanitized headers, and request ID for every inbound request |
| 6 | π Security Sanitization | Passwords, JWTs, AWS keys, DB URLs, and credit cards auto-redacted before leaving your server |
| 7 | π Smart Deduplication | The same error fires at most once per hour β clean dashboards, intact quota |
| 8 | π‘ Offline Queue | Errors are queued in memory when the API is unreachable and flushed on reconnect |
| 9 | π‘οΈ Express Middleware | Drop-in requestMiddleware and errorMiddleware for full HTTP observability |
| 10 | π TLS 1.2+ Enforced | All outbound connections enforce TLS 1.2 minimum β no exceptions |
| 11 | π Exponential Backoff | Transient delivery failures retry automatically with backoff β no thundering herd |
# npm
npm install prodpulse-node-sdk
# yarn
yarn add prodpulse-node-sdk
# pnpm
pnpm add prodpulse-node-sdkRequirements: Node.js >= 16.0.0
Add this at the very top of your application entry file, before any other require() calls. This ensures that even startup errors are captured.
// β
app.js β line 1
const prodpulse = require('prodpulse-node-sdk');
prodpulse.init('pp_live_xxx', {
appName: 'My API',
appVersion: '2.0.2,
environment: 'production',
});
// All unhandled errors and promise rejections are now captured automatically.
// Continue loading the rest of your application below.
const express = require('express');
// ...That's it. uncaughtException and unhandledRejection are both captured by default β no additional wiring required.
- Sign up or log in at app.prodpulse.ai
- Navigate to Settings β API Keys
- Create a new key β choose
pp_live_for production orpp_test_for development - Copy the key and pass it to
prodpulse.init()
Keep your API key secret. Do not commit it to source control. Use environment variables:
prodpulse.init(process.env.PRODPULSE_API_KEY, { ... });
prodpulse.init(apiKey, options) accepts the following options:
| Option | Type | Default | Description |
|---|---|---|---|
appName |
string |
'unnamed-app' |
Human-readable application name shown in the dashboard |
appVersion |
string |
'0.0.0' |
Your application's semantic version |
environment |
string |
'production' |
Deployment environment β 'development', 'staging', or 'production' |
captureUnhandled |
boolean |
true |
Auto-capture uncaughtException and unhandledRejection events |
deduplicationWindow |
number |
3600 |
Seconds before the same error is eligible to be sent again (default: 1 hour) |
maxQueueSize |
number |
100 |
Max offline queue depth β oldest events are dropped when exceeded |
sanitize |
boolean |
true |
Enable automatic secret redaction. Locked true in production |
ignoredErrors |
string[] |
[] |
Error message substrings to silently discard |
beforeSend |
function |
null |
(event) => event | null β modify or suppress events before dispatch |
debug |
boolean |
false |
Enable verbose SDK logging (see Debug Mode) |
endpoint |
string |
Auto | Override the ingestion endpoint for self-hosted or proxy deployments |
prodpulse.init(process.env.PRODPULSE_API_KEY, {
appName: 'Payments Service',
appVersion: process.env.npm_package_version,
environment: process.env.NODE_ENV,
// Suppress noisy, unactionable errors
ignoredErrors: ['ECONNRESET', 'socket hang up', 'read ETIMEDOUT'],
// Deduplicate aggressively in high-traffic services
deduplicationWindow: 1800, // 30 minutes
// Enrich or gate events before they are sent
beforeSend: (event) => {
// Drop health-check triggered errors
if (event.request?.url === '/health') return null;
// Attach business context
event.tags = {
...event.tags,
team: 'platform',
region: process.env.AWS_REGION,
};
return event;
},
});Mount requestMiddleware as the first middleware and errorMiddleware as the last β after all routes and other middleware.
const express = require('express');
const prodpulse = require('prodpulse-node-sdk');
prodpulse.init(process.env.PRODPULSE_API_KEY, {
appName: 'My API',
environment: 'production',
});
const app = express();
// β First β attaches request context to every incoming request
app.use(prodpulse.requestMiddleware());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// Your routes
app.get('/users/:id', async (req, res) => { /* ... */ });
app.post('/checkout', async (req, res) => { /* ... */ });
// β‘ Last β captures errors from all routes and middleware above
app.use(prodpulse.errorMiddleware());
app.listen(3000, () => console.log('Server running on port 3000'));const fastify = require('fastify')({ logger: true });
const prodpulse = require('prodpulse-node-sdk');
prodpulse.init(process.env.PRODPULSE_API_KEY, {
appName: 'My Fastify API',
environment: 'production',
});
// Attach request context on every incoming request
fastify.addHook('onRequest', prodpulse.requestMiddleware());
// Capture all errors thrown by route handlers
fastify.setErrorHandler(prodpulse.errorMiddleware());
fastify.listen({ port: 3000 });| Field | Example Value | Notes |
|---|---|---|
method |
POST |
β |
url |
/api/v1/checkout |
Query params sanitized |
statusCode |
500 |
β |
ip |
103.21.Γ.Γ |
Partially masked |
userAgent |
Mozilla/5.0 ... |
β |
requestId |
req_7f3k2p |
Auto-generated if not present |
authorization |
[REDACTED] |
Always scrubbed |
cookie |
[REDACTED] |
Always scrubbed |
x-api-key |
[REDACTED] |
Always scrubbed |
x-auth-token |
[REDACTED] |
Always scrubbed |
Monitor query performance and connection errors across your entire data layer with a single call per connection.
const prodpulse = require('prodpulse-node-sdk');
const mysql = require('mysql2');
const { Pool } = require('pg');
const mongoose = require('mongoose');
// Create your connections as usual
const mysqlConn = mysql.createConnection({ host: 'localhost', database: 'mydb' });
const pgPool = new Pool({ connectionString: process.env.DATABASE_URL });
// Hand them to ProdPulse β instrumentation is applied automatically
prodpulse.monitorDatabase(mysqlConn, 'mysql');
prodpulse.monitorDatabase(pgPool, 'postgresql');
prodpulse.monitorDatabase(mongoose, 'mongodb');What gets tracked:
- Slow query detection with configurable threshold
- Connection errors and pool exhaustion events
- Failed transactions and rollbacks
- Query fingerprints (parameterized β raw values are never captured)
- Database type and connection metadata
Use prodpulse.capture() anywhere you catch errors yourself, or to record custom events with structured metadata.
const prodpulse = require('prodpulse-node-sdk');
// ββ Basic capture ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
prodpulse.capture(new Error('Payment gateway timed out'));
// ββ With structured context ββββββββββββββββββββββββββββββββββββββββββββββββββ
try {
await processCheckout(cart);
} catch (err) {
prodpulse.capture(err, {
userId: 'usr_8a3f9c',
orderId: 'ord_992kl1',
cart: { items: 3, totalCents: 429900 },
region: 'ap-south-1',
});
res.status(500).json({ error: 'Checkout failed' });
}
// ββ Custom string events (non-Error) ββββββββββββββββββββββββββββββββββββββββ
prodpulse.capture('webhook.signature_mismatch', {
webhookId: 'wh_live_xxx',
severity: 'warning',
source: 'payment-provider',
});prodpulse.init(process.env.PRODPULSE_API_KEY, {
beforeSend: (event) => {
// Return null to silently drop the event
if (event.user?.role === 'bot') return null;
// Attach any runtime metadata
event.tags = {
...event.tags,
deploymentId: process.env.DEPLOYMENT_ID,
};
return event; // Always return the event to send it
},
});ProdPulse v2.0.0 applies automatic, recursive sanitization to every outbound event. Sensitive values are replaced with [REDACTED] before any data leaves your process β not at the server, in the SDK itself.
| Category | Detected By | Example Input | Sent as |
|---|---|---|---|
| π Passwords | Field names: password, passwd, pwd, secret, pass |
"hunter2" |
[REDACTED] |
| πͺ JWT Tokens | eyJ prefix pattern |
"eyJhbGciOiJIUzI1..." |
[REDACTED] |
| βοΈ AWS Access Keys | AKIA prefix pattern (20-char) |
"AKIAIOSFODNN7EXAMPLE" |
[REDACTED] |
| βοΈ AWS Secret Keys | Field names: aws_secret, secretAccessKey |
"wJalrXUtnFEMI..." |
[REDACTED] |
| ποΈ Database URLs | URI schemes: mongodb://, postgres://, mysql://, redis:// |
"postgres://user:pass@host/db" |
[REDACTED] |
| π³ Credit Cards | Luhn-valid 13β19 digit sequences | "4111111111111111" |
[REDACTED] |
| π Private Keys | PEM block headers | "-----BEGIN RSA PRIVATE KEY-----" |
[REDACTED] |
| πͺ Cookies | Header names: cookie, set-cookie |
"session=abc123; Path=/" |
[REDACTED] |
| π Auth Headers | authorization, x-api-key, x-auth-token, x-access-token |
"Bearer sk_live_xxx" |
[REDACTED] |
| πͺͺ PII Fields | ssn, aadhar, pan, nric, cvv, otp, pin |
"123-45-6789" |
[REDACTED] |
| π Query Params | ?token=, ?key=, ?secret=, ?password= in URLs |
/reset?token=abc123 |
/reset?token=[REDACTED] |
Sanitization is applied recursively across all of the following:
- Custom context objects passed to
prodpulse.capture(err, context) - HTTP request headers captured by
requestMiddleware() - Error messages that contain secret-shaped strings
- URL query parameters
- Any nested objects, regardless of depth
prodpulse.init('pp_test_xxx', {
sanitize: false, // β οΈ Development/testing only
});Note:
sanitizeis permanently locked totruewhenenvironmentis set to'production'. This cannot be overridden.
The SDK never blocks your application and never loses an error event, even when your network is unavailable.
ββββββββββββββββ βββββββββββββββββββββββ βββββββββββββββββββ
β your app ββββββΆβ prodpulse-node-sdk ββββββΆβ prodpulse api β
ββββββββββββββββ βββββββββββββββββββββββ βββββββββββββββββββ
β β²
on failure β
βΌ on reconnect
ββββββββββββββββ β
β offline queueβββββββββββββββββββββΆβ
β (in-memory) β flush with backoff
ββββββββββββββββ
Queue behaviour:
- Every captured error is dispatched immediately and asynchronously
- On API failure, the event is pushed to an in-memory queue
- The SDK probes for connectivity on a 30-second interval
- On reconnect, queued events are delivered oldest-first
- When the queue reaches
maxQueueSize, the oldest event is evicted to make room
| Retry Attempt | Delay Before Attempt |
|---|---|
| 1st | 1 s |
| 2nd | 2 s |
| 3rd | 4 s |
| 4th | 8 s |
| 5th | 16 s |
| 6th+ | 16 s (capped) |
Enable verbose SDK output to verify what is being captured, what is being redacted, and whether events are being delivered.
Via environment variable (recommended):
PRODPULSE_DEBUG=true node app.jsVia configuration:
prodpulse.init(process.env.PRODPULSE_API_KEY, {
debug: process.env.NODE_ENV !== 'production',
});Sample debug output:
[ProdPulse] β Initialized β app: "Payments Service" | env: production | sdk: v2.0.0
[ProdPulse] β Git context β commit: a3f9c12 | branch: feat/checkout | author: dev@example.com
[ProdPulse] βΆ Capturing β Error: "Payment gateway timed out"
[ProdPulse] Source: src/services/payment.js:142 in processCharge()
[ProdPulse] β Sanitization β 3 field(s) redacted
[ProdPulse] β Deduplication β new fingerprint, sending
[ProdPulse] β Delivered β eventId: evt_k9z2m1 | latency: 38ms
Call prodpulse.getContext() at any time to inspect the full diagnostic payload that ProdPulse attaches to every event.
const ctx = prodpulse.getContext();
console.log(JSON.stringify(ctx, null, 2));{
"app": {
"name": "Payments Service",
"version": "3.4.1",
"environment": "production",
"framework": "express@4.18.2",
"nodeVersion": "v20.11.0",
"pid": 28341
},
"git": {
"commit": "a3f9c12e",
"branch": "feat/checkout-v2",
"author": "dev@example.com",
"message": "Add retry logic to payment processor"
},
"system": {
"platform": "linux",
"arch": "x64",
"hostname": "prod-api-07",
"cpuUsage": "18%",
"memoryTotal": "8 GB",
"memoryFree": "2.9 GB",
"uptimeHours": 312.7
},
"sdk": {
"name": "prodpulse-node-sdk",
"version": "2.0.0"
}
}Initializes the SDK. Call once, as early as possible in your application entry file.
| Parameter | Type | Required |
|---|---|---|
apiKey |
string |
β |
options |
InitOptions |
β |
Manually captures and dispatches an error event.
| Parameter | Type | Required | Description |
|---|---|---|---|
error |
Error | string |
β | The error or message to capture |
context |
object |
β | Arbitrary metadata to attach to the event |
Returns: Promise<string> β the assigned event ID, or null if dropped by deduplication or beforeSend.
Returns an Express/Fastify middleware function that attaches full HTTP request context to all captured errors within the request lifecycle.
Returns a 4-argument Express error handler (err, req, res, next) that captures, enriches, and forwards all errors that pass through the Express error pipeline.
Instruments a database connection for query-level monitoring.
| Parameter | Type | Required | Accepted Values |
|---|---|---|---|
connection |
object |
β | Your connection, pool, or ODM instance |
type |
string |
β | 'mysql' Β· 'postgresql' Β· 'mongodb' Β· 'redis' |
Returns a plain object snapshot of the current SDK context β app, git, system, and SDK metadata.
Returns: ContextSnapshot
| Channel | Where to go |
|---|---|
| π Documentation | coming soon |
| π¬ Community Discord | coming soon |
| π Bug Reports | coming soon |
| π Feature Requests | coming soon |
| π§ Enterprise & Priority Support | coming soon |
| π¦ Updates | coming soon |
Found ProdPulse useful? Give us a β on GitHub β it helps more than you'd think.
prodpulse.ai Β Β·Β Dashboard Β Β·Β Docs Β Β·Β Changelog Β Β·Β Status
MIT License  © 2026 ProdPulse Technologies