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:
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.
npm install -g caloohpay
No installation required, run directly with npx:
npx caloohpay -r "SCHEDULE_ID"
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:
# .env
API_TOKEN=your_pagerduty_api_token_here
# Get help
caloohpay --help
# Calculate payments for a single schedule (previous month)
caloohpay -r "PQRSTUV"
# Calculate for multiple schedules with custom date range
caloohpay -r "PQRSTUV,PSTUVQR" -s "2024-01-01" -u "2024-01-31"
CalOohPay can be used as a library in both Node.js and browser environments.
Node.js (with file system access and PagerDuty API):
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.):
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 →
CalOohPay now works in web browsers! The core calculation engine is completely independent of Node.js.
// 🌐 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';
'use client'; // Next.js 13+ App Router
import { 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 (
<div>
<input value={weekdayRate} onChange={(e) => setWeekdayRate(Number(e.target.value))} />
<input value={weekendRate} onChange={(e) => setWeekendRate(Number(e.target.value))} />
{/* Your UI here */}
</div>
);
}
What works in browsers:
OnCallPaymentsCalculator)OnCallUser, OnCallPeriod)Node.js only:
fs module)fs module)| Period | Rate |
|---|---|
| Weekdays (Mon-Thu) | £50 per day |
| Weekends (Fri-Sun) | £75 per day |
You can customize compensation rates by creating a .caloohpay.json file:
{
"rates": {
"weekdayRate": 60,
"weekendRate": 90,
"currency": "USD"
}
}
The tool searches for this file in:
~/.caloohpay.json (user-wide defaults)Example config file: .caloohpay.json.example
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.
"Command not found: caloohpay"
npm link after buildingdist/src/CalOohPay.js exists"Invalid API Token"
.env file contains the correct token"No schedule entries found"
Schedule IDs can be found in PagerDuty:
https://yourcompany.pagerduty.com/schedules/PQRSTUVTo fetch schedule data from PagerDuty, you need an API User Token that provides the same permissions as your user account.
⚠️ Security Warning: Never commit your API token to version control!
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:
# 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"
.caloohpay.json# Automatic timezone detection (recommended)
caloohpay -r "SCHEDULE_ID"
# Override timezone if needed
caloohpay -r "SCHEDULE_ID" -t "America/New_York"
Recently Completed:
Coming Soon:
This project is licensed under the ISC License - see the LICENSE file for details.
If you encounter any issues or have questions:
If CalOohPay has saved you time and made your life easier, consider supporting its development!
Your support helps me:
Every coffee counts and is greatly appreciated! ☕
Made with ❤️ for engineering teams who deserve fair compensation for their on-call dedication.