npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ericdahl.dev/openai-and-claude-usage-report-generator

v1.2.17

Published

OpenAI and Claude API Usage Report Generator - CLI tool and library for generating billing reports

Readme

OpenAI and Claude Usage Report Generator

A CLI tool and library for generating billing reports from the OpenAI or Claude (Anthropic) cost APIs. Outputs Markdown (readable) and CSV (data) reports.

Can be used as:

  • CLI tool: Run reports from the command line
  • Library: Import functions programmatically in your Node.js/TypeScript projects

Features

  • Fetches usage/cost data from OpenAI's organization costs API or Anthropic's Usage and Cost API
  • Generates detailed Markdown reports with summaries and breakdowns
  • Exports CSV data for further analysis
  • Exports JSON data for programmatic consumption
  • Daily and line-item cost breakdowns

Prerequisites

Installation

As a CLI Tool (Development)

git clone <repository-url>
cd openai-and-claude-usage-report-generator
yarn install

As an npm Package (Library)

yarn add @ericdahl.dev/openai-and-claude-usage-report-generator
# or
npm install @ericdahl.dev/openai-and-claude-usage-report-generator

Configuration

Create a .env file in the root directory (see .env.example for a template).

⚠️ Important: Both platforms require admin/administrative API keys. Standard API keys will not work.

OpenAI (default):

OPENAI_ADMIN_KEY=sk-...          # Must be an admin key, not a standard API key
OPENAI_ORG_ID=org-...
OPENAI_PROJECT_ID=proj_...

Claude:

ANTHROPIC_ADMIN_API_KEY=sk-ant-admin-...  # Must be an admin key (starts with sk-ant-admin), not a standard API key

Usage

CLI Usage

Generate a report for a date range. Default provider is OpenAI.

yarn report 2024-01-01 2024-01-31
yarn report 2024-01-01 2024-01-31 --provider openai
yarn report 2024-01-01 2024-01-31 --provider claude

Library Usage

Import and use the functions programmatically in your code:

import {
  fetchOpenAICosts,
  fetchClaudeCosts,
  aggregateCosts,
  generateMarkdownReport,
  generateCSVReport,
  generateJSONReport,
  writeReports,
  parseDate,
  validateDateRange,
  loadConfig,
} from '@ericdahl.dev/openai-and-claude-usage-report-generator';
import type { OpenAIReportConfig, ClaudeReportConfig } from '@ericdahl.dev/openai-and-claude-usage-report-generator';

// Example: Fetch and process OpenAI costs
// Note: OPENAI_ADMIN_KEY must be an admin key, not a standard API key
async function generateOpenAIReport() {
  const config: OpenAIReportConfig = {
    provider: 'openai',
    startDate: '2024-01-01',
    endDate: '2024-01-31',
    apiKey: process.env.OPENAI_ADMIN_KEY!,  // Must be an admin key
    orgId: process.env.OPENAI_ORG_ID!,
    projectId: process.env.OPENAI_PROJECT_ID!,
  };

  // Fetch cost data
  const buckets = await fetchOpenAICosts(config);

  // Aggregate the data
  const aggregated = aggregateCosts(
    buckets,
    config.startDate,
    config.endDate,
    config.projectId
  );

  // Generate reports
  const markdown = generateMarkdownReport(aggregated, config.orgId, 'openai');
  const csv = generateCSVReport(aggregated);
  const json = generateJSONReport(aggregated, config.orgId, 'openai');

  // Or write directly to files
  const { mdPath, csvPath, jsonPath } = writeReports(aggregated, config.orgId, 'openai');

  console.log(`Reports written to ${mdPath}, ${csvPath}, and ${jsonPath}`);
}

// Example: Fetch and process Claude costs
// Note: ANTHROPIC_ADMIN_API_KEY must be an admin key (sk-ant-admin...), not a standard API key
async function generateClaudeReport() {
  const config: ClaudeReportConfig = {
    provider: 'claude',
    startDate: '2024-01-01',
    endDate: '2024-01-31',
    apiKey: process.env.ANTHROPIC_ADMIN_API_KEY!,  // Must be an admin key (starts with sk-ant-admin)
  };

  const buckets = await fetchClaudeCosts(config);
  const aggregated = aggregateCosts(buckets, config.startDate, config.endDate, 'default');
  const markdown = generateMarkdownReport(aggregated, 'default', 'claude');

  console.log(markdown);
}

