# How FreeLLMAPI Supports Anthropic /v1/messages Alongside OpenAI

> Learn how FreeLLMAPI supports Anthropic's v1 messages endpoint alongside OpenAI. Discover its translation layer for unified free LLM access via both API specs.

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

---

**FreeLLMAPI implements Anthropic’s `/v1/messages` endpoint as a thin translation layer that converts incoming requests to an internal OpenAI-shaped format, processes them through shared routing and fallback logic, and transforms responses back to Anthropic’s wire format, enabling unified access to free LLM models via both API specifications.**

The tashfeenahmed/freellmapi repository provides an open-source API gateway designed to aggregate free-tier large language model providers. By treating the **FreeLLMAPI Anthropic /v1/messages endpoint** as a compatibility shim rather than a separate codebase, the system maintains exact wire-format compliance with Claude SDKs while leveraging the same resilient backend that serves OpenAI-compatible clients.

## Translation-Only Router Architecture

The Anthropic route lives in [`server/src/routes/anthropic.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/routes/anthropic.ts) and functions as a bidirectional adapter. Incoming requests undergo immediate structural transformation before entering the core processing pipeline.

Request conversion occurs at lines 33-38, where the Anthropic-specific JSON payload transforms into the internal `ChatMessage` structure used by the OpenAI implementation. This normalization allows the system to apply identical validation, rate limiting, and routing logic regardless of the client’s expected wire format.

After the shared `runFallbackLoop` completes processing, the response flows through `toAnthropicContent` (lines 93-115). This function remaps the OpenAI-style output—including content blocks, tool calls, and metadata—back into the Anthropic Messages API schema. For streaming responses, the `streamCompletion` wrapper (lines 62-66) translates Server-Sent Events (SSE) streams into the format expected by Claude Code and other Anthropic-native tools.

## Model Mapping and Family Classification

Anthropic clients reference model families using aliases like `claude-sonnet-4-5` or `claude-opus`, which must resolve to concrete catalog entries. The [`server/src/services/anthropic-map.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/anthropic-map.ts) module handles this resolution through two primary functions.

The `classifyClaudeFamily` function (lines 60-73) parses the incoming model string to identify whether the request targets Sonnet, Opus, or Haiku lineages. Subsequently, `getClaudeModelMap` checks operator-defined mappings stored in the settings database. If a family maps to `"auto"`, the request enters the automatic provider-routing logic; otherwise, the configured catalog model ID pins the request to a specific backend (lines 88-115). This architecture allows administrators to redirect entire Claude families to specific free models or provider pools without modifying client code.

## Unified Authentication and Fallback Logic

Both OpenAI and Anthropic endpoints accept identical authentication schemes. The Anthropic router’s `authenticate` middleware (lines 94-102) validates bearer tokens or `x-api-key` headers using the same credential store as the OpenAI routes, ensuring consistent access control across API surfaces.

The critical resilience layer resides in [`server/src/lib/fallback-loop.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/lib/fallback-loop.ts). Both route handlers invoke `runFallbackLoop`, which implements retry logic, provider cooldowns, exhaustion handling, and circuit-breaking. By pushing Anthropic requests through this shared machinery, FreeLLMAPI guarantees that Claude-format requests benefit from the same automatic failover between free providers as standard OpenAI chat completion calls.

## Feature Parity: Tools, Images, and Reasoning

The translation layer preserves advanced capabilities through specialized normalizers:

- **Tool Calls**: Anthropic’s `tool_use` blocks map to OpenAI’s `tool_calls` format. The system rescues inline tool invocations that appear as raw text through dialect-detection logic in [`server/src/lib/tool-args.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/lib/tool-args.ts) and [`server/src/lib/tool-call-rescue.js`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/lib/tool-call-rescue.js).

