OpenAI 401 “Incorrect API Key Provided” — Complete Fix Guide
The OpenAI 401 error almost always means a key mismatch, whitespace issue, or wrong key type. This guide covers the difference between sk-proj-, sk-org-, and legacy sk- keys, common .env file mistakes, and how to validate a key in under 10 seconds.
The exact error message
A 401 from the OpenAI API returns this JSON body:
{
"error": {
"message": "Incorrect API key provided: sk-abc**. You can find your API key at https://platform.openai.com/account/api-keys.",
"type": "invalid_request_error",
"param": null,
"code": "invalid_api_key"
}
} The key fragment in the message (e.g. sk-abc**) is redacted for security. The error code invalid_api_key is distinct from insufficient_quota (credit exhausted) and rate_limit_exceeded (429). If you get a 401 with code invalid_api_key, the problem is always the key itself, not billing or rate limits.
Step 1 — Know your key type
OpenAI now issues three key formats. Each has a different prefix:
| Prefix | Type | Scope |
|---|---|---|
| sk-proj-... | Project key | Limited to one project’s models, spend limits, and members |
| sk-svcacct-... / sk-org-... | Service account | Organization-level, created for automated workloads |
| sk-... | Legacy user key | Tied to your personal account across all projects |
Step 2 — Check for whitespace in your .env file
The most common silent cause of a 401 is an invisible trailing space or newline after the key in a .env file. The key looks correct visually but the SDK sends sk-abc123\n instead of sk-abc123.
Correct .env format (no quotes, no trailing whitespace):
# Correct
OPENAI_API_KEY=sk-proj-abc123...
# Wrong — quoted values with some parsers add the quotes to the value
OPENAI_API_KEY="sk-proj-abc123..."
# Wrong — trailing space will be included in the value
OPENAI_API_KEY=sk-proj-abc123... Verify what value your process actually sees at runtime:
# Python — print the key length and first/last 4 chars
import os
key = os.environ.get("OPENAI_API_KEY", "")
print(f"Length: {len(key)} | Start: {key[:8]} | End repr: {repr(key[-4:])}") If repr(key[-4:]) shows '...\\n' or '... ', strip the key: key.strip().
Step 3 — Validate the key with /v1/models
The GET /v1/models endpoint is the cheapest way to test a key — it costs no tokens and returns your available models on success:
# Replace YOUR_KEY with the actual key value
curl https://api.openai.com/v1/models \
-H "Authorization: Bearer YOUR_KEY"
# Expected 200 response (valid key):
# { "object": "list", "data": [ { "id": "gpt-4o", ... }, ... ] }
# Expected 401 response (invalid key):
# { "error": { "code": "invalid_api_key", ... } } Same check in Python:
from openai import OpenAI
import os
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
try:
models = client.models.list()
print(f"Key is valid. {len(models.data)} models available.")
except Exception as e:
print(f"Key error: {e}") Step 4 — Organization ID and project billing
If your account belongs to multiple organizations, or you are using a sk-proj- key, you may need to pass the Organization ID and Project ID explicitly. A mismatch produces a 401:
# Python SDK — pass org and project IDs explicitly
from openai import OpenAI
import os
client = OpenAI(
api_key=os.environ["OPENAI_API_KEY"],
organization=os.environ.get("OPENAI_ORG_ID"), # org-...
project=os.environ.get("OPENAI_PROJECT_ID"), # proj_...
) // Node.js SDK
import OpenAI from 'openai';
const client = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
organization: process.env.OPENAI_ORG_ID,
project: process.env.OPENAI_PROJECT_ID,
}); - Find your Organization ID at platform.openai.com/settings/organization/general — it starts with
org-. - Find your Project ID at platform.openai.com/settings — select the project, the ID starts with
proj_. - A
sk-proj-key only works within its own project. If you send a request with aproj_ID that does not match the key’s project, you get a 401.
Revoking and rotating keys safely
If a key was leaked or is no longer needed:
- Go to platform.openai.com/api-keys and click Revoke on the compromised key. Revocation is instant.
- Click Create new secret key and choose the correct project scope.
- Update the key in your environment variables or secrets manager before deploying.
- If the key was committed to git, use git-filter-repo to remove it from history and rotate immediately.
.env to your .gitignore and use environment secrets in CI/CD (GitHub Actions secrets, Vercel env vars, etc.) instead of hardcoding.
Get an email the next time OpenAI goes down
Outage alerts for OpenAI, straight to your inbox. No account needed, unsubscribe in every email.
Watching more than one service? A free account covers 5 services + a daily digest — and Pro is currently free.
FAQ
What is the difference between sk-proj-, sk-org-, and sk- OpenAI API keys?
sk-proj- keys are scoped to one OpenAI project and respect that project’s spend limits and member permissions. sk-org- / sk-svcacct- keys are organization-level service account keys. Legacy sk- keys are user keys with access across all your projects. Use a sk-proj- key for production to limit blast radius if it is leaked.
Why does my OpenAI API key give 401 Incorrect API key provided?
Most often: (1) the key was deleted or expired — check platform.openai.com/api-keys; (2) trailing whitespace in the .env file; (3) using the wrong key type for the project/organization; (4) free trial credit ran out and the key was deactivated automatically.
How do I check if my OpenAI API key is valid without making a paid API call?
Call GET /v1/models: curl https://api.openai.com/v1/models -H "Authorization: Bearer YOUR_KEY". A 200 response means the key is active. A 401 with code invalid_api_key means the key is invalid or revoked.
Do I need an Organization ID to use the OpenAI API?
Not for most personal accounts. The Organization ID (org-...) is optional unless you belong to multiple organizations or are using org-scoped endpoints. If you set the wrong OPENAI_ORG_ID, it causes a 401 even with a valid key.