How FreeLLMAPI's Health Checker Validates API Keys: A Complete Technical Guide
The FreeLLMAPI health checker validates API keys by decrypting stored credentials and executing provider-specific HTTP requests, marking keys as healthy only when upstream services return non-401/403 status codes, while automatically disabling keys after three consecutive authentication failures.
The tashfeenahmed/freellmapi repository implements a robust background validation system to ensure API keys remain functional across multiple LLM providers. Understanding how FreeLLMAPI's health checker determines API key validity is essential for operators managing large key pools, as it directly impacts request routing reliability and cost optimization.
The Health Check Lifecycle
The validation process runs continuously through a scheduled background service that evaluates every enabled key stored in the SQLite database.
Scheduler Initialization and Frequency
When the server boots, startHealthChecker() in server/src/services/health.ts registers a recurring job with the Scheduler abstraction. This job executes every five minutes, triggering the validation pipeline for all active credentials where enabled = 1.
Key Retrieval and Decryption
The checkAllKeys() function queries the api_keys table to fetch enabled keys. Before any network validation occurs, the system invokes decrypt() from server/src/lib/crypto.ts to decrypt the AES-GCM encrypted key material, ensuring plaintext credentials never persist in memory longer than necessary.
Provider-Specific Validation Logic
After decryption, the health service delegates validation to the appropriate provider implementation through a unified interface defined in the base provider class.
The validateKey Contract
The resolveProvider function selects the correct provider based on the key's platform and base URL. Each provider implements the validateKey() method, receiving the decrypted API key and a quota context containing the platform identifier and key ID. This context allows providers to track usage during validation requests.
HTTP Validation Pattern
Most providers perform lightweight validation by sending a GET request to an endpoint like /v1/models. The OpenAI-compatible provider in server/src/providers/openai-compat.ts implements this with a 30-second timeout and proper authorization headers:
async validateKey(apiKey: string): Promise<boolean> {
const res = await fetch(`${this.baseUrl}/models`, {
method: 'GET',
headers: this.authHeader(apiKey),
signal: AbortSignal.timeout(30000)
});
return res.status !== 401 && res.status !== 403;
}
This pattern treats any authentication or authorization error as a definitive invalid state, while accepting rate limits (429) or server errors (5xx) as evidence that the key itself is structurally valid.
Response Interpretation and Status Mapping
The health checker in server/src/services/health.ts categorizes validation results into three distinct states based on the provider's return value and exceptions.
Healthy Status: When validateKey() returns true, indicating the upstream service accepted the credentials with a non-401/403 status, the checker records healthy and clears any existing failure counters for that key.
Invalid Status: If the provider returns false after receiving an explicit 401 Unauthorized or 403 Forbidden response, the system updates the database status to invalid and increments a per-key failure counter.
Error Status: Transport-level failures—such as DNS timeouts or TLS handshake errors—cause validateKey() to throw exceptions. The catch block logs these as error status but crucially does not increment the failure counter, ensuring network instability does not penalize key validity.
Auto-Disable Mechanism for Invalid Keys
The system implements protective automation to prevent routing requests to compromised or expired credentials. When a key accumulates three consecutive invalid results, the checkKeyHealth() function automatically sets enabled = 0 in the api_keys table, effectively removing it from the active rotation pool without manual intervention.
Debugging and Manual Validation
Operators can trigger ad-hoc validation outside the five-minute cycle for troubleshooting specific credentials:
import { checkKeyHealth } from './services/health';
async function debugKey(keyId: number) {
const status = await checkKeyHealth(keyId);
console.log(`Key ${keyId} health status: ${status}`);
}
This invokes the same decryption and validation pipeline used by the background scheduler, ensuring consistent behavior between manual checks and automated monitoring.
Summary
- The FreeLLMAPI health checker runs every five minutes via
startHealthChecker()to validate all enabled keys in the SQLiteapi_keystable. - Validation requires AES-GCM decryption via
decrypt()inserver/src/lib/crypto.tsbefore provider-specific HTTP requests are attempted. - Keys are marked healthy only when
validateKey()returnstrue(non-401/403 responses), while explicit authentication failures mark them invalid. - Transport errors result in error status without incrementing the failure counter, distinguishing between temporary network issues and actual credential problems.
- Three consecutive invalid results trigger automatic disabling via the failure counter logic in
checkKeyHealth().
Frequently Asked Questions
How often does FreeLLMAPI check API key validity?
The health checker registers a recurring job via the Scheduler abstraction that executes every five minutes, validating every enabled key in the api_keys table by decrypting credentials and executing provider-specific validation requests.
What happens if an API key returns a 429 Rate Limit error during validation?
Rate limit responses (429) or server errors (5xx) do not mark a key as invalid. The validateKey() method in server/src/providers/openai-compat.ts only returns false for 401 or 403 status codes, so transient upstream issues preserve the key's healthy status while temporary blocks do not trigger the auto-disable counter.
Why does the failure counter only increment on 401/403 responses?
The failure counter logic in server/src/services/health.ts specifically targets authentication failures to avoid disabling valid keys during network instability. Transport errors caught in the exception handler set status to error but skip the increment operation, ensuring only confirmed invalid credentials trigger automatic disabling after three consecutive failures.
Can I manually validate a single API key without waiting for the scheduler?
Yes. Import checkKeyHealth from server/src/services/health.ts and pass the numeric key ID to execute the full validation pipeline—including AES-GCM decryption and provider-specific HTTP checks—immediately outside the standard five-minute cycle.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →