# How OmniRoute Handles API Format Translation Between LLM Providers

> OmniRoute seamlessly translates API formats between LLM providers. Discover how its three-layer translator subsystem ensures smooth communication and data compatibility.

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

---

**TLDR:** OmniRoute normalizes heterogeneous LLM provider schemas through a three-layer translator subsystem that converts OpenAI-compatible requests into provider-specific formats (and vice versa) using a bi-directional registry, lazy-loaded modules, and shared transformation helpers.

OmniRoute acts as a universal gateway for large language model APIs by implementing a robust **API format translation** layer that bridges the gap between OpenAI's ubiquitous schema and the diverse request/response formats used by providers like Claude, Gemini, and Antigravity. As implemented in the `diegosouzapw/OmniRoute` repository, this system enables a single client-facing endpoint to route requests across 268+ backends without requiring provider-specific client code. The translation pipeline is architecturally split into three discrete layers: a central format registry, request transformation logic, and response stream normalization.

## The Three-Layer Translation Architecture

OmniRoute's translator subsystem organizes cross-provider communication into distinct responsibilities managed through specific source files:

- **Format Registry** – Located in [`open-sse/translator/registry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/registry.ts), this maintains a bi-directional map of `source → target` translator factories for all supported providers.
- **Request Translation** – Modules like [`open-sse/translator/request/openai-to-claude.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/request/openai-to-claude.ts) convert incoming OpenAI-style payloads into provider-specific request bodies, handling field remapping and schema adjustments.
- **Response Translation** – Files such as [`open-sse/translator/response/openai-to-gemini.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/response/openai-to-gemini.ts) rewrite upstream responses back into OpenAI-compatible shapes while preserving streaming semantics.

## Central Entry Points: translateRequest and translateResponse

All request handlers, including those in [`open-sse/handlers/chatCore.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/handlers/chatCore.ts), interact with the translation layer through two primary functions exported from [`open-sse/translator/index.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/index.ts):

```typescript
import { translateRequest, translateResponse } from "@/translator";

const translatedBody = await translateRequest(
  rawBody,        // Client JSON payload
  sourceFormat,   // e.g., "openai"
  targetFormat,   // e.g., "claude"
  requestOptions  // Optional flags: maxTokens, tool schemas, etc.
);

```

The `translateRequest` function executes a strict three-phase pipeline:

1. **Registry Lookup** – Queries the registry in [`registry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/registry.ts) to retrieve the appropriate translator factory for the `sourceFormat` → `targetFormat` pair.
2. **Schema Validation** – Applies Zod-based coercion via [`helpers/schemaCoercion.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/helpers/schemaCoercion.ts) to reject malformed payloads before conversion.
3. **Provider Conversion** – Delegates to concrete translator modules that handle field renaming, tool-call mapping, and media encoding.

After receiving the upstream response, handlers invoke `translateResponse` with the same signature pattern to convert the provider's output back to the client-expected format.

## Bi-Directional Registry with Lazy Loading

The [`open-sse/translator/registry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/registry.ts) file implements a nested dictionary structure supporting translation in both directions:

```typescript
{
  openai: {
    claude: {
      request: () => import("./request/openai-to-claude"),
      response: () => import("./response/openai-to-claude")
    },
    gemini: { /* ... */ }
  },
  claude: {
    openai: { /* reverse translation */ }
  }
}

```

Lazy `import()` functions ensure modules load only when a specific **API format translation** occurs, minimizing memory footprint while maintaining support for bidirectional conversion between any supported format pair.

## Provider-Specific Transformation Logic

Concrete translator modules handle mechanical schema differences through shared utilities in the `helpers/` directory:

