# How OmniRoute Handles Image Generation Requests: A Complete Technical Guide

> Discover how OmniRoute handles image generation requests via its unified POST /v1/images/generations endpoint. Learn about its provider-agnostic pipeline and OpenAI-compatible response normalization.

- Repository: [Diego Rodrigues de Sa e Souza/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- Tags: how-to-guide
- Published: 2026-08-29

---

**OmniRoute processes image generation requests through a unified `POST /v1/images/generations` endpoint that routes to multiple providers using a provider-agnostic pipeline with OpenAI-compatible response normalization.**

The OmniRoute open-source proxy implements image generation as a first-class citizen in its API ecosystem. Whether you are routing requests to OpenAI's DALL-E, Google's Gemini, or specialized providers like Fal AI, OmniRoute abstracts provider-specific complexities behind a single, standardized interface. This architecture allows developers to switch between image models without changing client code, while maintaining complete observability and error handling throughout the request lifecycle.

## API Entry Point and Handler Delegation

Image generation requests enter the system through the Next.js API route `POST /v1/images/generations`. This endpoint immediately delegates processing to the dedicated **image-generation handler** located at [`open-sse/handlers/imageGeneration.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/handlers/imageGeneration.ts).

The handler acts as the orchestration layer for the entire pipeline. It receives the incoming request body, extracts critical parameters like the `model` field, and initiates the provider resolution chain. This centralized entry point ensures consistent validation, logging, and error handling regardless of which downstream provider ultimately fulfills the request.

## Provider and Model Resolution

OmniRoute uses a two-stage resolution process to determine where to send the image generation request.

First, the handler extracts the `model` parameter from the request body, which follows the format `provider/model` (e.g., `openai/dall-e-3`). It then invokes `parseImageModel` from [`open-sse/config/imageRegistry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/config/imageRegistry.ts) to resolve the provider ID and model ID. This function handles **model aliases** and **bare-model shortcuts**, allowing flexible client specifications.

If `parseImageModel` encounters an unknown provider or invalid model string, the pipeline terminates immediately with a **400 Invalid image model** error response. This early validation prevents unnecessary downstream calls and provides clear feedback to API consumers.

Once the provider ID is validated, `getImageProvider` retrieves the complete configuration object from the **Image Provider Registry** (`IMAGE_PROVIDERS`) defined in the same file. This configuration includes the `baseUrl`, `authType`, `authHeader`, `format`, and supported model definitions required for the next stage.

## Provider Configuration and Special Case Handling

The image generation pipeline includes specific logic for handling edge cases before dispatching to the provider.

**Retired Providers:** Certain providers like ChatGPT-Web and Microsoft Designer have been retired from the registry. When these provider IDs are detected, the handler short-circuits with a **410 Gone** response, indicating the service is permanently unavailable.

**Custom Nodes:** For custom nodes without built-in provider definitions, OmniRoute synthesizes an **OpenAI-compatible configuration** on the fly. The `resolveImageBaseUrl` function (defined in [`open-sse/handlers/imageGeneration.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/handlers/imageGeneration.ts)) normalizes custom node URLs, automatically appending `/images/generations` when necessary to create a valid endpoint for standard OpenAI-format requests.

## Provider-Specific Generation Handlers

After resolving the provider configuration, the handler branches based on the `providerConfig.format` field to execute the appropriate generator function. Each generator is specialized for its target service's API structure, request payload, and polling mechanisms.

The provider-specific handlers reside in `open-sse/handlers/imageGeneration/providers/` and include:

- **`handleGeminiImageGeneration`**: Processes requests for Antigravity/Gemini models using the `"gemini-image"` format, implementing Google's `generateContent` flow.
- **`handleOpenAIImageGeneration`**: Handles native OpenAI-compatible providers, sending standard JSON payloads to the configured endpoint.
- **`handleKieImageGeneration`**: Manages asynchronous task creation and polling for KIE market/flux-kontext models.
- **`handleFalAIImageGeneration`**: Translates OmniRoute requests into Fal AI's custom endpoint format, handling image-size mapping specific to their API.
- **`handleStabilityAIImageGeneration`**: Routes to Stability AI's generation endpoints with their specific authentication and payload requirements.

Each generator knows the exact request construction, headers, and response parsing logic required for its service, abstracting these differences from the main handler.

## Request Construction and Execution

Within the provider-specific generators, OmniRoute constructs the final HTTP request using several helper utilities.

The system builds request bodies using `buildAgnesImageRequestBody` or direct mapping from the incoming client payload. Authentication headers are injected based on the provider's `authHeader` configuration, supporting variants like `Bearer`, `x-api-key`, or custom header schemes.

For providers that support anonymous access (such as Pollinations), the handler applies **fallback session logic** before dispatching, allowing requests to proceed without explicit credentials when permitted.

## Response Normalization and Error Handling

Regardless of the upstream provider's response format, OmniRoute normalizes all successful outputs to match the **OpenAI image generation specification**:

```json
{
  "created": 1234567890,
  "data": [
    {
      "b64_json": "...",
      "url": "https://...",
      "revised_prompt": "..."
    }
  ]
}

```

Image data may arrive from providers as base64 strings, direct URLs, or raw bytes, but the handler transforms these into the unified structure above. Failed requests return a standardized error object: `{ success: false, status, error }`.

The system records every call via `saveCallLog` (from [`src/lib/usageDb.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/usageDb.ts)) for monitoring and analytics. Raw errors from providers are sanitized through `sanitizeErrorMessage` and `sanitizeImageProviderError` (in [`open-sse/utils/error.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/utils/error.ts)) to strip sensitive details before returning them to clients.

## Implementation Examples

### Client Request to OmniRoute

```typescript
import fetch from 'node-fetch';

await fetch('http://localhost:20128/v1/images/generations', {
  method: 'POST',
  headers: { 
    'Content-Type': 'application/json', 
    Authorization: 'Bearer <your-api-key>' 
  },
  body: JSON.stringify({
    model: 'openai/dall-e-3',
    prompt: 'A futuristic city skyline at sunset',
    size: '1024x1024',
    n: 2,
  })
})
  .then(r => r.json())
  .then(console.log);

```

### Adding a New Image Provider

To extend OmniRoute with a custom provider, modify the `IMAGE_PROVIDERS` registry in [`open-sse/config/imageRegistry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/config/imageRegistry.ts):

```typescript
export const IMAGE_PROVIDERS = {
  // ... existing providers
  myprovider: {
    id: 'myprovider',
    baseUrl: 'https://api.myprovider.com/v1/images/generations',
    authType: 'apikey',
    authHeader: 'bearer',
    format: 'openai',            // Reuse generic OpenAI flow
    models: [{ id: 'my-model-1', name: 'My Model 1' }],
    supportedSizes: ['1024x1024'],
  },
};

```

### Creating a Custom Provider Handler

For providers requiring specialized logic, implement a dedicated handler function:

```typescript
export async function handleMyProviderImageGeneration({
  model, 
  providerConfig, 
  body, 
  credentials, 
  log
}) {
  const token = credentials.apiKey || credentials.accessToken;
  const headers = { 
    'Content-Type': 'application/json', 
    Authorization: `Bearer ${token}` 
  };
  const payload = { 
    model, 
    prompt: body.prompt, 
    size: body.size 
  };
  
  const response = await fetch(providerConfig.baseUrl, { 
    method: 'POST', 
    headers, 
    body: JSON.stringify(payload) 
  });
  
  // Parse provider-specific response and return OpenAI-compatible shape
  const data = await response.json();
  return {
    created: Date.now(),
    data: [{ url: data.image_url }]
  };
}

```

## Summary

- OmniRoute exposes image generation through a unified `POST /v1/images/generations` endpoint that mirrors the OpenAI API specification.
- The `parseImageModel` function in [`open-sse/config/imageRegistry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/config/imageRegistry.ts) resolves provider and model IDs, returning **400 Invalid image model** for unknown configurations.
- Provider-specific handlers in `open-sse/handlers/imageGeneration/providers/` manage the unique request formats for services like Gemini, Fal AI, KIE, and Stability AI.
- The system normalizes all provider responses into the standard OpenAI format and sanitizes errors through `sanitizeErrorMessage` before returning them to clients.
- Custom nodes and retired providers receive specialized handling via `resolveImageBaseUrl` and explicit **410 Gone** responses, respectively.

## Frequently Asked Questions

### How does OmniRoute support multiple image providers simultaneously?

OmniRoute maintains a centralized **Image Provider Registry** (`IMAGE_PROVIDERS` in [`open-sse/config/imageRegistry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/config/imageRegistry.ts)) that defines configuration for each supported service. When a request arrives, the `parseImageModel` function identifies the target provider, and the handler dispatches to a format-specific generator function (e.g., `handleGeminiImageGeneration`, `handleFalAIImageGeneration`). This architecture allows dozens of providers to coexist behind a single API endpoint.

### What happens if an image provider is retired or temporarily unavailable?

If the requested provider is retired (such as ChatGPT-Web or Microsoft Designer), OmniRoute returns a **410 Gone** status code immediately. For transient failures from active providers, the specific generator function handles the error and passes it through `sanitizeImageProviderError` to remove sensitive details before returning a standardized error response to the client.

### How does OmniRoute normalize responses from different image generation APIs?

Each provider-specific generator transforms the raw API response into the OpenAI-compatible format before returning to the main handler. The unified response always includes a `created` timestamp and a `data` array containing objects with `b64_json`, `url`, or `revised_prompt` fields. This normalization occurs in the provider handlers located in `open-sse/handlers/imageGeneration/providers/`, ensuring clients receive consistent data structures regardless of the upstream service.

### Can I add custom image providers to OmniRoute without modifying the core codebase?

Yes. You can add custom providers by extending the `IMAGE_PROVIDERS` registry in [`open-sse/config/imageRegistry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/config/imageRegistry.ts) with a new entry specifying the `baseUrl`, `authType`, and `format`. For providers using the standard OpenAI API format, set `format: 'openai'` and the system will use `handleOpenAIImageGeneration` automatically. For proprietary APIs, you may need to create a new generator function in `open-sse/handlers/imageGeneration/providers/` following the existing handler patterns.