Provider Key Statuses in the Health Checker: A Complete Guide to FreeLLMAPI Key Monitoring

The FreeLLMAPI health checker assigns five possible statuses to provider keys—healthy, invalid, error, rate_limited, and unknown—based on validation results and network conditions.

The health checker in tashfeenahmed/freellmapi continuously monitors API keys to ensure reliable access to language model providers. It stores each key's condition in the api_keys table using the strongly-typed KeyStatus enum defined in shared/types.ts. Understanding these provider key statuses helps developers diagnose authentication failures, network timeouts, and rate-limiting scenarios.

The Five Provider Key Statuses Explained

The KeyStatus type in shared/types.ts defines five distinct states that represent the health of a provider API key.

healthy

A healthy status indicates the key was successfully validated. When the checkKeyHealth function in server/src/services/health.ts executes provider.validateKey and receives true, line 31 sets status: KeyStatus = isValid ? 'healthy' : 'invalid'. This confirms the key is active and authorized for requests.

invalid

The invalid status means the provider rejected the key, typically returning HTTP 401 or 403 responses. This status is set on the same line 31 of health.ts when isValid evaluates to false, indicating expired, revoked, or malformed credentials.

error

An error status indicates transport-level failures such as DNS timeouts, TLS errors, or unreachable endpoints. Unlike invalid, this suggests the key itself may be valid, but the provider was unreachable. The health checker catches these exceptions in lines 50-56 of health.ts and assigns this status before updating the database.

rate_limited

The rate_limited status indicates the key has exceeded provider-enforced request quotas. According to the source code, the health checker does not set this status directly during validation. Instead, other system components populate this value when quota observations detect a limit breach, typically in related services like provider-quota.ts.

unknown

The unknown status serves as a default fallback when a key's health cannot be determined. This occurs with missing data, unexpected responses, or initialization states before the first health check completes.

How the Health Checker Assigns Statuses

The status determination logic resides in server/src/services/health.ts within the checkKeyHealth function. The implementation follows a decision tree:

  1. Validation attempt: The function calls provider.validateKey to test the credential
  2. Boolean mapping: At line 31, a ternary operator maps the boolean result to either healthy or invalid
  3. Exception handling: Lines 50-56 catch network errors and assign error status before persisting to SQLite

The function then updates the api_keys table via server/src/db/index.ts, recording both the status and timestamp for downstream monitoring.

Working with Key Statuses in Practice

Checking a Single Key Programmatically

Import the checkKeyHealth service to validate individual keys on demand:

import { checkKeyHealth } from '@/server/src/services/health';

// Check the health of key ID 42
const status = await checkKeyHealth(42);
console.log(`Key 42 status → ${status}`);
// → "healthy" | "invalid" | "error"

Displaying Status in UI Components

Use the KeyStatus type to render visual indicators:

function KeyStatusBadge({ status }: { status: KeyStatus }) {
  const colors = {
    healthy: 'green',
    invalid: 'red',
    error: 'gray',
    rate_limited: 'orange',
    unknown: 'blue',
  };
  return (
    <span style={{ color: colors[status] }}>
      {status.replace('_', ' ')}
    </span>
  );
}

Manual Database Updates

While rare, you can manually update statuses via the SQLite connection:

import { getDb } from '@/server/src/db/index';

const db = getDb();
db.prepare(
  `UPDATE api_keys SET status = ?, last_checked_at = datetime('now') WHERE id = ?`
).run('rate_limited', 23);

Summary

  • The KeyStatus enum in shared/types.ts defines five possible states: healthy, invalid, error, rate_limited, and unknown
  • healthy and invalid are set at line 31 of server/src/services/health.ts based on boolean validation results
  • error is assigned in the catch block (lines 50-56) when network transport fails
  • rate_limited is populated by external quota monitoring services, not the health checker itself
  • unknown serves as the default state for uninitialized or indeterminate keys

Frequently Asked Questions

What is the difference between invalid and error status?

The invalid status indicates authentication rejection by the provider (401/403 responses), meaning the key is expired or revoked. The error status indicates network transport failures such as DNS timeouts or TLS errors, suggesting the provider was unreachable but the key may still be valid.

Where is the KeyStatus type defined in the FreeLLMAPI codebase?

The KeyStatus type is defined in shared/types.ts at lines 107-108. This central definition ensures type safety across both the health checker service and any UI components consuming the API key data.

How does the health checker handle rate-limited keys?

The health checker does not directly assign the rate_limited status during validation. Instead, it detects validation success or failure, while separate quota monitoring services update the status to rate_limited when they detect provider-side rate limiting.

Can I manually update a provider key's status in the database?

Yes, though this is uncommon. You can manually update statuses using the SQLite connection from server/src/db/index.ts, executing prepared statements against the api_keys table to set specific statuses like rate_limited or unknown when automated detection fails.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →