OpenAI API Key Format (sk-proj, sk-svcacct, sk-admin): Anatomy & Security
An OpenAI API key is the second most common secret we see mishandled after the classic .env leak of a wallet mnemonic — and the failure modes are identical. Both are long, high-entropy bearer credentials. Both grant everything the moment they leak: a wallet in one case, a billing account and every model behind it in the other. And both get pasted into config files as if they were ordinary strings. This article breaks down the exact format of every OpenAI key type — sk-proj-, sk-svcacct-, sk-admin- and the legacy bare sk- — and how to generate, validate and store one with the same discipline you already apply to a seed phrase. It is the companion piece to our breakdown of the Anthropic API key format.
The Four Prefixes at a Glance
OpenAI has issued four kinds of secret keys over the years, and the prefix tells you exactly what you are holding:
sk-proj-…— a project key, the default since mid-2024. It is scoped to a single project inside your organisation, can carry restricted permissions, and is what you get today when you click “Create new secret key”.sk-svcacct-…— a service-account key. It belongs to a machine identity inside a project rather than to a human user, which is what you want for production servers and CI: the key survives when an employee leaves the org.sk-admin-…— an admin key for the organisation-management API (creating projects, managing users, reading audit logs). It deliberately cannot call the model endpoints — a separation of duties, not an inconvenience.sk-…(nothing aftersk-) — the legacy user key format. These 51-character keys were tied to a personal account across all projects and are no longer issued; existing ones still work until rotated away.
If a tutorial tells you an OpenAI key “looks like sk- plus 48 characters”, the tutorial predates 2024. Modern keys are much longer and always carry a scope tag after sk-.
Anatomy of a Key
A modern project key looks like this:
sk-proj-AAAAAAAAAAAAAAAAAAAA...T3BlbkFJ...BBBBBBBBBBBBBBBBBBBB
Read left to right:
sk— “secret key”, the industry convention that also opens Anthropic and Stripe secrets. It marks the string as a private credential, never a publishable identifier.proj/svcacct/admin— the scope: which kind of principal the key authenticates as.- The body — roughly 150 characters of random
base64url-style data (A–Z a–z 0–9 - _), bringing a project key to about 164 characters in total.
One charming fossil survives inside the randomness: most OpenAI keys embed the marker T3BlbkFJ somewhere in the body — which is simply OpenAI in base64. Secret-scanning tools have keyed on that substring for years, and it is the fastest way to recognise an OpenAI credential in a leaked log file.
“A high-entropy secret with no checksum behaves exactly like a private key: there is no ‘invalid’ state, only ‘works’ and ‘does not work yet’.”
As with an Anthropic key — and unlike a BIP39 mnemonic, whose final word encodes a checksum — there is no checksum. Truncate the key while copying and nothing warns you; you simply get a 401 at request time with no hint whether the key was mistyped, revoked, or never real. Copy it whole, or not at all.
How to Generate One
To create a project key:
- Sign in at
platform.openai.com. - Pick the project the key should belong to (top-left project switcher).
- Open Dashboard → API keys and click Create new secret key.
- Give it a descriptive name (
prod-backend,ci-tests), choose the owner — you or a service account — and optionally restrict permissions to read-only or specific endpoints. - Copy the key immediately. The full value is shown exactly once; after you close the dialog only a masked preview remains.
That “shown once” behaviour is the single most important parallel to crypto key management: the moment of creation is the only moment you can back it up safely. Treat the copy step like writing down a 24-word phrase.
Admin keys live elsewhere — under organisation settings, available only to org owners — precisely so that day-to-day project work never touches them.
Validating a Key Locally
Two cheap checks before anything ships:
1. Shape check with a regex — confirm the string at least looks like an OpenAI key before sending it anywhere:
^sk-(proj|svcacct|admin)-[A-Za-z0-9_-]{40,}$
(or ^sk-[A-Za-z0-9]{48}$ for a legacy key).
2. Live check with the cheapest authenticated call — listing models costs nothing and confirms the key is alive:
curl https://api.openai.com/v1/models \
-H "Authorization: Bearer $OPENAI_API_KEY"
A 200 with a JSON list means the key is valid. A 401 means it is wrong or revoked; a 429 with an insufficient_quota message means the key is fine but the account has no credit.
Note the header: OpenAI wants Authorization: Bearer, while Anthropic uses x-api-key. Swapping the two is one of the most common “the key is definitely correct but nothing works” mistakes when a codebase talks to both providers.
Treat the Key Like a Seed Phrase
The mental model that keeps a BIP39 mnemonic safe is the same one that keeps an API key safe — a high-value bearer secret with no recovery once it leaks. If you have read our breakdown of what happens when a seed phrase is compromised, the failure modes below will look identical.
- Never commit it to source control. A hard-coded key pushed to a public repo is scraped within minutes. OpenAI participates in GitHub secret scanning and will often auto-revoke a leaked key and email you — helpful, but by then the string has already been copied by bots.
- Use environment variables or a secrets manager, never inline literals. Vault, AWS Secrets Manager, Doppler, or an OS keychain all beat plaintext in a config file.
- Scope keys per environment and per service. One project key for production, another for staging, a service-account key for each deployed system. A leak then burns one environment, not the whole organisation — the same logic as separating hot and cold wallets. The same pattern applies to exchange API keys.
- Set usage limits and watch the dashboard. Per-project budgets and alerts turn a leak from an unbounded bill into a capped one, and an unexpected spike is your earliest warning — exactly like an unexpected outgoing transaction from a wallet.
- Rotate on any suspicion. Revoking and reissuing takes seconds and breaks nothing that reads its key from the environment. When in doubt, rotate.
“You cannot un-leak a secret. The only real defences are isolation, monitoring, and fast rotation — for an API key exactly as for a private key.”
OpenAI API Key Frequently Asked Questions
Q1: What does the sk-proj- prefix mean?
sk marks the string as a secret key and proj says it is scoped to a single project inside your organisation. Project keys are the default since mid-2024 and replace the old account-wide sk- user keys, so a leaked key exposes one project rather than everything you own.
Q2: What is the difference between sk-proj, sk-svcacct, and sk-admin?
sk-proj keys belong to a human user within a project. sk-svcacct keys belong to a service account — a machine identity that survives staff changes, ideal for servers and CI. sk-admin keys drive the organisation-management API only and cannot call models at all. For production model traffic you almost always want a service-account key.
Q3: How long is an OpenAI API key, and does it have a checksum?
A modern project key is about 164 characters: the sk-proj- prefix plus roughly 150 characters of random base64url data, usually containing the T3BlbkFJ marker (base64 for “OpenAI”). Legacy keys were 51 characters. Neither format has a checksum — a single mistyped character just produces a 401, so always copy the key whole.
Q4: I lost my key — can I recover it?
No. The full value is shown only once, at creation, and afterwards only a masked preview exists. Revoke the lost key on the API-keys page and create a new one — revocation is instant and free, so rotating is painless.
Q5: My key returns a 401 error. What should I check?
In order: confirm you copied the whole string with no stray whitespace; make sure you send it as Authorization: Bearer … (not x-api-key, which is Anthropic’s header); check the key was not auto-revoked after a leak — OpenAI does this when a key appears in a public repo; verify you are calling from the right project; and if in doubt, rotate and retry with a fresh key.
Conclusion
The OpenAI key format is self-describing by design: sk for secret, a scope tag that tells you the blast radius, and ~150 characters of raw entropy with no checksum. That simplicity is also the warning — nothing about the string protects you once it escapes, and bots watch public repos precisely because these keys are worth money. If you already think in seed-phrase terms, you have everything you need: copy it once, store it like a secret, scope it narrowly, cap its spend, and rotate the instant something feels off. Handle your OpenAI keys with the same care you give a private key, and the format will never be the part that fails you.