NodeJS middleware for Perplexity AI API with Revenium metering
npm install @revenium/perplexityA lightweight, production-ready middleware that adds Revenium metering and tracking to Perplexity AI API calls.





- Automatic Metering - Tracks all API calls with detailed usage metrics
- Streaming Support - Full support for streaming responses
- TypeScript First - Built with TypeScript, includes full type definitions
- Multi-Format - Supports both ESM and CommonJS
- Custom Metadata - Add custom tracking metadata to any request
- Production Ready - Battle-tested and optimized for production use
``bash`
npm install @revenium/perplexity
Note: The dotenv package is optional. The middleware automatically loads .env files via Initialize().
For complete setup instructions, TypeScript patterns, and usage examples, see examples/README.md.
The following guide walks you through creating a new project from scratch:
#### Step 1: Create Your Project
`bashCreate project directory
mkdir my-perplexity-project
cd my-perplexity-project
#### Step 2: Install Dependencies
`bash
Install Revenium middleware
npm install @revenium/perplexityFor TypeScript projects (optional)
npm install -D typescript tsx @types/node
`#### Step 3: Setup Environment Variables
Create a
.env file in your project root:`bash
Create .env file
echo. > .env # On Windows (CMD)
touch .env # On Mac/Linux
OR
PowerShell
New-Item -Path .env -ItemType File
`Copy and paste the following into
.env:`env
Perplexity Configuration
PERPLEXITY_API_KEY=pplx_your_perplexity_api_keyRevenium Configuration
REVENIUM_METERING_API_KEY=hak_your_revenium_api_keyOptional: For development/testing (defaults to https://api.revenium.ai)
REVENIUM_METERING_BASE_URL=https://api.revenium.ai
Optional: Perplexity API base URL (defaults to https://api.perplexity.ai)
PERPLEXITY_API_BASE_URL=https://api.perplexity.ai
Optional: Enable debug logging
REVENIUM_DEBUG=false
Optional: Terminal cost/metrics summary
REVENIUM_PRINT_SUMMARY=true # or 'human' or 'json'
REVENIUM_TEAM_ID=your_team_id # Required for cost retrieval
`Replace the placeholder values with your actual keys!
For a complete list of all available environment variables, see the Configuration Options section below.
#### Step 4: Implement in Your Code
Use the examples as reference for implementing the middleware in your project. See examples/README.md for complete implementation examples including:
- How to initialize the middleware with your configuration
- Making API calls with automatic metering
- Handling streaming responses
- Adding custom metadata to track business context
Note for ESM projects: If you get a "Cannot use import statement outside a module" error, make sure your
package.json includes "type": "module":`json
{
"name": "my-perplexity-project",
"version": "1.0.0",
"type": "module",
"dependencies": {
"@revenium/perplexity": "^2.0.0"
}
}
`---
Running Examples from Cloned Repository
If you've cloned this repository from GitHub and want to run the included examples to see how the middleware works (without modifying the middleware source code):
$3
`bash
Install dependencies
npm installBuild the package
npm run buildConfigure environment variables
cp .env.example .env # On Mac/Linux
copy .env.example .env # On Windows (CMD)
OR PowerShell
Copy-Item .env.example .envEdit .env with your API keys
`$3
Using npm scripts:
`bash
npm run example:getting-started # Getting started example
npm run example:basic # Basic chat completion
npm run example:stream # Streaming response
npm run example:metadata # Custom metadata
npm run example:advanced # Advanced features
`Or use npx tsx directly:
`bash
npx tsx examples/getting_started.ts
npx tsx examples/basic.ts
npx tsx examples/stream.ts
npx tsx examples/metadata.ts
npx tsx examples/advanced.ts
`For detailed information about each example, see examples/README.md.
---
Local Development and Contributing
For information on modifying the middleware source code, development workflow, and contributing to the project, see:
- DEVELOPMENT.md - Complete development guide, build system, and testing
- CONTRIBUTING.md - Contribution guidelines and process
---
What Gets Tracked
The middleware automatically captures comprehensive usage data:
$3
- Token Counts - Input tokens, output tokens, total tokens
- Model Information - Model name, provider (Perplexity)
- Request Timing - Request duration, response time
- Cost Calculation - Estimated costs based on current pricing
$3
- User Tracking - Subscriber ID, email, credentials
- Organization Data - Organization ID, subscription ID, product ID
- Task Classification - Task type, agent identifier, trace ID
- Quality Metrics - Response quality scores, task identifiers
$3
- API Endpoints - Chat completions
- Request Types - Streaming vs non-streaming
- Error Tracking - Failed requests, error types, retry attempts
- Environment Info - Development vs production usage
Metadata Fields
The following table shows all fields this middleware sends to the Revenium API:
| Field | Type | Required | Description |
| ----------------------- | ------- | --------- | -------------------------------------------------------- |
| Core Fields | | | |
|
model | string | Yes | Perplexity model name (e.g., "sonar-pro") |
| provider | string | Yes | Always "Perplexity" |
| inputTokenCount | integer | Yes | Number of input tokens consumed |
| outputTokenCount | integer | Yes | Number of output tokens generated |
| totalTokenCount | integer | Yes | Total tokens (input + output) |
| requestDuration | integer | Yes | Request duration in milliseconds |
| Timing | | | |
| requestTime | string | Auto | ISO 8601 timestamp when request started |
| responseTime | string | Auto | ISO 8601 timestamp when response completed |
| completionStartTime | string | Auto | ISO 8601 timestamp when completion started |
| timeToFirstToken | integer | Streaming | Time to first token in ms (streaming only) |
| Request Details | | | |
| transactionId | string | Auto | Unique transaction identifier |
| operationType | string | Auto | Always "CHAT" for chat completions |
| stopReason | string | Auto | Completion finish reason ("END", "STOP", etc.) |
| isStreamed | boolean | Auto | Whether response was streamed |
| costType | string | Auto | Always "AI" |
| modelSource | string | Auto | Always "PERPLEXITY" |
| middlewareSource | string | Auto | Always "revenium-perplexity-node" |
| Cost Information | | | |
| inputTokenCost | number | Optional | Cost for input tokens (if provided by Perplexity) |
| outputTokenCost | number | Optional | Cost for output tokens (if provided by Perplexity) |
| totalCost | number | Optional | Total cost (if provided by Perplexity) |
| Business Context | | | |
| organizationName | string | Optional | Customer organization name for multi-tenant applications |
| productName | string | Optional | Product or feature name that is using AI services |
| subscriptionId | string | Optional | Your subscription identifier |
| taskType | string | Optional | Type of AI task (e.g., "chat", "research") |
| traceId | string | Optional | Session or conversation tracking ID |
| agent | string | Optional | AI agent or bot identifier |
| responseQualityScore | number | Optional | Custom quality rating (0.0-1.0) |
| subscriber.id | string | Optional | User identifier |
| subscriber.email | string | Optional | User email address |
| subscriber.credential | object | Optional | Authentication credential (name, value) |Notes:
- Required fields are always sent with every request
- Auto fields are automatically populated by the middleware
- Optional fields are only sent if you provide them via
usageMetadata
- Streaming fields are only sent for streaming requestsReference:
- API Reference - Complete metadata field documentation
Trace Visualization Fields
The middleware automatically captures trace visualization fields for distributed tracing and analytics:
| Field | Type | Description | Environment Variable |
| --------------------- | ------ | ------------------------------------------------------------------------------- | ---------------------------------- |
|
environment | string | Deployment environment (production, staging, development) | REVENIUM_ENVIRONMENT, NODE_ENV |
| operationType | string | Operation classification (CHAT, EMBED, etc.) - automatically detected | N/A (auto-detected) |
| operationSubtype | string | Additional detail (function_call, etc.) - automatically detected | N/A (auto-detected) |
| retryNumber | number | Retry attempt number (0 for first attempt, 1+ for retries) | REVENIUM_RETRY_NUMBER |
| parentTransactionId | string | Parent transaction reference for distributed tracing | REVENIUM_PARENT_TRANSACTION_ID |
| transactionName | string | Human-friendly operation label | REVENIUM_TRANSACTION_NAME |
| region | string | Cloud region (us-east-1, etc.) - auto-detected from AWS/Azure/GCP | AWS_REGION, REVENIUM_REGION |
| credentialAlias | string | Human-readable credential name | REVENIUM_CREDENTIAL_ALIAS |
| traceType | string | Categorical identifier (alphanumeric, hyphens, underscores only, max 128 chars) | REVENIUM_TRACE_TYPE |
| traceName | string | Human-readable label for trace instances (max 256 chars) | REVENIUM_TRACE_NAME |All trace visualization fields are optional. The middleware will automatically detect and populate these fields when possible.
$3
`env
REVENIUM_ENVIRONMENT=production
REVENIUM_REGION=us-east-1
REVENIUM_CREDENTIAL_ALIAS=Perplexity Production Key
REVENIUM_TRACE_TYPE=customer_support
REVENIUM_TRACE_NAME=Support Ticket #12345
REVENIUM_PARENT_TRANSACTION_ID=parent-txn-123
REVENIUM_TRANSACTION_NAME=Answer Customer Question
REVENIUM_RETRY_NUMBER=0
`.env.example.Prompt Capture
The middleware can capture prompts and responses for analysis. This feature is disabled by default for privacy.
$3
Enable prompt capture using environment variables, programmatic configuration, or per-call metadata:
Environment Variables:
`bash
export REVENIUM_CAPTURE_PROMPTS=true
export REVENIUM_MAX_PROMPT_SIZE=50000
`Programmatic Configuration:
`typescript
import { Initialize } from "@revenium/perplexity";Initialize({
reveniumApiKey: "hak_your_key",
reveniumBaseUrl: "https://api.revenium.ai",
perplexityApiKey: "pplx_your_key",
capturePrompts: true,
maxPromptSize: 50000,
});
`Per-Call Override:
`typescript
const response = await client.chat.completions.create(
{
model: "llama-3.1-sonar-small-128k-online",
messages: [{ role: "user", content: "Hello" }],
},
{
usageMetadata: { capturePrompts: true },
},
);
`$3
The middleware uses the following priority order (highest to lowest):
1. Per-call
usageMetadata.capturePrompts
2. Programmatic config.capturePrompts
3. Environment variable REVENIUM_CAPTURE_PROMPTS
4. Default: false$3
All captured prompts are automatically sanitized to remove sensitive credentials:
- Perplexity API keys (pplx-\*)
- OpenAI keys (sk-\, sk-proj-\, sk-ant-\*)
- AWS access keys (AKIA\*)
- GitHub tokens (ghp\, ghs\)
- JWT tokens
- Bearer tokens
- Generic API keys, tokens, passwords, secrets
Prompts exceeding
maxPromptSize (default: 50000 characters) are automatically truncated with a flag indicating truncation.Terminal Cost/Metrics Summary
The middleware can print a cost and metrics summary to your terminal after each API request. This is useful for development and debugging.
$3
Enable terminal summary output using environment variables or programmatic configuration:
Environment Variables:
`bash
Enable human-readable summary (default format)
export REVENIUM_PRINT_SUMMARY=trueOr specify format explicitly
export REVENIUM_PRINT_SUMMARY=human # Human-readable format
export REVENIUM_PRINT_SUMMARY=json # JSON format for log parsingOptional: Set team ID to fetch cost data
export REVENIUM_TEAM_ID=your_team_id
`Programmatic Configuration:
`typescript
import { Initialize } from "@revenium/perplexity";Initialize({
reveniumApiKey: "hak_your_api_key",
reveniumBaseUrl: "https://api.revenium.ai",
perplexityApiKey: "pplx_your_api_key",
printSummary: true, // or 'human' or 'json'
teamId: "your_team_id", // Optional: for cost retrieval
});
`$3
Human-readable format (
printSummary: true or printSummary: 'human'):`
============================================================
š REVENIUM USAGE SUMMARY
============================================================
š¤ Model: sonar-pro
š¢ Provider: Perplexity
ā±ļø Duration: 1.23sš¬ Token Usage:
š„ Input Tokens: 150
š¤ Output Tokens: 75
š Total Tokens: 225
š° Cost: $0.004500
š Trace ID: trace-abc-123
============================================================
`JSON format (
printSummary: 'json'):`json
{
"model": "sonar-pro",
"provider": "Perplexity",
"durationSeconds": 1.23,
"inputTokenCount": 150,
"outputTokenCount": 75,
"totalTokenCount": 225,
"cost": 0.0045,
"traceId": "trace-abc-123"
}
`$3
- Without
teamId: Shows token counts and duration, displays hint to set REVENIUM_TEAM_ID
- With teamId: Fetches actual cost from Revenium API with automatic retry logic
- Cost pending: Shows "(pending aggregation)" if cost data isn't available yet
- Fire-and-forget: Never blocks your application, even if cost fetch failsAPI Overview
-
Initialize(config?) - Initialize the middleware (from environment or explicit config)
- GetClient() - Get the global Revenium client instance
- Configure(config) - Alias for Initialize() for programmatic configuration
- IsInitialized() - Check if the middleware is initialized
- Reset() - Reset the global client (useful for testing)examples/README.md.Configuration Options
$3
For a complete list of all available environment variables with examples, see
.env.example.Examples
examples/ directory.Project Structure
`
revenium-middleware-perplexity-node/
āāā src/
ā āāā core/
ā ā āāā client/ # Client manager (Initialize/GetClient)
ā ā āāā config/ # Configuration management
ā ā āāā middleware/ # Perplexity API middleware wrapper
ā ā āāā providers/ # Provider detection
ā ā āāā tracking/ # Metering and tracking
ā āāā types/ # TypeScript type definitions
ā āāā utils/ # Utility functions
ā āāā index.ts # Main entry point
āāā examples/ # TypeScript examples
āāā package.json
āāā tsconfig.json
āāā README.md
`How It Works
1. Initialize: Call
Initialize() to set up the middleware with your configuration
2. Get Client: Call GetClient() to get a wrapped Perplexity client instance
3. Make Requests: Use the client normally - all requests are automatically tracked
4. Async Tracking: Usage data is sent to Revenium in the background (fire-and-forget)
5. Transparent Response: Original Perplexity responses are returned unchangedThe middleware never blocks your application - if Revenium tracking fails, your Perplexity requests continue normally.
Supported APIs:
- Chat Completions API (
client.chat().completions().create())
- Streaming API (client.chat().completions().createStreaming())Troubleshooting
$3
No tracking data appears:
1. Verify environment variables are set correctly in
.env
2. Enable debug logging by setting REVENIUM_DEBUG=true in .env
3. Check console for [Revenium] log messages
4. Verify your REVENIUM_METERING_API_KEY is validClient not initialized error:
- Make sure you call
Initialize() before GetClient()
- Check that your .env file is in the project root
- Verify REVENIUM_METERING_API_KEY is setPerplexity API errors:
- Verify
PERPLEXITY_API_KEY is set correctly
- Check that your API key starts with pplx-
- Ensure you're using a valid model nameWindows-specific issues:
If you're developing on Windows and encounter build errors with
npm run clean:- The
clean script uses rm -rf which may not work in Windows CMD
- Use PowerShell or Git Bash instead
- Or manually delete the dist folder before building
- Alternatively, install rimraf globally: npm install -g rimraf and update the script to use rimraf dist$3
Enable detailed logging by adding to your
.env:`env
REVENIUM_DEBUG=true
`$3
If issues persist:
1. Enable debug logging (
REVENIUM_DEBUG=true)
2. Check the examples/ directory for working examples
3. Review examples/README.md for detailed setup instructions
4. Contact support@revenium.io with debug logsSupported Models
This middleware works with any Perplexity model. For the complete model list, see the Perplexity Models Documentation.
$3
The following table shows what has been tested and verified with working examples:
| Feature | Chat Completions | Streaming |
| --------------------- | ---------------- | --------- |
| Basic Usage | Yes | Yes |
| Metadata Tracking | Yes | Yes |
| Token Counting | Yes | Yes |
examples/` directory- Node.js 20+
- TypeScript 5.0+ (for TypeScript projects)
- Revenium API key
- Perplexity API key
For detailed documentation, visit docs.revenium.io
See CONTRIBUTING.md
See SECURITY.md
This project is licensed under the MIT License - see the LICENSE file for details.
For issues, feature requests, or contributions:
- GitHub Repository: revenium/revenium-middleware-perplexity-node
- Issues: Report bugs or request features
- Documentation: docs.revenium.io
- Contact: Reach out to the Revenium team for additional support
---
Built by Revenium