Skip to content

API Key Generator

Generate a strong API key — random hex, base64, prefixed (sk_live_…), or UUID v4.

An API key is a credential — a long opaque string a client presents to a service to identify itself. Unlike a password, it isn’t typed by a human, so it can be longer and more random than a password ever could. The tool above generates API keys using the browser’s crypto.getRandomValues() API; the value is generated in your browser and never transmitted.

What “good” means for an API key

Three properties matter:

  1. Unguessable. The key must come from a cryptographically secure random number generator (CSPRNG). Math.random() is not a CSPRNG — its output is predictable to an attacker who observes a few outputs. Browser crypto.getRandomValues() is. Node.js crypto.randomBytes() is. Anything else, check the docs.
  2. Long enough. 128 bits of entropy is the minimum bar (2¹²⁸ keyspace), 256 is conservative. That’s 16–32 raw bytes, which encode to 22–43 characters in base64url or 32–64 in hex.
  3. Distinguishable from other keys. A common pattern: a short human-readable prefix that identifies the issuer or environment, then a random suffix. sk_live_8K9F3p2N... and sk_test_4mP7Q1R... are immediately distinguishable as Stripe live vs test keys, which makes leak-detection easier.

A typical layout

prefix _ env _ randomness
sk     _ live _ 9KdQ8pWnZ3F4mR7vT2cY1B6jN5xLs0gH
  • Prefix. Identifies the key type or service. Stripe uses sk_ for secret, pk_ for publishable. GitHub uses ghp_ for personal access tokens, ghs_ for server tokens.
  • Environment. live vs test is widely standard.
  • Randomness. 32 base64url characters = 192 bits of entropy. More than enough.

The tool above emits plain random keys (hex or base64url), a UUID v4, or a key with a fixed sk_live_ prefix. For your own prefix, generate a plain key and prepend it — the randomness is all in the generated part.

Encoding choices

Encoding16 raw bytes becomesProperties
Hex32 chars (a–f, 0–9)Case-insensitive, no special chars, ~50% denser than binary
Base6424 chars + paddingIncludes +, /, = — needs URL-encoding in URLs
Base64url22 chars (no padding)URL- and header-safe out of the box
ASCII alphanumeric~26 charsSkips ambiguous chars (0/O, 1/l) — used by some “human-readable” key generators

For machine-to-machine API keys, base64url is the typical choice — dense, URL-safe, no special characters. For keys that humans might type once (a setup wizard), the ambiguous-character-stripped alphanumeric form is friendlier. See URL encoding for why URL-safety matters in tokens.

What clients should do with an API key

  • Send it in the Authorization header, not the query string. Query strings end up in access logs, in Referer headers when the page links elsewhere, and in browser history.
  • Use HTTPS-only. An API key over HTTP is a credential broadcast in cleartext to every network hop.
  • Rotate periodically. A key that’s been live for two years has likely leaked somewhere — a misconfigured CI log, a checked-in .env, a developer’s laptop that got resold.
  • Scope when possible. Multiple keys with limited scopes are safer than one master key. Stripe’s restricted keys, AWS IAM access keys with minimal policies — these are the patterns.

What servers should do with an API key

  • Hash it before storing. A leaked database of plaintext API keys is a breach of every customer. Servers should store sha256(key) and look up by hash, exactly the way they store password hashes (though typically without the deliberate slowness of bcrypt — keys have 128+ bits of entropy, so dictionary attacks are impossible).
  • Show the plaintext key once. When a user creates a key, show it; on every subsequent view, show only a prefix or last-4 characters. If the user loses the key, they regenerate. This is now standard across SaaS platforms.
  • Constant-time comparison on lookup. When verifying a candidate key against the stored hash, compare in constant time to avoid timing attacks. Most modern frameworks have a crypto.timingSafeEqual or equivalent.
  • Log key usage. Per-key request counts and last-seen timestamps make leak detection viable — a key that suddenly fires a million requests from a new IP is detectable in real time.

What an API key isn’t

  • Not a password. It’s longer, machine-typed, and revocable independently of the user account.
  • Not a session token. Sessions are short-lived, tied to a user-agent, and often bear additional context (logged-in-as, MFA status). API keys are generally long-lived and identify the application/integration.
  • Not a JWT. A JWT carries claims and is verifiable without a server lookup. An API key is opaque — the server has to look it up. Both are valid; the choice depends on whether stateless verification is worth the JWT’s complexity. See JWT decoder.
  • Not an OAuth token. OAuth flows produce short-lived access tokens via a delegation handshake. API keys are simpler but require the user to copy-paste secrets, which is more error-prone for end-user integrations.

Common pitfalls

  • Generating keys with weak randomness. Especially in older Node.js code or browser code that defaults to Math.random(). Use crypto.randomBytes or crypto.getRandomValues.
  • Embedding keys in client-side JavaScript. Anything in the browser is visible to the user. “Public” keys (like Stripe’s pk_*) are designed for this; secret keys are not.
  • Checking keys into git. The single most common cause of leaked API keys. Use .env files, secret managers, and git-secrets-style scanners.
  • Reusing keys across environments. A test-environment key that accidentally points at prod is one of the worst possible misconfigurations.

For raw-randomness generators with different shapes, see UUID generator and password generator.