How to Create and Use Custom Model Profiles in FreeLLMAPI: A Complete Guide

FreeLLMAPI lets you group models into prioritized fallback chains called profiles, allowing you to switch active model configurations on-the-fly without changing client code.

Custom model profiles in FreeLLMAPI provide a powerful way to organize your LLM infrastructure. By creating and using custom model profiles, you can define which models serve requests and in what priority order, enabling different configurations for different projects or user groups while maintaining a single OpenAI-compatible endpoint.

Understanding Model Profiles in FreeLLMAPI

A model profile (also referred to as a fallback chain) defines the order and enabled/disabled state of models that will be queried when a request does not specify a particular model. According to the FreeLLMAPI source code, profiles are stored in a SQLite database with two core tables: profiles and profile_models, which maintain a many-to-many relationship between profiles and models while tracking priority and enabled flags.

The system offers three key advantages:

  • Prioritize models for specific projects or user groups by assigning priority values (1 = highest priority)
  • Enable or disable models dynamically without removing them from the catalog
  • Switch configurations instantly by changing the active profile, allowing the same client code to automatically use different model sets

Creating a Custom Model Profile

Creating a profile involves two steps: first creating the profile container, then populating it with models and their configurations.

Step 1: Create the Profile Container

Use the REST API to create a new profile with a descriptive name:

curl -X POST https://your-llmapi.com/api/profiles \
     -H "Content-Type: application/json" \
     -d '{"name":"research-team"}'

This returns a profile ID (e.g., 3) that you will use in subsequent operations.

Step 2: Add Models to the Profile

Populate the profile using the PATCH /api/profiles/:id/models endpoint. In server/src/routes/profiles.ts, this endpoint handles the models array where each entry requires a modelId, priority (integer), and enabled boolean:

curl -X PATCH https://your-llmapi.com/api/profiles/3/models \
     -H "Content-Type: application/json" \
     -d '{
           "models": [
             {"modelId":"openrouter:gpt-4o","priority":1,"enabled":true},
             {"modelId":"groq:mixtral-8x7b-32768","priority":2,"enabled":true},
             {"modelId":"huggingface:bert-base-uncased","priority":3,"enabled":false}
           ]
         }'

The priority field determines selection order—lower numbers indicate higher priority. The enabled flag controls whether a model is eligible for selection without removing it from the profile.

Activating and Switching Profiles

Once created, a profile must be activated to affect routing decisions. The server/src/services/profile-models.ts file contains the getActiveProfileId function, which reads the current active profile from the settings table.

To activate a profile:

curl -X POST https://your-llmapi.com/api/profiles/active \
     -H "Content-Type: application/json" \
     -d '{"profileId":3}'

To revert to the global fallback chain (disabling profile-specific routing):

curl -X POST https://your-llmapi.com/api/profiles/active \
     -H "Content-Type: application/json" \
     -d '{"profileId":null}'

When a profile is active, the router automatically limits model selection to enabled entries of that profile, respecting the defined priority order on every request.

Using Profiles in Client Applications

From the client perspective, no code changes are required to use custom model profiles. Client applications continue using the standard OpenAI-compatible endpoint. To utilize the active profile, specify "model": "auto" in your request:

import requests

resp = requests.post(
    "https://your-llmapi.com/v1/chat/completions",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={
        "model": "auto",
        "messages": [{"role": "user", "content": "Explain quantum tunnelling"}],
        "max_tokens": 200
    }
)
print(resp.json())

When "auto" is specified, the router checks for an active profile via getActiveProfileId. If a profile exists, the query joins against the profile_models table to select the first enabled model according to priority. If no profile is active, "auto" falls back to the global chain (all enabled models in the catalog).

Updating Profiles on the Fly

You can modify profile composition dynamically without restarting the server. The PATCH /api/profiles/:id/models endpoint accepts partial updates, allowing you to enable previously disabled models or reprioritize entries:

curl -X PATCH https://your-llmapi.com/api/profiles/3/models \
     -H "Content-Type: application/json" \
     -d '{"models":[{"modelId":"huggingface:bert-base-uncased","priority":3,"enabled":true}]}'

The router picks up these changes immediately because server/src/services/router.ts reads the profile_models table on every request, ensuring zero-downtime configuration changes.

Core Implementation Details

Understanding the underlying architecture helps troubleshoot and extend profile functionality.

Database Layer (profile-models.ts)

The server/src/services/profile-models.ts file provides critical helper functions:

  • getActiveProfileId: Queries the settings table to retrieve the currently active profile identifier
  • ensureModelInProfiles: Guarantees that newly-added models appear in all auto-include profiles
  • ensureAllModelsInProfiles: Bulk-adds missing models to maintain profile integrity

These functions ensure data consistency between the model catalog and profile definitions.

REST API Endpoints (profiles.ts)

The server/src/routes/profiles.ts Express router exposes these endpoints:

  • GET /api/profiles – List all available profiles
  • GET /api/profiles/active – Fetch the currently active profile
  • POST /api/profiles/active – Set or clear the active profile
  • GET /api/profiles/:id/models – Read a profile's model configuration
  • PATCH /api/profiles/:id/models – Reorder, enable, or disable models within a profile

Request Routing Integration

In server/src/services/router.ts, the request routing logic integrates profile selection by checking getActiveProfileId at request time. When a profile is active, the router performs a SQL join against profile_models to filter and sort eligible models before making the upstream LLM request.

Summary

  • Custom model profiles in FreeLLMAPI let you define prioritized, enabled/disabled model groups without modifying client code
  • Create profiles via POST /api/profiles and populate them using PATCH /api/profiles/:id/models with priority values and enabled flags
  • Activate profiles through POST /api/profiles/active; use null to revert to global fallback behavior
  • Client applications use "model": "auto" to automatically respect the active profile's configuration
  • Changes to profiles take effect immediately as the router reads the database on each request

Frequently Asked Questions

What happens if I request a specific model while a profile is active?

When you specify an explicit model ID (not "auto"), FreeLLMAPI routes directly to that specific model, bypassing the active profile logic entirely. Profiles only affect routing when "auto" is specified or when the request does not include a model parameter.

How does the priority system work when multiple models have the same priority?

According to the implementation in server/src/services/profile-models.ts, the router selects the model with the lowest priority number (highest precedence). If multiple models share the same priority value, the database query order determines selection, though you should assign unique priority values for predictable behavior.

Can I use profiles to implement user-specific model access?

Yes. Since the active profile is stored server-side in the settings table, you can build middleware that calls POST /api/profiles/active to switch profiles based on authentication tokens or API keys before processing requests. This allows per-user or per-team model customization without client-side changes.

Do I need to restart the server after creating or updating a profile?

No. All profile operations are dynamic. The server/src/services/router.ts implementation queries the profile_models table on every request, meaning changes via PATCH /api/profiles/:id/models or activation changes via POST /api/profiles/active take effect immediately without service interruption.

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 →