openrouter-key-manager
v0.17.0
Published
A Node.js Library and CLI tool for managing OpenRouter.ai API keys
Readme
OpenRouter Key Manager
A Node.js library and CLI tool for creating and managing OpenRouter.ai API keys with flexible tagging and bulk operations, built on the official OpenRouter TypeScript SDK.
Features
- Bulk Operations: Create, delete, rotate, and adjust limits for multiple keys at once
- Flexible Tagging: Organize API keys with custom tags for easy filtering
- Usage Tracking: Analyze requests, spend, tokens, models, and caching
- Pattern Matching: Use glob patterns to manage groups of keys
- Key Rotation: Securely rotate keys while preserving names and limits
- CSV-Based: Simple CSV input/output for easy integration
- Programmatic API: Use as a library in your applications
[!NOTE] The blackboard2openrouter tool uses
openrouter-key-managerin order to simplify generating API keys for students using Blackboard grade book exports.
Installation
npm install openrouter-key-managerOr run directly with npx:
npx openrouter-key-manager@latest [command] [options]Prerequisites
You need an OpenRouter.ai Provisioning API Key. Get one from your OpenRouter.ai account dashboard.
Provide your OpenRouter.ai Provisioning API Key in one of two ways:
Environment Variable (recommended):
export OPENROUTER_PROVISIONING_KEY=your_provisioning_key_hereCommand Line Argument (CLI only):
openrouter-key-manager --provisioning-key your_key_here [command]Workspaces
API Keys are created in a workspace. Each OpenRouter account has a default workspace if none is explicitly selected. You can override which workspace you use with the global --workspace flag. For example, list all keys in the custom-workspace workspace:
npx openrouter-key-manager --workspace custom-workspace listThe value you pass to --workspace can be the workspace's id, name, or slug.
The workspaces sub-command can also be used to view and manage workspaces.
List Workspaces
To see a list of all workspaces, use workspaces list:
$ npx openrouter-key-manager workspaces list
Found 2 workspaces
┌────────────────────┬────────────────────┬──────────────────────────────────────┐
│ Name │ Slug │ ID │
├────────────────────┼────────────────────┼──────────────────────────────────────┤
│ Seneca-Acad-AIP444 │ seneca-acad-aip444 │ 1576d782-43cd-424a-83ac-b7b9a37fc993 │
├────────────────────┼────────────────────┼──────────────────────────────────────┤
│ Default Workspace │ default │ 891e0cdd-b0ff-58c0-a36f-72f2a706d8c2 │
└────────────────────┴────────────────────┴──────────────────────────────────────┘Create Workspace
To create a new workspace, use workspaces create:
$ npx openrouter-key-manager workspaces create Test
✓ Created workspace: Test
Slug: test
ID: ed609d27-2cdd-447d-93c2-3b45622b4204Include the optional --slug and --description flags to add more detail.
[!NOTE] The slug must be URL-friendly (alphanumeric and dashes only).
Delete Workspace
To delete an existing workspace, use workspaces delete:
$ npx openrouter-key-manager workspaces delete Test
Deleting a workspace cannot be undone.
The workspace must contain no API keys.
✔ Delete workspace "test"? Yes
✓ Deleted workspace: Test
Slug: test
ID: ed609d27-2cdd-447d-93c2-3b45622b4204[!NOTE] Delete all API Keys from a workspace before you try to delete the workspace itself.
Usage
CLI Usage
See the CLI Commands section below for detailed command documentation.
Library Usage
Import and use the library functions in your application:
import {
create,
bulkCreate,
list,
destroy,
disable,
enable,
setLimit,
rotate,
report,
analytics,
getAnalyticsMeta,
queryAnalytics,
} from "openrouter-key-manager";
// Create a single key
const key = await create({
provisioningKey: "your-provisioning-key",
email: "[email protected]",
tags: ["CCP555", "student"],
limit: 15,
expiresIn: "3 months",
});
console.log(`Created key: ${key.apiKey}`);
console.log(`Hash: ${key.hash}`);
// List all keys
const keys = await list({
provisioningKey: "your-provisioning-key",
includeDisabled: false,
});
console.log(`Found ${keys.length} active keys`);
// Disable a key
const result = await disable({
provisioningKey: "your-provisioning-key",
hash: key.hash,
});
console.log(`Disabled ${result.modified.length} key(s)`);
// Generate an HTML report
const reportResult = await report({
provisioningKey: "your-provisioning-key",
pattern: "*CCP555*",
});
// Save the HTML report
await writeFile("report.html", reportResult.html);
// Analyze the previous 30 complete UTC days by API key
const usage = await analytics({
provisioningKey: "your-provisioning-key",
pattern: "*CCP555*",
});
if (usage.view === "keys") {
for (const row of usage.rows) {
console.log(row.keyName, row.requests, row.totalSpend);
}
}Library API Reference
All library functions accept an options object with a provisioningKey property, or you can pass it via environment variable:
// Option 1: Pass provisioning key directly
const key = await create({
provisioningKey: "your-key",
email: "[email protected]",
limit: 15,
expiresAt: "2027-12-31",
});
// Option 2: Use environment variable
process.env.OPENROUTER_PROVISIONING_KEY = "your-key";
const key = await create({
email: "[email protected]",
limit: 15,
expiresIn: "30d",
});create(options)- Create a single API keyinterface CreateOptions { provisioningKey?: string; email: string; limit: number; tags?: string[]; date?: string; // YYYY-MM-DD expiresAt?: string; // YYYY-MM-DD or YYYY-MM-DDTHH:mm:ssZ expiresIn?: string; // e.g. 30d, 12h, 3 months }bulkCreate(file, options)- Create multiple keys from CSV/JSONinterface BulkCreateOptions { provisioningKey?: string; limit: number; date?: string; expiresAt?: string; expiresIn?: string; delimiter?: string; skipHeader?: boolean; }list(options)- List API keysinterface ListOptions { provisioningKey?: string; pattern?: string; includeDisabled?: boolean; }destroy(options)- Delete API keysinterface DestroyOptions { provisioningKey?: string; pattern?: string; hash?: string; }disable(options)/enable(options)- Disable/enable keysinterface DisableOptions { provisioningKey?: string; pattern?: string; hash?: string; }setLimit(options)- Update spending limitsinterface SetLimitOptions { provisioningKey?: string; pattern?: string; hash?: string; limit: number; }rotate(options)- Rotate API keysinterface RotateOptions { provisioningKey?: string; pattern?: string; hash?: string; }report(options)- Generate HTML usage reportinterface ReportOptions { provisioningKey?: string; pattern?: string; includeDisabled?: boolean; }analytics(options)- Query curated workspace analyticstype AnalyticsView = "keys" | "summary" | "models"; type AnalyticsPeriod = "hour" | "day" | "7-days" | "30-days" | "90-days"; interface AnalyticsOptions { provisioningKey?: string; workspace?: string; view?: AnalyticsView; // default: "keys" period?: AnalyticsPeriod; // default: "30-days" pattern?: string; includeDisabled?: boolean; }The discriminated
AnalyticsResultcontains the resolved workspace, UTC range, normalized rows, query count and time, truncation state, and warnings. For advanced queries, usegetAnalyticsMeta()andqueryAnalytics(query); raw metric and dimension names remain dynamic strings so they can follow OpenRouter's live metadata catalog.
Quick Start
1. Create API Keys for Multiple Users
Create a CSV file with user information, including their email and one or more tags (every column after email is considered a tag):
accounts.csv:
email,course,role
[email protected],CCP555,student
[email protected],CCP555,student
[email protected],CCP555,professorUse this file to create keys for each user with the specified spending limit (limits are per user and in US dollars):
openrouter-key-manager bulk-create --limit 15 accounts.csvYou can also create keys with an expiration date or relative lifetime:
# Expire at the end of 2027-12-31 UTC
openrouter-key-manager bulk-create --limit 15 --expires-at 2027-12-31 accounts.csv
# Expire 3 months from now
openrouter-key-manager bulk-create --limit 15 --expires-in "3 months" accounts.csvThis will generate API Keys for all users in accounts.csv and create a CSV file (e.g., CCP555-student-2025-01-15.csv) containing the newly created keys:
name,key,hash
[email protected] CCP555 student 2025-01-15,sk-or-v1-abc123...,hash-abc123...
[email protected] CCP555 student 2025-01-15,sk-or-v1-def456...,hash-def456...
[email protected] CCP555 professor 2025-01-15,sk-or-v1-ghi789...,hash-ghi789...Important:
- The
keycolumn contains the actual API keys to distribute to users - The
hashcolumn is used for management operations (list, disable, delete, rotate) - Keep this CSV file secure - it contains sensitive API keys
2. Monitor Usage
List all active keys (use --include-disabled to see all keys):
openrouter-key-manager listBy default, the name and hash columns are truncated for readability. Use --full to see complete values:
openrouter-key-manager list --fullList keys by pattern (e.g., email or tag):
openrouter-key-manager list --pattern "*CCP555*"Generate a detailed HTML report for all or some keys:
openrouter-key-manager report --pattern "*CCP555*"Analyze usage over the previous 30 complete UTC days:
openrouter-key-manager analytics
openrouter-key-manager analytics --summary
openrouter-key-manager analytics --models --period 7-days3. Adjust Spending Limits
Increase limits for students running low on credits:
# Single key by hash
openrouter-key-manager set-limit --hash abc123... --limit 25 -y
# All students in a course
openrouter-key-manager set-limit --pattern "*CCP555*student*" --limit 25 -y
# Bulk update from CSV
openrouter-key-manager bulk-set-limit --limit 25 CCP555-student-2025-01-15.csv -y4. Rotate Keys
Rotate keys for security (generates new keys with same names and limits):
# Rotate specific key
openrouter-key-manager rotate --hash abc123... -y
# Rotate all keys for a course
openrouter-key-manager rotate --pattern "*CCP555*" -y
# Bulk rotate from CSV
openrouter-key-manager bulk-rotate CCP555-student-2025-01-15.csv -y5. Manage Keys
Disable keys temporarily:
openrouter-key-manager disable --pattern "*CCP555*student*" -yRe-enable keys:
openrouter-key-manager enable --pattern "*CCP555*student*" -yDelete keys permanently:
# Delete by pattern
openrouter-key-manager delete --pattern "*CCP555*" -y
# Or delete using the hash from your CSV
openrouter-key-manager delete --hash abc123... -yCommands
create
Create a single API key and save it to a CSV file.
openrouter-key-manager create [options]Required Options:
-l, --limit <amount>- Spending limit in US dollars (e.g.,10for $10)-e, --email <email>- User's email address
Optional:
-t, --tags <tags...>- Multiple tags passed as separate arguments (e.g.,--tags CCP555 student)-d, --date <date>- Issue date inYYYY-MM-DDformat (default: today)--expires-at <datetime>- Expire at a UTC date/time (YYYY-MM-DDorYYYY-MM-DDTHH:mm:ssZ)--expires-in <duration>- Expire after a duration like30d,12h, or3 months-o, --output <file>- CSV output filename (default: auto-generated)
Examples:
# Create key with tags
openrouter-key-manager create \
--limit 10 \
--email [email protected] \
--tags CCP555 student
# Create key without tags
openrouter-key-manager create \
--limit 10 \
--email [email protected]
# Create key that expires at the end of a UTC day
openrouter-key-manager create \
--limit 10 \
--email [email protected] \
--expires-at 2027-12-31
# Create key that expires after 90 days
openrouter-key-manager create \
--limit 10 \
--email [email protected] \
--expires-in 90d
# Specify custom output filename
openrouter-key-manager create \
--limit 10 \
--email [email protected] \
--tags CCP555 student \
--output alice-key.csvOutput:
Creates a CSV file with the key name, key, and hash columns:
name,key,hash
[email protected] CCP555 student 2025-01-15,sk-or-v1-abc123...,hash-abc123...- name: The key identifier (email + tags + date)
- key: The actual API key to give to the user
- hash: The key's unique identifier for management operations
Default Filename: {email}-{date}.csv or {tags}-{date}.csv
bulk-create
Create API keys for multiple users from a CSV/TSV file.
openrouter-key-manager bulk-create [options] <file>Arguments:
<file>- CSV or TSV file with account information
Required Options:
-l, --limit <amount>- Spending limit in US dollars (e.g.,10for $10)
Optional:
-d, --date <date>- Issue date inYYYY-MM-DDformat (default: today)--expires-at <datetime>- Expire at a UTC date/time (YYYY-MM-DDorYYYY-MM-DDTHH:mm:ssZ)--expires-in <duration>- Expire after a duration like30d,12h, or3 months--delimiter <char>- Field delimiter (auto-detected:.csv=,,.tsv=\t)--skip-header [boolean]- Skip first row (default:true)-o, --output <file>- CSV output filename (default: auto-generated)
Input File Format:
The input CSV must have email as the first column. All subsequent columns
are treated as tags (optional):
email,tag1,tag2,tag3
[email protected],CCP555,student,section-A
[email protected],CCP555,student,section-B
[email protected],CCP555,professor
[email protected]Key Points:
- First column: email (required)
- Remaining columns: tags (optional)
- Empty tag cells are ignored
- Rows can have just email with no tags
Examples:
# Create keys with default output filename
openrouter-key-manager bulk-create --limit 10 accounts.csv
# Create keys that expire at the end of 2027-12-31 UTC
openrouter-key-manager bulk-create --limit 10 --expires-at 2027-12-31 accounts.csv
# Create keys that expire in 3 months
openrouter-key-manager bulk-create --limit 10 --expires-in "3 months" accounts.csv
# Specify custom output filename
openrouter-key-manager bulk-create \
--limit 10 \
--output ccp555-keys.csv \
accounts.csv
# Use TSV file
openrouter-key-manager bulk-create --limit 10 accounts.tsv
# Specify custom delimiter
openrouter-key-manager bulk-create \
--limit 10 \
--delimiter "|" \
accounts.txtOutput:
Creates a CSV file with name, key, and hash columns:
name,key,hash
[email protected] CCP555 student 2025-01-15,sk-or-v1-abc123...,hash-abc123...
[email protected] CCP555 student 2025-01-15,sk-or-v1-def456...,hash-def456...- name: The key identifier (email + tags + date)
- key: The actual API key to distribute to users
- hash: The key's unique identifier for management operations
Default Filename: {tags}-{date}.csv (e.g., CCP555-student-2025-01-15.csv)
Security Note: This CSV contains actual API keys. Store it securely and distribute keys to users through secure channels.
list
List API keys with usage information.
openrouter-key-manager list [options]Options:
-p, --pattern <pattern>- Filter by glob pattern--include-disabled- Include disabled keys (default: false)-f, --format <format>- Output format:table,json, orcsv(default:table)-o, --output <file>- Write to file instead of stdout--full- Show full name and hash (default: truncated)
Examples:
# List all active keys (truncated display)
openrouter-key-manager list
# List with full name and hash
openrouter-key-manager list --full
# List keys matching a pattern
openrouter-key-manager list --pattern "*CCP555*"
# List keys for a specific user
openrouter-key-manager list --pattern "[email protected]*"
# Include disabled keys
openrouter-key-manager list --include-disabled
# Export to CSV
openrouter-key-manager list \
--pattern "*CCP555*" \
--format csv \
--output ccp555-status.csvOutput Fields:
name- Key name (email + tags + date)- Default: Truncated at first space (shows email only)
- With
--full: Complete name
hash- Key hash identifier (for management operations)- Default: First 7 characters
- With
--full: Complete hash
remaining- Remaining budget in dollarsdisabled- Whether the key is disabled
Note: The list command does not show the actual API keys for
security reasons. It only shows the hash, which can be used for management
operations.
Truncation Behavior:
By default, the table format truncates columns for readability:
name: Shows only the email (splits at first space)hash: Shows first 7 characters
Use --full to see complete values. JSON and CSV formats always show full values.
CSV Output Format:
name,hash,remaining,disabled
[email protected] CCP555 student 2025-01-15,hash-abc123...,8.45,false
[email protected] CCP555 student 2025-01-15,hash-def456...,2.10,falseGlob Patterns:
Use standard glob wildcards (quote to avoid shell expansion):
*- Match any characters?- Match single character**- Match across separators
Examples:
"*CCP555*"- All keys with CCP555 tag"[email protected]*"- All keys for alice"*2025-01-15*"- All keys from specific date"*CCP555*student*"- Keys with both tags
set-limit
Set the spending limit for one or more API keys.
openrouter-key-manager set-limit [options]Required Options:
-l, --limit <amount>- New spending limit in US dollars (e.g.,25for $25)
Other Options:
-p, --pattern <pattern>- Filter by glob pattern--hash <hash>- Specific key hash to update-y, --confirm- Skip confirmation prompt
Note: Either --pattern or --hash is required (but not both).
Examples:
# Update specific key by hash
openrouter-key-manager set-limit --hash hash-abc123... --limit 25 -y
# Update all keys matching pattern (with confirmation)
openrouter-key-manager set-limit --pattern "*CCP555*student*" --limit 25
# Update all keys for a user
openrouter-key-manager set-limit --pattern "[email protected]*" --limit 30 -y
# Increase limits for all students in a course
openrouter-key-manager set-limit --pattern "*CCP555*" --limit 20 -yUse Cases:
- Students running low on credits mid-semester
- Adjusting budgets for final projects
- Increasing limits for TAs or professors
- Bulk budget adjustments
bulk-set-limit
Set spending limits for multiple API keys using a CSV or JSON file.
openrouter-key-manager bulk-set-limit [options] <file>Arguments:
<file>- CSV or JSON file with key information
Required Options:
-l, --limit <amount>- New spending limit in US dollars (e.g.,25for $25)
Other Options:
--delimiter <char>- Field delimiter for CSV (auto-detected)--skip-header [boolean]- Skip first row (default: true)-y, --confirm- Skip confirmation prompt
Input File Format:
You can use the CSV file created by create or bulk-create, or create a simple CSV with just name and hash columns:
CSV (from bulk-create):
name,key,hash
[email protected] CCP555 student 2025-01-15,sk-or-v1-abc123...,hash-abc123...
[email protected] CCP555 student 2025-01-15,sk-or-v1-def456...,hash-def456...CSV (minimal):
name,hash
[email protected] CCP555 student 2025-01-15,hash-abc123...
[email protected] CCP555 student 2025-01-15,hash-def456...JSON:
[
{
"name": "[email protected] CCP555 student 2025-01-15",
"hash": "hash-abc123..."
},
{
"name": "[email protected] CCP555 student 2025-01-15",
"hash": "hash-def456..."
}
]Examples:
# Update limits using CSV from bulk-create
openrouter-key-manager bulk-set-limit \
--limit 25 \
CCP555-student-2025-01-15.csv -y
# Update with confirmation prompt
openrouter-key-manager bulk-set-limit \
--limit 30 \
CCP555-keys.csv
# Update using JSON file
openrouter-key-manager bulk-set-limit \
--limit 20 \
keys.json -yUse Cases:
- Mid-semester budget increases for entire class
- Adjusting limits for specific groups
- Restoring limits after temporary reductions
rotate
Rotate one or more API keys by deleting the old key and creating a new one with the same name and limit. This generates new API keys that must be distributed to users.
openrouter-key-manager rotate [options]Options:
-p, --pattern <pattern>- Filter by glob pattern--hash <hash>- Specific key hash to rotate-y, --confirm- Skip confirmation prompt-o, --output <file>- CSV output file (default: auto-generated)
Note: Either --pattern or --hash is required (but not both).
Examples:
# Rotate specific key by hash
openrouter-key-manager rotate --hash hash-abc123... -y
# Rotate all keys matching pattern (with confirmation)
openrouter-key-manager rotate --pattern "*CCP555*"
# Rotate all keys for a user
openrouter-key-manager rotate --pattern "[email protected]*" -y
# Rotate with custom output filename
openrouter-key-manager rotate \
--pattern "*CCP555*" \
--output ccp555-rotated-keys.csv -yOutput:
Creates a CSV file with the new keys:
name,key,hash
[email protected] CCP555 student 2025-01-15,sk-or-v1-xyz789...,hash-xyz789...
[email protected] CCP555 student 2025-01-15,sk-or-v1-uvw456...,hash-uvw456...Important:
- Old keys are permanently deleted
- New keys have the same name and limit as the old keys
- Users must update to the new API keys
- The old API keys will no longer work
Use Cases:
- Security incident response (compromised keys)
- Semester transitions (reuse same key names)
- Periodic security rotation policy
- Revoking access while maintaining key structure
Default Filename: rotated-{date}.csv
bulk-rotate
Rotate multiple API keys using a CSV or JSON file.
openrouter-key-manager bulk-rotate [options] <file>Arguments:
<file>- CSV or JSON file with key information
Options:
--delimiter <char>- Field delimiter for CSV (auto-detected)--skip-header [boolean]- Skip first row (default: true)-y, --confirm- Skip confirmation prompt-o, --output <file>- CSV output file (default: auto-generated)
Input File Format:
You can use the CSV file created by create or bulk-create, or create a simple CSV with just name and hash columns:
CSV (from bulk-create):
name,key,hash
[email protected] CCP555 student 2025-01-15,sk-or-v1-abc123...,hash-abc123...
[email protected] CCP555 student 2025-01-15,sk-or-v1-def456...,hash-def456...CSV (minimal):
name,hash
[email protected] CCP555 student 2025-01-15,hash-abc123...
[email protected] CCP555 student 2025-01-15,hash-def456...JSON:
[
{
"name": "[email protected] CCP555 student 2025-01-15",
"hash": "hash-abc123..."
},
{
"name": "[email protected] CCP555 student 2025-01-15",
"hash": "hash-def456..."
}
]Examples:
# Rotate using CSV from bulk-create
openrouter-key-manager bulk-rotate CCP555-student-2025-01-15.csv -y
# Rotate with confirmation prompt
openrouter-key-manager bulk-rotate CCP555-keys.csv
# Rotate using JSON file
openrouter-key-manager bulk-rotate keys.json -y
# Specify custom output filename
openrouter-key-manager bulk-rotate \
--output ccp555-new-keys.csv \
CCP555-old-keys.csv -yOutput:
Creates a CSV file with the new keys:
name,key,hash
[email protected] CCP555 student 2025-01-15,sk-or-v1-xyz789...,hash-xyz789...
[email protected] CCP555 student 2025-01-15,sk-or-v1-uvw456...,hash-uvw456...Important:
- Old keys are permanently deleted
- New keys have the same names and limits as the old keys
- Users must update to the new API keys
- The old API keys will no longer work
Use Cases:
- Rotating all keys at semester end
- Security incident affecting multiple users
- Implementing periodic rotation policy
- Migrating to new key generation
Default Filename: rotated-{date}.csv
disable
Disable one or more API keys. Disabled keys cannot be used but can be re-enabled later.
openrouter-key-manager disable [options]Options:
-p, --pattern <pattern>- Filter by glob pattern--hash <hash>- Specific key hash to disable-y, --confirm- Skip confirmation prompt
Note: Either --pattern or --hash is required (but not both).
Examples:
# Disable specific key by hash
openrouter-key-manager disable --hash hash-abc123... -y
# Disable all keys matching pattern (with confirmation)
openrouter-key-manager disable --pattern "*CCP555*"
# Disable all keys for a user
openrouter-key-manager disable --pattern "[email protected]*" -yenable
Re-enable one or more previously disabled API keys.
openrouter-key-manager enable [options]Options:
-p, --pattern <pattern>- Filter by glob pattern--hash <hash>- Specific key hash to enable-y, --confirm- Skip confirmation prompt
Note: Either --pattern or --hash is required (but not both).
Examples:
# Enable specific key by hash
openrouter-key-manager enable --hash hash-abc123... -y
# Enable all keys matching pattern (with confirmation)
openrouter-key-manager enable --pattern "*CCP555*"
# Enable all keys for a user
openrouter-key-manager enable --pattern "[email protected]*" -ydelete
Permanently delete one or more API keys. This cannot be undone.
openrouter-key-manager delete [options]Options:
-p, --pattern <pattern>- Filter by glob pattern--hash <hash>- Specific key hash to delete-y, --confirm- Skip confirmation prompt
Note: Either --pattern or --hash is required (but not both).
Examples:
# Delete specific key by hash
openrouter-key-manager delete --hash hash-abc123... -y
# Delete all keys matching pattern (with confirmation)
openrouter-key-manager delete --pattern "*CCP555*"
# Delete all keys from specific date
openrouter-key-manager delete --pattern "*2025-01-15*" -ybulk-delete
Delete multiple API keys using a CSV or JSON file.
openrouter-key-manager bulk-delete [options] <file>Arguments:
<file>- CSV or JSON file with key information
Options:
--delimiter <char>- Field delimiter for CSV (auto-detected)--skip-header [boolean]- Skip first row (default: true)-y, --confirm- Skip confirmation prompt
Input File Format:
You can use the CSV file created by create or bulk-create, or create a simple CSV with just name and hash columns (i.e., the key itself is not needed):
CSV (from bulk-create):
name,key,hash
[email protected] CCP555 student 2025-01-15,sk-or-v1-abc123...,hash-abc123...
[email protected] CCP555 student 2025-01-15,sk-or-v1-def456...,hash-def456...CSV (minimal):
name,hash
[email protected] CCP555 student 2025-01-15,hash-abc123...
[email protected] CCP555 student 2025-01-15,hash-def456...JSON:
[
{
"name": "[email protected] CCP555 student 2025-01-15",
"hash": "hash-abc123..."
},
{
"name": "[email protected] CCP555 student 2025-01-15",
"hash": "hash-def456..."
}
]Note: The bulk-delete command only needs the name and hash columns. If your CSV has additional columns (like key), they will be ignored.
Examples:
# Delete using CSV from bulk-create
openrouter-key-manager bulk-delete CCP555-student-2025-01-15.csv -y
# Delete with confirmation prompt
openrouter-key-manager bulk-delete CCP555-keys.csv
# Delete using JSON file
openrouter-key-manager bulk-delete keys.json -yanalytics
Show curated usage analytics for current API keys in the selected workspace.
The default view has one row per key; --summary produces one workspace row,
and --models groups usage by model.
openrouter-key-manager analytics [options]Options:
--summary- Show one aggregate workspace row--models- Group usage by model--period <period>- Completed UTC window:hour,day,7-days,30-days, or90-days(default:30-days)-p, --pattern <pattern>- Select API keys by glob pattern--include-disabled- Include disabled keys (default: false)-f, --format <format>- Outputtable,json, orcsv(default:table)-o, --output <file>- Write output to a file instead of stdout
--summary and --models are mutually exclusive. Periods always exclude the
current partial UTC hour or day. The 90-days period is queried as three
contiguous 30-day ranges and merged.
Examples:
# Previous 30 complete UTC days, one row per active key
openrouter-key-manager analytics
# Previous complete UTC day, summarized for the workspace
openrouter-key-manager analytics --summary --period day
# Models used by matching keys over seven complete UTC days
openrouter-key-manager analytics \
--models \
--period 7-days \
--pattern "*CCP555*"
# Export the previous completed hour as CSV
openrouter-key-manager analytics \
--period hour \
--include-disabled \
--format csv \
--output hourly-analytics.csvEvery view includes requests, total spend, total/prompt/completion/reasoning/ cached tokens, cache hit rate, and blended cost per million tokens. Cache hit rate is cached tokens divided by prompt tokens; blended cost is total spend divided by total tokens, multiplied by one million. A zero denominator produces zero.
The command uses OpenRouter's analytics query API, not the older fixed-window activity endpoint. If OpenRouter reports warnings or truncation, the command prints a warning to stderr and still emits the available data.
For advanced library queries outside this curated interface:
import { getAnalyticsMeta, queryAnalytics } from "openrouter-key-manager";
const metadata = await getAnalyticsMeta({ provisioningKey: "your-key" });
const raw = await queryAnalytics(
{
metrics: ["request_count", "total_usage"],
dimensions: ["model"],
},
{ provisioningKey: "your-key" },
);See OpenRouter's analytics metadata API for the current metric and dimension catalog.
report
Generate a comprehensive HTML report with usage statistics.
openrouter-key-manager report [options]Options:
-p, --pattern <pattern>- Filter by glob pattern--include-disabled- Include disabled keys (default: false)-o, --output <file>- Output filename (default:report-YYYY-MM-DD.html)
Examples:
# Generate report for all active keys
openrouter-key-manager report
# Generate report for specific pattern
openrouter-key-manager report \
--pattern "*CCP555*" \
--output ccp555-report.html
# Include disabled keys
openrouter-key-manager report --include-disabled
# Report for specific date
openrouter-key-manager report --pattern "*2025-01-15*"Report Contents:
The HTML report includes:
Summary Statistics:
- Total keys (active/disabled)
- Total budget limit
- Total usage
- Total remaining budget
Detailed Table (sorted by usage):
- Key name
- Hash (hover to see full, click to copy)
- Disabled status
- Budget limit
- Remaining budget (highlighted if < $1)
- Total usage
- Daily/weekly/monthly usage
- Creation date
The report is a self-contained HTML file that works in any browser.
Key Naming Convention
Keys are automatically named using this format:
{email} {tag1} {tag2} ... {YYYY-MM-DD}Examples:
[email protected] CCP555 student 2025-01-15[email protected] research AI-lab 2025-01-15[email protected] 2025-01-15(no tags)
Tag Rules:
- Tags cannot contain spaces (use hyphens or underscores)
- Tags are optional
- Tags make filtering easier
Complete Workflow Example
Semester Setup
1. Prepare student list (students.csv):
email,course,role,section
[email protected],CCP555,student,A
[email protected],CCP555,student,A
[email protected],CCP555,student,B
[email protected],CCP555,TA2. Create keys with $15 limit:
openrouter-key-manager bulk-create \
--limit 15 \
--expires-in "4 months" \
--output ccp555-winter2025.csv \
students.csv3. Distribute keys to students:
The CSV file contains three columns:
name: Key identifierkey: The actual API key (distribute this to users)hash: Management identifier (keep for yourself)
You can:
- Extract the
keycolumn and email to students - Create individual files per student
- Import into your LMS
- Use a script to send personalized emails
Example: Extract keys for distribution
# Extract just email and key columns
cut -d',' -f1,2 ccp555-winter2025.csv | tail -n +2 > keys-to-distribute.csvDuring Semester
4. Check usage weekly:
# Quick status check (truncated display)
openrouter-key-manager list --pattern "*CCP555*"
# Detailed report
openrouter-key-manager report \
--pattern "*CCP555*" \
--output weekly-report.html5. Handle budget issues:
# Increase limits for students running low
openrouter-key-manager set-limit \
--pattern "*CCP555*student*" \
--limit 25 -y
# Or increase specific student's limit
openrouter-key-manager set-limit \
--pattern "[email protected]*" \
--limit 30 -y6. Handle security issues:
# Disable a specific student's key temporarily
openrouter-key-manager disable --pattern "[email protected]*" -y
# Rotate compromised key (generates new key)
openrouter-key-manager rotate --pattern "[email protected]*" -y
# Re-enable after issue is resolved
openrouter-key-manager enable --pattern "[email protected]*" -yEnd of Semester
7. Clean up:
# Delete all course keys using the original CSV
openrouter-key-manager bulk-delete ccp555-winter2025.csv -y
# Or delete by pattern
openrouter-key-manager delete --pattern "*CCP555*" -yBest Practices
Secure storage - The CSV files from
create/bulk-create/rotatecontain actual API keys. Store them securely and distribute keys through secure channels.Keep creation CSVs - Save the CSV output for later management operations (the hash column is needed for disable/delete/rotate/set-limit).
Use meaningful tags - Choose tags that make filtering easy (course codes, roles, sections).
Consistent naming - Establish tag conventions (e.g.,
COURSE-ROLE-SECTION).Regular monitoring - Generate reports periodically to track usage and identify students running low on credits.
Proactive limit adjustments - Use
set-limitto increase budgets before students run out, rather than waiting for complaints.Disable before delete - Test impact by disabling keys before permanent deletion. Use
enableto restore access if needed.Rotate for security - Use
rotateinstead ofdelete+createwhen you want to maintain the same key names and limits.Pattern matching - Use glob patterns to manage groups efficiently.
File organization - Use descriptive output filenames:
ccp555-winter2025.csvresearch-team-keys.csvadmin-staff-2025.csv
Backup - Keep copies of CSV files in version control or secure storage (encrypted if they contain API keys).
Key distribution - Extract just the
keycolumn when distributing to users. Don't share thehashcolumn publicly.Use
-yfor automation - The-yflag (shorthand for--confirm) is useful in scripts to skip confirmation prompts.Mutual exclusivity - Remember that
--patternand--hashcannot be used together. Choose the appropriate one for your use case.Rotation vs. Creation - Use
rotatewhen you want to keep the same key names (e.g., semester transitions). Usecreatewhen you want new names with updated dates.Truncated display - Use the default
listoutput for quick overviews (shows just emails). Use--fullwhen you need complete names and hashes for management operations.
License
BSD-2-Clause
