A CLI tool and library to calculate out-of-hours on-call compensation. Works in Node.js and browsers (Next.js, React, etc.)
npm install caloohpay





A command-line tool that automates the calculation of out-of-hours (OOH) on-call compensation for engineering teams using PagerDuty schedules.
CalOohPay eliminates the manual work of calculating on-call payments by:
- Fetching schedule data directly from PagerDuty API
- Calculating compensation based on weekday vs weekend rates
- Supporting multiple teams and schedules simultaneously
- Providing auditable records for payroll processing
- Handling timezone conversions automatically
In many organizations, engineers get compensated for going on-call outside of working hours. Managers typically spend 5-10 minutes per team each month reconciling on-call rotas for payroll. With multiple teams and distributed locations, this manual process quickly becomes time-consuming and error-prone.
CalOohPay automates this entire process, turning hours of manual work into a single command.
- Node.js (v14 or higher)
- npm or yarn
- PagerDuty API User Token (How to get one)
``bash`
npm install -g caloohpay
No installation required, run directly with npx:
`bash`
npx caloohpay -r "SCHEDULE_ID"
`bash`
git clone https://github.com/lonelydev/caloohpay.git
cd caloohpay
npm install
npm run build
npm link
Create a .env file in the project root:
`bash`.env
API_TOKEN=your_pagerduty_api_token_here
#### CLI Usage
`bashGet help
caloohpay --help
#### Programmatic Usage
CalOohPay can be used as a library in both Node.js and browser environments.
Node.js (with file system access and PagerDuty API):
`typescript
import { ConfigLoader, OnCallPaymentsCalculator } from 'caloohpay';const loader = new ConfigLoader();
const rates = loader.loadRates();
const calculator = new OnCallPaymentsCalculator(rates.weekdayRate, rates.weekendRate);
`Browser/Web Applications (Next.js, React, Vue, etc.):
`typescript
import { OnCallUser, OnCallPeriod, OnCallPaymentsCalculator } from 'caloohpay/core';// Create on-call periods from your data
const user = new OnCallUser('user-id', 'John Doe', [
new OnCallPeriod(
new Date('2024-08-01T18:00:00Z'),
new Date('2024-08-05T09:00:00Z'),
'Europe/London'
)
]);
// Calculate with custom rates
const calculator = new OnCallPaymentsCalculator(60, 90);
const amount = calculator.calculateOnCallPayment(user);
console.log(
Compensation: $${amount});
`š View Full API Documentation ā
š Browser Compatibility (New in v2.1.0)
CalOohPay now works in web browsers! The core calculation engine is completely independent of Node.js.
$3
`typescript
// š Browser-compatible core (zero Node.js dependencies)
import { OnCallPaymentsCalculator, OnCallUser, OnCallPeriod, DEFAULT_RATES } from 'caloohpay/core';// š„ļø Node.js-specific features (ConfigLoader, CsvWriter, PagerDuty API)
import { ConfigLoader, CsvWriter, calOohPay } from 'caloohpay/node';
// š¦ Everything (backward compatible, Node.js only)
import { ConfigLoader, OnCallPaymentsCalculator } from 'caloohpay';
`$3
`typescript
'use client'; // Next.js 13+ App Routerimport { useState } from 'react';
import { OnCallPaymentsCalculator, DEFAULT_RATES } from 'caloohpay/core';
export default function CompensationCalculator() {
const [weekdayRate, setWeekdayRate] = useState(DEFAULT_RATES.weekdayRate);
const [weekendRate, setWeekendRate] = useState(DEFAULT_RATES.weekendRate);
const calculator = new OnCallPaymentsCalculator(weekdayRate, weekendRate);
// Use calculator.calculateOnCallPayment(user) with your data
return (
setWeekdayRate(Number(e.target.value))} />
setWeekendRate(Number(e.target.value))} />
{/ Your UI here /}
);
}
`What works in browsers:
- ā
Core calculation engine (
OnCallPaymentsCalculator)
- ā
Models (OnCallUser, OnCallPeriod)
- ā
All constants and types
- ā
Date utilities and validationNode.js only:
- ā ConfigLoader (uses
fs module)
- ā CsvWriter (uses fs module)
- ā calOohPay function (uses PagerDuty API)
- ā CLI toolsš° Compensation Rates
$3
| Period | Rate |
|--------|------|
| Weekdays (Mon-Thu) | £50 per day |
| Weekends (Fri-Sun) | £75 per day |
$3
You can customize compensation rates by creating a
.caloohpay.json file:`json
{
"rates": {
"weekdayRate": 60,
"weekendRate": 90,
"currency": "USD"
}
}
`The tool searches for this file in:
1. Current working directory (project-specific rates)
2. Home directory
~/.caloohpay.json (user-wide defaults)
3. Built-in defaults if no config foundExample config file: .caloohpay.json.example
Development and contributing
Development, testing, contributor workflow and git-hook guidance has moved to CONTRIBUTING.md. Please read that document for detailed setup and contribution instructions, including how to run tests, lint, generate docs, and prepare a pull request.
Note on ESLint configuration: this project uses ESLint v9 with a flat config file located at
eslint.config.cjs (instead of legacy .eslintrc.json). If you need to adjust lint rules or add new shareable configs, update eslint.config.cjs and run npm run lint to validate your changes.š§ Troubleshooting
$3
"Command not found: caloohpay"
- Run
npm link after building
- Restart your terminal
- Check if dist/src/CalOohPay.js exists"Invalid API Token"
- Verify your
.env file contains the correct token
- Ensure no extra spaces or quotes around the token
- Check token permissions in PagerDuty"No schedule entries found"
- Verify the schedule ID is correct
- Check the date range includes on-call periods
- Ensure you have permissions to view the schedule
š Finding Schedule IDs
Schedule IDs can be found in PagerDuty:
1. Navigate to People ā On-Call Schedules
2. Click on your schedule
3. The ID is in the URL:
https://yourcompany.pagerduty.com/schedules/PQRSTUVš PagerDuty API Setup
To fetch schedule data from PagerDuty, you need an API User Token that provides the same permissions as your user account.
$3
1. Login to PagerDuty
2. Navigate to Profile: Hover over your profile icon ā My Profile
3. Access Settings: Go to User Settings
4. Create Token: Click Create API User Token
5. Secure Storage: Store the token securely (e.g., 1Password, environment variable)
ā ļø Security Warning: Never commit your API token to version control!
š CLI Reference
$3
`bash
caloohpay -r "SCHEDULE_ID" [options]
`Common Options:
-
-r, --rota-ids - Schedule ID(s) (required)
- -s, --since - Start date (YYYY-MM-DD)
- -u, --until - End date (YYYY-MM-DD)
- -o, --output-file - Save to CSV file
- -t, --timeZoneId - Override timezone
- -k, --key - API token overrideExamples:
`bash
Basic usage
caloohpay -r "PQRSTUV"Multiple schedules to CSV
caloohpay -r "TEAM_A,TEAM_B" -o "./monthly-report.csv"Custom date range
caloohpay -r "PQRSTUV" -s "2024-01-01" -u "2024-01-31"
`ā
Current Features
- ā
PagerDuty Integration: Fetches schedules with automatic timezone detection
- ā
Multi-Schedule Support: Process multiple schedules simultaneously
- ā
Configurable Rates: Custom weekday/weekend rates via
.caloohpay.json
- ā
Timezone Support: Accurate OOH calculations for distributed teams
- ā
CSV Export: Google Sheets compatible payroll files
- ā
Comprehensive Testing: 328+ unit tests with full coverage$3
`bash
Automatic timezone detection (recommended)
caloohpay -r "SCHEDULE_ID"Override timezone if needed
caloohpay -r "SCHEDULE_ID" -t "America/New_York"
``Recently Completed:
- ā
Configurable rates via config file
- ā
Full timezone support with automatic detection
- ā
CSV export for payroll systems
Coming Soon:
- Enhanced console output with colors
- NPM package distribution
- Automated monthly reporting
- API Documentation - Auto-generated API docs (GitHub Pages)
- PagerDuty API Documentation
- PagerDuty Time Zones
- Luxon.js Documentation
- Jest Testing Framework
- TypeScript with Node.js
- Yargs Command Line Parser
This project is licensed under the ISC License - see the LICENSE file for details.
If you encounter any issues or have questions:
1. Check the troubleshooting section
2. Search existing issues
3. Create a new issue with detailed information
If CalOohPay has saved you time and made your life easier, consider supporting its development!

Your support helps me:
- š Continue developing new features
- š Fix bugs and improve stability
- š Maintain documentation
- š” Explore new ideas and integrations
Every coffee counts and is greatly appreciated! ā
---
Made with ā¤ļø for engineering teams who deserve fair compensation for their on-call dedication.