# How to Configure Image Generation and Text-to-Speech Endpoints in FreeLLMAPI

> Configure FreeLLMAPI for image generation and text-to-speech. Learn to set up provider rows and environment variables for OpenAI-compatible endpoints and automatic fallback.

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

---

**Configure FreeLLMAPI's generative-media endpoints by inserting provider rows into the `media_models` database table and setting encrypted platform keys via environment variables, which enables OpenAI-compatible image generation at `/v1/images/generations` and text-to-speech at `/v1/audio/speech` with automatic provider fallback.**

FreeLLMAPI treats image generation and text-to-speech (TTS) as standalone **generative-media** services that operate outside the standard chat-completion pipeline. According to the `tashfeenahmed/freellmapi` source code, these capabilities are orchestrated through a media catalogue system defined in [`server/src/services/media.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/media.ts) that manages provider adapters, encrypted API keys, and intelligent request routing via [`server/src/routes/proxy.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/routes/proxy.ts).

## Architecture Overview

The media subsystem consists of four interconnected components that handle provider abstraction and request routing.

**Media Catalogue.** A database table called `media_models` stores every available provider-model capable of generating images or audio. Only rows with `enabled = 1` are exposed through the API. The catalogue API is defined in [`media.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/media.ts) (lines 1-11) through functions like `listMediaModels` and `listAllMediaModels`.

**Platform Keys.** The system retrieves encrypted API keys via `getPlatformKey()` in [`media.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/media.ts) (lines 18-20). Keys are decrypted at request time from the `api_keys` table. Pollinations is the only provider listed in `KEYLESS_CAPABLE` that requires no authentication.

**Request Routing.** HTTP routes `/v1/images/generations` and `/v1/audio/speech` in [`proxy.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/proxy.ts) (lines 448-497) forward requests to the media catalogue, select the highest-priority enabled model for the requested modality, and invoke the concrete provider adapter (`callImageProvider` or `callSpeechProvider`).

**Provider Adapters.** A `switch` statement in [`media.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/media.ts) (lines 173-200) implements platform-specific adapters for `nvidia`, `pollinations`, `cloudflare`, `siliconflow`, and `google`. These adapters normalize external HTTP responses into OpenAI-compatible formats (`b64_json` for images, raw audio bytes for speech).

## Step 1: Register Media Models in the Database

