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

llm-key-validator

v1.0.1

Published

Validate API keys for OpenAI, Anthropic, Google Gemini, Groq, Mistral, OpenRouter, Cohere, DeepSeek, Together, Fireworks, xAI, and Perplexity. Zero dependencies. CLI + library.

Readme

llm-key-validator

npm version CI license: MIT node

Check if an LLM API key is valid — no install required:

npx llm-key-validator sk-ant-...

Supports OpenAI, Anthropic, Google Gemini, Groq, Mistral, OpenRouter, Cohere, DeepSeek, Together, Fireworks, xAI, and Perplexity, as a CLI or a TypeScript library. Zero runtime dependencies, works in Node ≥ 20 (and Bun/Deno/Cloudflare Workers/browsers as a library).

  • Auto-detects the provider from the key's prefix
  • Distinguishes invalid keys from rate limits, timeouts, and network errors
  • --env validates every *_API_KEY in your environment; scan audits a .env file
  • --offline mode checks key format with no network call
  • Also available as a library (npm i llm-key-validator) and a GitHub Action

Install

# no install — one-shot
npx llm-key-validator <key>

# global CLI (installs both `lkv` and `llm-key-validator`)
npm i -g llm-key-validator

# as a library
npm i llm-key-validator

# Python (≥ 3.8, stdlib only, same CLI surface)
pip install llm-key-validator

After global install, use the short alias lkv everywhere. See python/README.md for Python-specific examples.

CLI

# auto-detect provider from key prefix
npx llm-key-validator sk-ant-...

# force a provider
lkv <key> --provider openai

# read keys from stdin (preferred — avoids shell history)
echo "$OPENAI_API_KEY" | lkv --stdin

# bulk
lkv <key1> <key2> <key3>

# validate every <PROVIDER>_API_KEY found in the environment
lkv --env

# JSON output for scripting
lkv <key> --json

# offline mode — format-only check, no network call
lkv --offline sk-ant-...

# scan a .env file (.env and .env.local are checked by default)
lkv scan
lkv scan --check-revoked   # hide VALIDs, show only failures

Exit codes: 0 all valid, 1 usage error, 2 ≥ 1 invalid, 3 unexpected error. Run lkv --help for the full flag list.

Library

import { validateKey } from "llm-key-validator";

const result = await validateKey("sk-ant-...");
if (result.valid) {
  console.log("OK —", result.provider, "in", result.latencyMs, "ms");
} else {
  console.log("Failed:", result.reason, result.message);
}

For bundle-size-sensitive consumers (browser, edge workers), import only the providers you need:

import { validateKey } from "llm-key-validator/core";
import { openai, anthropic } from "llm-key-validator/providers";

await validateKey(key, { providers: [openai, anthropic] });

llm-key-validator/core has zero import-time side effects, so bundlers drop every provider you don't import (~500 B per provider vs. ~5 KB for the eager default with all 12).

Options

await validateKey(key, {
  provider: "anthropic",  // force, skip auto-detect
  offline: true,          // skip network call; format-only check
  timeoutMs: 5000,        // default 10_000
  retries: 1,             // default 1 (5xx / network errors)
});

Result shape:

type ValidationResult =
  | { valid: true;  provider: string; latencyMs: number }
  | { valid: false; provider: string; reason: ValidationFailureReason; message: string };

type ValidationFailureReason =
  | "invalid_key" | "rate_limited" | "server_error"
  | "network_error" | "timeout" | "unknown_provider" | "malformed_key";

See examples/ for browser, Cloudflare Worker, and Bun usage.

Supported providers

| Provider | Env var | Key prefix | Endpoint | |---|---|---|---| | OpenAI | OPENAI_API_KEY | sk-... | GET /v1/models | | Anthropic | ANTHROPIC_API_KEY | sk-ant-... | GET /v1/models | | Google Gemini | GOOGLE_API_KEY | AIza... | GET /v1beta/models?key= | | Groq | GROQ_API_KEY | gsk_... | GET /openai/v1/models | | Mistral | MISTRAL_API_KEY | 32 alphanumeric | GET /v1/models | | OpenRouter | OPENROUTER_API_KEY | sk-or-... | GET /v1/auth/key | | Cohere | COHERE_API_KEY | 40 alphanumeric | GET /v1/models | | DeepSeek | DEEPSEEK_API_KEY | sk-<32 hex> | GET /models | | Together | TOGETHER_API_KEY | 64 hex or tgp_v1_... | GET /v1/models | | Fireworks | FIREWORKS_API_KEY | fw_... | GET /inference/v1/models | | xAI (Grok) | XAI_API_KEY | xai-... | GET /v1/models | | Perplexity | PERPLEXITY_API_KEY | pplx-... | POST /chat/completions (max_tokens: 1) |

Note: most providers expose a /models listing that costs nothing. Perplexity has no such endpoint — a single 1-token chat call is the smallest probe and may incur a tiny charge.

Auto-detect caveat: Mistral and Cohere keys are opaque alphanumeric strings with no distinguishing prefix. They are tried last during auto-detect to minimize false positives, but for any 32- or 40-character alphanumeric input, prefer --provider mistral or --provider cohere to be explicit.

Want to add a provider? See CONTRIBUTING.md.

GitHub Action

Validate every *_API_KEY secret in your repo on every PR:

# .github/workflows/check-keys.yml
name: Check keys
on: [pull_request, workflow_dispatch]

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: jishnu-mohan/llm-key-validator@v1
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
        with:
          args: "--env --json"

The default args (--env --json) validates every standard *_API_KEY env var exposed to the job. Fails the build (exit 1) if any key is invalid.

Security

  • Validation calls hit the live provider APIs — only validate keys you own
  • Some endpoints count toward rate limits even when not billed
  • Prefer --stdin over passing keys on argv (shell history)
  • Keys are never logged in full; CLI output masks to first 7 and last 4 characters

See SECURITY.md for the disclosure process.

License

MIT