- **Field Remapping** – Converting `model` to `modelId` and restructuring `messages` arrays into provider-specific `prompt` objects.
- **Tool-Call Normalization** – Using [`helpers/toolCallShim.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/helpers/toolCallShim.ts) to map OpenAI's `function_calls` to Claude's `tool_calls` format and vice versa.
- **Image Encoding** – Converting between base64 and multipart formats via [`image/sizeMapper.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/image/sizeMapper.ts).
- **Token Budgeting** – Adjusting `max_tokens` values through [`helpers/maxTokensHelper.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/helpers/maxTokensHelper.ts) to respect provider-specific limits.
- **System Prompt Handling** – Guaranteeing system message compatibility through [`helpers/strictSystemHoist.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/helpers/strictSystemHoist.ts).

## Streaming Response Translation

For providers supporting Server-Sent Events (SSE), response translators implement Node.js `TransformStream` interfaces. The [`open-sse/translator/response/openai-to-gemini-sse.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/response/openai-to-gemini-sse.ts) module, for example, consumes Gemini's native SSE chunks and yields OpenAI-compatible `data: {"choices":[…]}` frames. This allows [`chatCore.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/chatCore.ts) to treat all upstream streams identically, regardless of the provider's native streaming format.

## Extending the Translator for New Providers

Adding support for a new LLM provider follows a predictable pattern:

1. **Create translator modules** at [`src/translator/request/openai-to-myai.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/translator/request/openai-to-myai.ts) and [`src/translator/response/openai-to-myai.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/translator/response/openai-to-myai.ts).
2. **Register bidirectional entries** in [`open-sse/translator/registry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/registry.ts):
   ```typescript
   Registry["openai"]["myai"] = {
     request: () => import("./request/openai-to-myai"),
     response: () => import("./response/openai-to-myai")
   };
   Registry["myai"]["openai"] = {
     request: () => import("./request/myai-to-openai"),
     response: () => import("./response/myai-to-openai")
   };
   ```

3. **Update [`open-sse/translator/formats.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/formats.ts)** to include the new format identifier if required.

New translators automatically inherit utilities from [`helpers/jsonUtil.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/helpers/jsonUtil.ts) for safe deep-cloning and pruning, ensuring consistency across the ecosystem.

## Summary

- OmniRoute's **API format translation** architecture consists of a Format Registry, Request Translation layer, and Response Translation layer.
- The `translateRequest` and `translateResponse` functions in [`open-sse/translator/index.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/index.ts) serve as the unified entry points for all provider conversions.
- A bi-directional registry in [`registry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/registry.ts) uses lazy-loaded imports to minimize bundle size while supporting 268+ providers.
- Provider-specific converters handle schema differences through shared helpers for tool calls, images, token limits, and system prompts.
- Streaming responses are normalized via TransformStream implementations to provide uniform SSE output to clients.

## Frequently Asked Questions

### How does OmniRoute handle tool-call format differences between providers?

OmniRoute normalizes tool-call structures through [`helpers/toolCallShim.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/helpers/toolCallShim.ts), which maps OpenAI's `function_calls` to Claude's `tool_calls` format during request translation, with reverse mapping occurring during response translation. This ensures compatibility regardless of which provider executes the function.

### Can OmniRoute translate between any two provider formats, or only from OpenAI format?

While OpenAI-compatible format serves as the primary client-facing interface, the registry supports bi-directional translation between any supported format pairs. As defined in [`open-sse/translator/registry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/registry.ts), entries exist for both `openai → claude` and `claude → openai`, enabling translation in either direction, though OpenAI format typically acts as the canonical intermediate representation.

### What happens to streaming responses during API format translation?

Response translators for streaming providers implement Node.js TransformStreams. For example, [`open-sse/translator/response/openai-to-gemini-sse.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/response/openai-to-gemini-sse.ts) converts Gemini's SSE chunks into OpenAI-compatible `data:` frames, allowing [`open-sse/handlers/chatCore.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/handlers/chatCore.ts) to process all upstream streams uniformly without provider-specific branching logic.

### How does the system validate requests before translation?

Before conversion, `translateRequest` executes Zod-based validation through [`helpers/schemaCoercion.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/helpers/schemaCoercion.ts). This rejects malformed payloads immediately, preventing invalid requests from reaching provider-specific translators and ensuring type safety across the 268 supported integrations.