Check whether an API key works with curl
Published 2026-10-15 · Updated 2026-10-20
You don’t need to spend a token to find out whether a key is alive. Every provider has a free endpoint, usually the model list, that authenticates the same way as a paid call.
The universal pattern
curl <base_url>/models -H "Authorization: Bearer $KEY"
A 200 means the key is live. A 401 means dead. Everything else is details.
Per provider
OpenRouter
curl https://openrouter.ai/api/v1/auth/key \
-H "Authorization: Bearer $OPENROUTER_API_KEY"
Returns the key’s credit balance and rate limits, better than /models because it tells you how much is left.
OpenAI
curl https://api.openai.com/v1/models \
-H "Authorization: Bearer $OPENAI_API_KEY"
Anthropic: remember, header not bearer:
curl https://api.anthropic.com/v1/models \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01"
Gemini: key in the URL:
curl "https://generativelanguage.googleapis.com/v1beta/models?key=$GEMINI_API_KEY"
DeepSeek: check the balance, not just the model list:
curl https://api.deepseek.com/user/balance \
-H "Authorization: Bearer $DEEPSEEK_API_KEY"
xAI, Mistral, Groq, Cerebras, NVIDIA, Moonshot: all take Bearer against their /models path. Swap in the base URL from the cheat sheet.
The one that costs a token: Perplexity
Perplexity has no free validation endpoint. The smallest probe is a one-token chat call:
curl https://api.perplexity.ai/chat/completions \
-H "Authorization: Bearer $PPLX_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "sonar", "messages": [{"role": "user", "content": "hi"}], "max_tokens": 1}'
A 200 costs a fraction of a cent; a 401 costs nothing.
Reading the response
- 200: key works.
- 401 / 403: dead, revoked, or lacks permission for the endpoint.
- 402 / “insufficient balance”: alive but empty.
- 429: alive but rate-limited. Try again later rather than discarding it.
Checking before you commit to a key saves more time than any other single habit.