Note: When using as a library, you need to handle environment variables yourself. The loadConfig function is available but requires environment variables to be set, or you can construct the config objects directly as shown above.

⚠️ Important Reminder: Both platforms require admin/administrative API keys. Standard API keys will not work for accessing cost/usage data.

Output

  • OpenAI: reports/openai/
  • Claude: reports/claude/

Each run produces:

  • usage-YYYY-MM-DD-to-YYYY-MM-DD.md – Human-readable Markdown report
  • usage-YYYY-MM-DD-to-YYYY-MM-DD.csv – CSV data export
  • usage-YYYY-MM-DD-to-YYYY-MM-DD.json – JSON data export for programmatic consumption

Report Contents

The Markdown report includes:

  • Summary: Total cost, billing days, average daily cost
  • Cost by Model/Service: Breakdown by line item with percentages
  • Daily Usage Breakdown: Detailed daily costs by model/service
  • Total by Day: Daily totals for quick overview

The CSV export contains:

  • Date, line item, cost (USD), and project ID for each entry

The JSON export contains:

  • Metadata (provider, billing period, project/organization IDs, generation timestamp)
  • Summary (total cost, billing days, average daily cost)
  • Costs by line item (sorted by cost, includes percentages)
  • Daily breakdown (all daily costs by date and line item)
  • Daily totals (aggregated totals per day)

API Reference

Core Functions

fetchOpenAICosts(config: OpenAIReportConfig): Promise<CostBucket[]>

Fetches cost data from OpenAI's organization costs API. Returns an array of cost buckets.

fetchClaudeCosts(config: ClaudeReportConfig): Promise<CostBucket[]>

Fetches cost data from Anthropic's cost report API. Returns an array of cost buckets (normalized to match OpenAI format).

aggregateCosts(buckets: CostBucket[], startDate: string, endDate: string, projectId: string): AggregatedCosts

Aggregates cost buckets into a structured format with totals, daily breakdowns, and line item summaries.

generateMarkdownReport(aggregated: AggregatedCosts, orgId: string, provider: 'openai' | 'claude'): string

Generates a human-readable Markdown report from aggregated costs.

generateCSVReport(aggregated: AggregatedCosts): string

Generates a CSV report from aggregated costs.

generateJSONReport(aggregated: AggregatedCosts, orgId: string, provider: 'openai' | 'claude'): string

Generates a JSON report from aggregated costs. Returns a formatted JSON string with metadata, summary, costs by line item, daily breakdown, and daily totals.

writeReports(aggregated: AggregatedCosts, orgId: string, provider: Provider, baseDir?: string): { mdPath: string; csvPath: string; jsonPath: string }

Writes Markdown, CSV, and JSON reports to disk. Returns paths to the generated files.

Utility Functions

parseDate(dateStr: string): Date

Parses a date string in YYYY-MM-DD format and returns a Date object.

validateDateRange(start: Date, end: Date): void

Validates that the end date is after the start date. Throws an error if invalid.

loadConfig(startDate: string, endDate: string, provider: Provider): ReportConfig

Loads configuration from environment variables. Requires appropriate env vars to be set based on provider.

Types

All TypeScript types are exported. Key types include:

  • OpenAIReportConfig - Configuration for OpenAI API
  • ClaudeReportConfig - Configuration for Claude API
  • AggregatedCosts - Aggregated cost data structure
  • CostBucket - Individual cost bucket from API
  • DailyCost - Daily cost entry
  • Provider - Union type: 'openai' | 'claude'

Development

Running Tests

yarn test        # watch mode
yarn test:run    # single run (used by CI)

Building

yarn build

CI

GitHub Actions runs on push and pull requests to main: yarn install --frozen-lockfile, yarn test:run, then yarn build. See .github/workflows/ci.yml.