- **Image Processing**: Multimodal requests containing Anthropic image blocks undergo conversion via `imageBlockToUrl` (lines 31-39 in [`anthropic.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/anthropic.ts)), transforming base64 or URL-based Anthropic image objects into OpenAI-compatible `image_url` blocks.

- **Reasoning Content**: When backends return chain-of-thought or reasoning metadata, the system renders Anthropic’s `thinking` blocks from the internal `reasoning_content` field (lines 95-101), ensuring that extended thinking models present structured reasoning to compatible clients.

## Implementation Examples

### Calling the Anthropic Messages Endpoint

This example demonstrates submitting a request using Claude-family nomenclature:

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

const response = await fetch('https://my-freellmapi.com/anthropic/v1/messages', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-api-key': 'YOUR_FREE_LLMAPI_KEY',
  },
  body: JSON.stringify({
    model: 'claude-sonnet-4-5',
    max_tokens: 512,
    messages: [{ role: 'user', content: 'Explain quantum tunnelling.' }],
  }),
});

const data = await response.json();
console.log(data);

```

The request hits the POST handler in [`server/src/routes/anthropic.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/routes/anthropic.ts), undergoes model resolution via `classifyClaudeFamily`, and routes through the shared fallback loop.

### Equivalent OpenAI Chat Completions Call

The same backend infrastructure processes standard OpenAI requests:

```typescript
await fetch('https://my-freellmapi.com/v1/chat/completions', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Authorization: 'Bearer YOUR_FREE_LLMAPI_KEY',
  },
  body: JSON.stringify({
    model: 'gpt-4o-mini',
    messages: [{ role: 'user', content: 'Tell a joke.' }],
  }),
});

```

Both requests consume from the same pool of free model providers, with routing decisions determined by the operator’s mapping configuration rather than the client’s chosen wire protocol.

### Configuring Model Family Mappings

Administrators can pin Claude families to specific catalog models:

```typescript
await fetch('https://my-freellmapi.com/admin/anthropic-model-map', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Authorization: 'Bearer ADMIN_KEY',
  },
  body: JSON.stringify({ sonnet: 'gpt-4o-mini' }),
});

```

This mapping persists in the settings table and is retrieved by `getClaudeModelMap` (lines 31-38 in [`server/src/services/anthropic-map.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/anthropic-map.ts)), forcing all Sonnet-family requests to target the specified model.

## Summary

- **FreeLLMAPI implements the Anthropic `/v1/messages` endpoint** in [`server/src/routes/anthropic.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/routes/anthropic.ts) as a bidirectional translation layer rather than a standalone implementation.
- **Request and response conversion** occurs at lines 33-38 and 93-115 respectively, transforming Anthropic wire formats to internal OpenAI-shaped structures and back.
- **Model family resolution** happens via `classifyClaudeFamily` and `getClaudeModelMap` in [`server/src/services/anthropic-map.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/anthropic-map.ts), supporting both automatic routing and operator-pinned mappings.
- **Shared infrastructure** includes unified authentication (lines 94-102), the `runFallbackLoop` for resilience, and feature normalizers for tools, images, and reasoning content.
- **Full compatibility** is maintained with existing Anthropic SDKs, Claude Code, and OpenAI clients while routing all traffic through a consolidated free-model aggregation backend.

## Frequently Asked Questions

### How does FreeLLMAPI handle authentication for Anthropic requests compared to OpenAI requests?

FreeLLMAPI uses identical authentication logic for both endpoints. The Anthropic router accepts the standard `x-api-key` header or `Authorization: Bearer` tokens, validating them against the same credential store as OpenAI routes (see `authenticate` in [`server/src/routes/anthropic.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/routes/anthropic.ts), lines 94-102). This unified approach allows users to use a single API key regardless of which wire format their application expects.

### Can I use Claude-specific features like tool use and extended thinking through the FreeLLMAPI Anthropic endpoint?

Yes. The translation layer specifically handles Anthropic’s `tool_use` blocks by mapping them to OpenAI’s `tool_calls` format, with additional rescue logic for inline tool dialects. For reasoning content, the system populates Anthropic’s `thinking` blocks from the internal `reasoning_content` field (lines 95-101 in [`anthropic.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/anthropic.ts)). Image inputs are normalized via `imageBlockToUrl` (lines 31-39), ensuring multimodal parity across both APIs.

### What happens if I request a Claude model that isn’t explicitly mapped to a free provider?

If the requested Claude family maps to `"auto"` in the operator configuration, the request enters the automatic routing logic that selects an available free provider based on current capacity and health status. If the family maps to a specific model ID via `getClaudeModelMap` (lines 88-115 in [`anthropic-map.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/anthropic-map.ts)), the request pins to that catalog entry. If no mapping exists and auto-routing fails, the `runFallbackLoop` returns an exhaustion error after exhausting the provider pool.

### Is the streaming implementation different between Anthropic and OpenAI endpoints in FreeLLMAPI?

The core streaming logic is identical; both endpoints utilize the shared `streamCompletion` infrastructure. However, the Anthropic route includes a thin wrapper (lines 62-66 in [`anthropic.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/anthropic.ts)) that reformats the SSE event stream to match Anthropic’s expected data prefixes and termination sequences. This ensures compatibility with Claude Code and other Anthropic-native streaming consumers while maintaining the same underlying retry and fallback behavior.