# How FreeLLMAPI's Health Checker Validates API Keys: A Complete Technical Guide

> Learn how FreeLLMAPI validates API keys by decrypting credentials and performing HTTP requests, ensuring healthy keys by checking upstream service status codes and disabling faulty ones.

- Repository: [Tashfeen/freellmapi](https://github.com/tashfeenahmed/freellmapi)
- Tags: how-to-guide
- Published: 2026-06-30

---

**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`](https://github.com/tashfeenahmed/freellmapi/blob/main/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`](https://github.com/tashfeenahmed/freellmapi/blob/main/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`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/providers/openai-compat.ts) implements this with a 30-second timeout and proper authorization headers:

```typescript
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`](https://github.com/tashfeenahmed/freellmapi/blob/main/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:

```typescript
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 SQLite `api_keys` table.
- Validation requires AES-GCM decryption via `decrypt()` in [`server/src/lib/crypto.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/lib/crypto.ts) before provider-specific HTTP requests are attempted.
- Keys are marked **healthy** only when `validateKey()` returns `true` (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`](https://github.com/tashfeenahmed/freellmapi/blob/main/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`](https://github.com/tashfeenahmed/freellmapi/blob/main/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`](https://github.com/tashfeenahmed/freellmapi/blob/main/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.