# How FreeLLMAPI Handles Cohere Tool Call Schema Differences

> FreeLLMAPI resolves Cohere tool call schema differences by removing unsupported keys like additionalProperties and $schema. Ensure seamless OpenAI-compatible tool-call functionality.

- Repository: [Tashfeen/freellmapi](https://github.com/tashfeenahmed/freellmapi)
- Tags: internals
- Published: 2026-08-27

---

**FreeLLMAPI automatically removes unsupported JSON Schema keys like `additionalProperties` and `$schema` from tool definitions before sending requests to Cohere's API, preventing 400 Bad Request errors while maintaining OpenAI-compatible tool-call functionality.**

FreeLLMAPI provides a unified, OpenAI-compatible interface for multiple large language model providers. When working with Cohere's API, the **Cohere tool call schema** imposes stricter validation rules than other providers, rejecting certain standard JSON Schema keys that are harmless in OpenAI's implementation. To solve this, FreeLLMAPI implements a provider-specific sanitization layer that strips incompatible keys while preserving the rest of the tool definition.

## The Problem: Cohere's Strict Schema Validation

Unlike OpenAI's permissive validation, Cohere's endpoint strictly enforces JSON Schema compliance for tool definitions. When FreeLLMAPI forwards a standard OpenAI-format tool definition containing certain schema metadata, Cohere responds with a **400 Bad Request** error. Specifically, Cohere rejects the `additionalProperties` and `$schema` keys that many OpenAI-compatible clients include by default in their JSON Schema objects.

## How FreeLLMAPI Strips Incompatible Keys

FreeLLMAPI solves the **Cohere tool call schema** compatibility issue through a three-stage sanitization pipeline defined in [`server/src/providers/cohere.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/providers/cohere.ts) and [`server/src/lib/tool-args.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/lib/tool-args.ts).

### Identifying Unsupported Keys

The system first defines exactly which keys trigger Cohere's validation errors. In [`server/src/providers/cohere.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/providers/cohere.ts) at lines 21-22, the code declares a constant set of problematic keys:

```typescript
const COHERE_UNSUPPORTED_SCHEMA_KEYS = new Set([
  "additionalProperties",
  "$schema"
]);

```

This explicit enumeration ensures that only the specific keys known to cause Cohere failures are targeted for removal.

### The Sanitization Process

Before any API request, the `sanitizeCohereTools` helper processes the array of `ChatToolDefinition` objects. Located at lines 23-30 in [`server/src/providers/cohere.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/providers/cohere.ts), this function walks through each tool and checks for `function.parameters` objects:

```typescript
function sanitizeCohereTools(tools?: ChatToolDefinition[]) {
  if (!tools || tools.length === 0) return tools;
  return tools.map(t =>
    t.function?.parameters
      ? {
          ...t,
          function: {
            ...t.function,
            parameters: stripSchemaKeys(
              t.function.parameters,
              COHERE_UNSUPPORTED_SCHEMA_KEYS
            )
          }
        }
      : t
  );
}

```

This mapping preserves all other tool metadata—names, descriptions, and required parameters—while targeting only the schema object for cleaning.

### Recursive Key Removal

The actual key removal happens in [`server/src/lib/tool-args.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/lib/tool-args.ts) at lines 72-85 via the `stripSchemaKeys` utility. This generic function recursively traverses the JSON Schema object and deletes any property whose key appears in the supplied exclusion set:

```typescript
function stripSchemaKeys(
  obj: Record<string, any>,
  keysToStrip: Set<string>
): Record<string, any> {
  if (typeof obj !== "object" || obj === null) return obj;
  
  const result: Record<string, any> = {};
  for (const [key, value] of Object.entries(obj)) {
    if (keysToStrip.has(key)) continue;
    result[key] = stripSchemaKeys(value, keysToStrip);
  }
  return result;
}

```

This recursive approach handles nested schema definitions, ensuring that `$schema` or `additionalProperties` keys are removed regardless of their depth in the object hierarchy.

## Implementation in the Cohere Provider

The sanitized tools are integrated into both standard and streaming completion flows. In [`server/src/providers/cohere.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/providers/cohere.ts) at lines 44-52, the `CohereProvider.chatCompletion` and `CohereProvider.streamChatCompletion` methods apply the sanitization before constructing the request payload:

```typescript
// Inside CohereProvider class
async chatCompletion(apiKey: string, messages: Message[], model: string, options: ChatOptions) {
  const sanitizedTools = sanitizeCohereTools(options.tools);
  
  const requestBody = {
    model,
    messages,
    tools: sanitizedTools,  // Cohere-safe schema
    stream: false
  };
  
  return fetch("https://api.cohere.ai/v1/chat", {
    method: "POST",
    headers: { Authorization: `Bearer ${apiKey}` },
    body: JSON.stringify(requestBody)
  });
}

```

This ensures that whether you're calling `command-r-plus` for a single response or streaming tokens, the **Cohere tool call schema** receives only the keys it accepts.

## Summary

- **FreeLLMAPI** maintains OpenAI compatibility by automatically sanitizing tool schemas for provider-specific restrictions.
- The `COHERE_UNSUPPORTED_SCHEMA_KEYS` set explicitly targets `additionalProperties` and `$schema` as the problematic keys rejected by Cohere.
- The `sanitizeCohereTools` function in [`server/src/providers/cohere.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/providers/cohere.ts) processes tool arrays before API transmission.
- **Recursive cleaning** via `stripSchemaKeys` in [`server/src/lib/tool-args.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/lib/tool-args.ts) ensures nested schema objects are properly handled.
- Sanitization applies to both `chatCompletion` and `streamChatCompletion` methods, preventing 400 errors across all Cohere interaction modes.

## Frequently Asked Questions

### What specific JSON Schema keys does Cohere reject?

Cohere's API rejects the `additionalProperties` and `$schema` keys within tool parameter definitions. According to the FreeLLMAPI source code in [`server/src/providers/cohere.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/providers/cohere.ts), these are defined in the `COHERE_UNSUPPORTED_SCHEMA_KEYS` constant and removed before every request to prevent validation failures.

### How does FreeLLMAPI maintain OpenAI compatibility while supporting Cohere?

FreeLLMAPI accepts standard OpenAI-format tool definitions at its interface level, then applies provider-specific transformations internally. For Cohere, it strips incompatible schema keys via `sanitizeCohereTools` while leaving all other tool metadata—names, descriptions, and parameter types—completely unchanged, ensuring the same client code works across providers.

### Can the schema stripping logic be reused for other providers?

Yes. The `stripSchemaKeys` function in [`server/src/lib/tool-args.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/lib/tool-args.ts) is designed as a generic utility that accepts any set of keys to remove. FreeLLMAPI uses this same function for other providers like Google's Gemini that impose similar JSON Schema restrictions, making it a reusable component for handling strict validation requirements.

### Where is the Cohere-specific sanitization logic located?

The Cohere-specific logic resides primarily in [`server/src/providers/cohere.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/providers/cohere.ts), which contains the `COHERE_UNSUPPORTED_SCHEMA_KEYS` constant and the `sanitizeCohereTools` function. The underlying recursive removal utility is shared across providers and located in [`server/src/lib/tool-args.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/lib/tool-args.ts) at lines 72-85.