Before using the endpoints, you must populate the `media_models` table with enabled providers. The server loads these into memory via the catalog-sync service ([`server/src/services/catalog-sync.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/catalog-sync.ts)) and refreshes automatically after changes.

### Image Generation Model

Insert a row specifying `modality: 'image'` and a supported platform. This example configures NVIDIA's Flux 1-Schnell model:

```sql
INSERT INTO media_models
  (platform, model_id, display_name, modality, priority, enabled, quota_label)
VALUES
  ('nvidia', 'black-forest-labs/flux.1-schnell', 'Flux 1‑Schnell', 'image', 1, 1, 'free');

```

### Text-to-Speech Model

Insert a row with `modality: 'audio'` to enable TTS. This example configures SiliconFlow:

```sql
INSERT INTO media_models
  (platform, model_id, display_name, modality, priority, enabled, quota_label)
VALUES
  ('siliconflow', 'speech-tts', 'SiliconFlow TTS', 'audio', 1, 1, 'free');

```

## Step 2: Configure Platform API Keys

Most providers require authentication. Set environment variables in your `.env` file following the convention `LLMAPI_<PLATFORM>_KEY`. The startup script in [`server/src/env.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/env.ts) encrypts these values and stores them in the `api_keys` table.

```dotenv
LLMAPI_NVIDIA_KEY=sk‑your‑nvidia‑api‑key
LLMAPI_SILICONFLOW_KEY=sk‑your‑siliconflow‑key
LLMAPI_CLOUDFLARE_KEY=your‑cloudflare‑token

```

**Note:** Pollinations is the only provider that does not require a key. The `KEYLESS_CAPABLE` constant in [`media.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/media.ts) explicitly excludes it from the key lookup logic.

## Step 3: Verify Endpoint Routing

Once the database and environment are configured, the OpenAI-compatible endpoints become active. The routing logic in [`proxy.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/proxy.ts) (lines 448-497) validates the request, queries the media catalogue for the highest-priority enabled model matching the requested modality, and executes the appropriate provider adapter.

## Making API Requests

Both endpoints return standard OpenAI-compatible response shapes and support provider fallback if `MediaError` is thrown (as implemented in [`media.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/media.ts) lines 34-41).

### Image Generation

POST to `/v1/images/generations` with a JSON body describing the prompt and dimensions:

```bash
curl -X POST https://your‑host/v1/images/generations \
  -H "Authorization: Bearer $FREE_LLMAPI_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
        "prompt": "A cyber‑punk city at night, neon lights",
        "n": 1,
        "size": "1024x1024"
      }'

```

The response returns a Unix timestamp and a base64-encoded PNG:

```json
{
  "created": 1699999999,
  "data": [{ "b64_json": "<base64‑png>" }]
}

```

### Text-to-Speech

POST to `/v1/audio/speech` with the input text and desired voice:

```bash
curl -X POST https://your‑host/v1/audio/speech \
  -H "Authorization: Bearer $FREE_LLMAPI_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
        "input": "Hello, this is a test of Free LLMAPI TTS.",
        "voice": "Kore",
        "format": "wav"
      }' \
  --output hello.wav

```

The proxy streams raw audio bytes with `Content-Type: audio/wav` headers.

## Provider Adapters and Error Handling

The `switch` block in [`media.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/media.ts) (lines 173-200) handles platform-specific request construction. If a provider returns an HTTP error, the `MediaError` class (lines 34-41) captures the status and message, triggering the router to fall back to the next enabled provider in the priority cascade. If all providers fail, the endpoint returns a 502 or 500 with the final error message.

## Summary

- **Database Configuration:** Insert provider rows into `media_models` with `modality` set to `image` or `audio` and `enabled` set to `1`.
- **Authentication:** Set `LLMAPI_<PLATFORM>_KEY` environment variables for all providers except Pollinations.
- **Endpoints:** Use `/v1/images/generations` for base64-encoded images and `/v1/audio/speech` for raw audio streams.
- **Resilience:** The system automatically retries with fallback providers on `MediaError` and propagates clear error messages when the cascade exhausts.

## Frequently Asked Questions

### Which providers do not require an API key in FreeLLMAPI?

Pollinations is the only provider exempt from authentication. The `KEYLESS_CAPABLE` constant in [`server/src/services/media.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/media.ts) excludes it from the encrypted key lookup performed by `getPlatformKey()`. All other providers (NVIDIA, SiliconFlow, Google, Cloudflare) require a valid `LLMAPI_<PLATFORM>_KEY` environment variable.

### How does FreeLLMAPI handle provider failures?

When a provider adapter throws `MediaError` (defined in [`media.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/media.ts) lines 34-41), the router in [`proxy.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/proxy.ts) catches the exception and attempts the next highest-priority enabled model for that modality. This cascade continues until a provider succeeds or the list is exhausted, at which point the endpoint returns a 502 Bad Gateway with the final error details.

### What response format does the image generation endpoint return?

The `/v1/images/generations` endpoint returns a JSON object matching the OpenAI specification, containing a `created` timestamp and a `data` array where each element includes a `b64_json` field holding the base64-encoded PNG image. Provider adapters in [`media.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/media.ts) normalize external responses into this format before returning to the client.

### How often does the media catalogue sync with the database?

The catalogue sync service ([`server/src/services/catalog-sync.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/catalog-sync.ts)) refreshes the in-memory model list automatically after startup and detects database changes. You do not need to restart the server after inserting new rows into `media_models` or updating the `enabled` status, though changes to environment variables require a restart to trigger re-encryption in [`server/src/env.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/env.ts).