# How FreeLLMAPI Catalog Sync Updates Model Information: A Technical Deep Dive

> Discover how FreeLLMAPI catalog sync automatically updates model information every 12 hours, ensuring accurate metadata and availability while safeguarding your custom configurations.

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

---

**FreeLLMAPI automatically synchronizes its local SQLite model database with a cryptographically signed remote catalog every 12 hours, updating model metadata and availability flags while preserving user overrides and custom configurations.**

The `tashfeenahmed/freellmapi` repository maintains an up-to-date registry of AI models through a sophisticated catalog synchronization system. This process ensures that the routing layer always has accurate information about which models can serve incoming requests, while maintaining security through cryptographic verification. Understanding how the FreeLLMAPI catalog sync updates model information is essential for operators managing self-hosted instances or integrating with premium model providers.

## The Three-Stage Catalog Sync Architecture

The update flow operates as a pipeline with distinct responsibilities: remote fetching, local persistence, and runtime availability calculation.

### Fetching and Verifying the Remote Catalog

The synchronization initiates in [`server/src/services/catalog-sync.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/catalog-sync.ts) through the `startCatalogSync` function. This scheduler registers two execution paths: an initial boot-delay run and a repeated interval governed by `SYNC_INTERVAL_MS = 12h`.

The `syncCatalog()` function constructs a request to the `/v1/latest` endpoint, appending a *Bearer* token when a premium license key is configured. The request includes a timeout defined by `FETCH_TIMEOUT_MS`. Upon receiving the response, the system validates the `x-catalog-signature` header by verifying the raw response body against a hard-coded Ed25519 public key retrieved via `catalogPublicKey()`. If cryptographic verification fails, the entire catalog payload is discarded to prevent tampering.

### Applying Updates to the Local Database

Once verified, the `applyCatalog()` function processes the incoming `CatalogModel` entries. This stage differentiates between chat models and media generation models by inspecting the `modality` field against `MEDIA_MODALITIES`, routing entries to either the `models` or `media_models` SQLite tables.

For each entry, the system performs an **upsert** operation:

- **Updates** existing rows while preserving the local `enabled` flag unless the catalog explicitly disables the model
- **Inserts** new rows for models not yet present in the local database
- **Skips** entries where `platform === 'custom'` or where local tombstone overrides exist

After processing all catalog entries, the function performs garbage collection by deleting models removed from the remote catalog, clearing tombstoned rows, and refreshing user-provided overrides through `applyAllModelOverrides`.

### Deriving Runtime Availability for Routing

The final stage occurs in [`server/src/services/model-listing.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/model-listing.ts) within the `buildModelListing()` function. Rather than directly querying the `enabled` column, the system computes a dynamic `available` flag using a SQL expression that joins against the `api_keys` table:

```sql
(CASE WHEN m.enabled = 1 AND EXISTS (
     SELECT 1 FROM api_keys k
     WHERE k.platform = m.platform
       AND k.enabled = 1
       AND (m.key_id IS NULL OR k.id = m.key_id)
) THEN 1 ELSE 0 END)

```

This expression evaluates to **1** only when the model is catalog-enabled **and** an active API key exists for its platform. The resulting availability flag drives the `GET /v1/models` endpoint exposed by [`server/src/services/router.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/router.ts) and determines the "auto" context-window ceiling calculations.

## Implementation Details and Code Examples

### Initializing Background Synchronization

To start the automatic catalog refresh at server startup:

```typescript
import { startCatalogSync } from './services/catalog-sync.js';
import { Scheduler } from './lib/scheduler.js';

const scheduler = new Scheduler();
startCatalogSync(scheduler);

```

### Triggering Manual Catalog Updates

For on-demand synchronization, such as after adding a premium license key:

```typescript
import { syncCatalog } from './services/catalog-sync.js';

async function refreshCatalog() {
  const result = await syncCatalog(true); // force = true bypasses the `since` short-circuit
  console.log('Catalog refresh result:', result);
}

```

### Querying Available Models

The routing layer consumes the catalog state through the listing service:

```typescript
import { buildModelListing } from './services/model-listing.js';

function listModels() {
  const { models, autoContextWindow } = buildModelListing();
  console.log('Available models:', models);
  console.log('Auto context window:', autoContextWindow);
}

```

## Database State and Override Management

The [`server/src/services/model-state.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/model-state.ts) module maintains the integrity between catalog-managed and user-configured settings. Custom models added directly by users remain untouched during sync operations, while tombstone markers allow administrators to suppress specific catalog models permanently. The `enabled` column serves as the bridge between the catalog sync process (which writes it) and the model listing logic (which reads it alongside API key validity).

## Summary

- **FreeLLMAPI catalog sync** runs automatically every 12 hours via `startCatalogSync` in [`catalog-sync.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/catalog-sync.ts), with optional on-demand execution through `syncCatalog(true)`.
- **Cryptographic verification** using Ed25519 signatures ensures the remote catalog at `/v1/latest` has not been tampered with before local application.
- **Dual-table architecture** separates chat models (`models` table) from media models (`media_models` table) based on the `modality` field.
- **Availability calculation** combines the catalog's `enabled` flag with active API key presence, computed dynamically in `buildModelListing()` within [`model-listing.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/model-listing.ts).
- **User overrides** and custom platform models are preserved during sync operations, allowing local configuration to persist across catalog updates.

## Frequently Asked Questions

### How often does FreeLLMAPI synchronize the model catalog?

The system schedules automatic synchronization every 12 hours using the `SYNC_INTERVAL_MS` constant, with an initial delay at server startup. Administrators can trigger additional updates manually by calling `syncCatalog(true)` to bypass the incremental `since` parameter check.

### What happens if the remote catalog signature verification fails?

If the `x-catalog-signature` header cannot be verified against the hard-coded Ed25519 public key in `catalogPublicKey()`, the entire catalog payload is rejected. The local database retains its previous state, ensuring that corrupted or malicious catalog data never affects the available model list.

### Can I prevent specific catalog models from appearing in my instance?

Yes. The system respects tombstone markers and custom platform designations. Models marked as `platform === 'custom'` or those with local override entries in the database are excluded from catalog sync updates, allowing administrators to suppress unwanted models permanently.

### Why are some models disabled despite being present in the latest catalog?

A model appears unavailable when either the catalog sets `enabled = 0` or when no active API key exists for the model's platform. The SQL availability expression in [`model-listing.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/model-listing.ts) requires both conditions—catalog enablement and valid API key presence—to mark a model as available for routing.