How CCX Messages, Chat, Responses, Gemini, and Images Channels Differ: Protocol & Implementation Guide

In CCX, the five channels differ primarily by their upstream protocols: Messages uses Anthropic's Claude Messages API, Chat uses OpenAI's Chat Completions, Responses uses OpenAI's legacy Completions endpoint, Gemini uses Google's Gemini API, and Images uses OpenAI's Image generation/editing endpoints—each requiring distinct authentication headers, request bodies, and response parsers as implemented in their dedicated Go handler files.

CCX (Cross‑Channel eXchange) is an open‑source proxy that unifies large language model APIs under a common routing layer. Understanding the specific protocol differences between the Messages, Chat, Responses, Gemini, and Images channels is critical for configuring upstream providers and troubleshooting integration errors. This guide examines the implementation details from the BenedictKing/ccx repository, including exact handler file paths and runnable request examples.

Messages Channel: Anthropic Claude Protocol

The Messages channel implements the Anthropic Messages API for Claude models. Unlike standard OpenAI‑compatible endpoints, this channel requires the anthropic-version header and uses Claude's native message structure.

Key implementation details in backend-go/internal/handlers/messages/channels.go:

  • Endpoint: POST /v1/messages
  • Required Headers: Authorization: Bearer <key> and anthropic-version: 2023-06-01
  • Request Body: Uses a messages array with role and content fields, but follows Claude's formatting conventions
  • Response Structure: Returns type: "message" with role and content arrays, distinct from OpenAI's choices wrapper
curl -X POST http://localhost:8080/v1/messages \
  -H "Authorization: Bearer $CLAUDE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "anthropic-version: 2023-06-01" \
  -d '{
        "model":"claude-3-5-sonnet-20240620",
        "messages":[
          {"role":"user","content":"Explain quantum tunneling in one sentence."}
        ],
        "max_tokens":256
      }'

Chat Channel: OpenAI Chat Completions

The Chat channel handles OpenAI's standard Chat Completions protocol, which has become the industry default for conversational AI. This is the most commonly used channel for modern GPT models.

Implementation resides in backend-go/internal/handlers/chat/channels.go:

  • Endpoint: POST /v1/chat/completions
  • Authentication: Standard Authorization: Bearer <key>
  • Request Body: JSON with messages array containing objects with role (system, user, assistant) and content
  • Response Format: Returns choices[0].message structure
  • Streaming: Supports stream=true for Server‑Sent Events (SSE)
curl -X POST http://localhost:8080/v1/chat/completions \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "model":"gpt-4o-mini",
        "messages":[
          {"role":"system","content":"You are a helpful assistant."},
          {"role":"user","content":"Write a haiku about spring."}
        ],
        "temperature":0.7
      }'

Responses Channel: OpenAI Legacy Completions

The Responses channel corresponds to OpenAI's legacy Completions API (not Chat). This protocol differs significantly from the Chat channel by using raw prompt strings instead of structured message arrays.

Found in backend-go/internal/handlers/responses/channels.go:

  • Endpoint: POST /v1/completions
  • Request Body: Uses prompt field (string or array of strings) rather than messages
  • Response Format: Returns choices[0].text without role fields, providing only the generated text completion
  • Use Case: Text completion workflows that predate conversational formats
curl -X POST http://localhost:8080/v1/completions \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "model":"gpt-4o-mini",
        "prompt":"Summarize the plot of \"Pride and Prejudice\" in 30 words.",
        "max_tokens":150
      }'

Gemini Channel: Google Gemini API

The Gemini channel provides a bridge to Google's Gemini models via the v1beta API. This channel handles protocol translation between Google's native format and OpenAI‑compatible responses.

Implementation in backend-go/internal/handlers/gemini/channels.go:

  • Endpoint: POST /v1beta/models/{model}:generateContent
  • Authentication: Uses x-goog-api-key header instead of Bearer tokens
  • Model Listing: Queries /v1beta/models and converts the response to OpenAI‑compatible object: "list" JSON format
  • Request Structure: Uses Gemini's contents array with parts objects containing text
curl -X POST http://localhost:8080/v1beta/models/gemini-1.5-pro:generateContent \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "contents":[{"role":"user","parts":[{"text":"What is the capital of Canada?"}]}],
        "generationConfig":{"temperature":0.5}
      }'

To retrieve models through CCX's unified interface:

curl -X POST http://localhost:8080/gemini/channels/0/models \
  -H "Content-Type: application/json" \
  -d '{"key":"'"$GEMINI_API_KEY"'"}'

Images Channel: OpenAI Image Operations

The Images channel supports OpenAI's DALL‑E style image generation, editing, and variations. This channel has strict service type requirements and handles multipart form data for image uploads.

Located in backend-go/internal/handlers/images/channels.go:

  • Service Type Restriction: Only accepts upstream configurations with serviceType: "openai"
  • Endpoints: /v1/images/generations, /v1/images/edits, /v1/images/variations
  • Content Types: JSON for generations, multipart/form-data for edits and variations
  • Authentication: Standard OpenAI Bearer token only

Image Generation (JSON):

curl -X POST http://localhost:8080/v1/images/generations \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "prompt":"A futuristic cityscape at night, cyberpunk style",
        "n":1,
        "size":"1024x1024"
      }'

Image Editing (multipart/form-data):

curl -X POST http://localhost:8080/v1/images/edits \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -F "image=@original.png" \
  -F "mask=@mask.png" \
  -F 'prompt=Add a flying car' \
  -F "n=1"

Authentication & Header Differences

Each channel enforces distinct authentication patterns:

  • Messages: Requires Authorization: Bearer <key> and anthropic-version: 2023-06-01
  • Chat, Responses, Images: Standard Authorization: Bearer <key> (OpenAI‑compatible)
  • Gemini: Uses x-goog-api-key: <key> (Google‑specific header)

The backend-go/internal/config/config.go file defines the UpstreamConfig structure that stores these authentication credentials, while backend-go/internal/scheduler/channel_scheduler.go manages channel‑specific routing and failover logic based on these upstream types.

Request Structure Comparison

The five channels accept fundamentally different request payloads:

  1. Messages & Chat: Both use messages arrays, but Messages requires Claude‑specific formatting and versioning
  2. Responses: Uses legacy prompt strings instead of structured conversations
  3. Gemini: Implements Google's contents array with nested parts objects
  4. Images: Uses either JSON parameters (generations) or multipart form uploads (edits/variations)

Response parsing also varies: Messages returns Claude's native format, Chat returns choices[0].message, Responses returns choices[0].text, and Gemini responses are proxied with format conversion for model listings.

Summary

Frequently Asked Questions

Which CCX channel should I use for Claude 3.5 Sonnet?

Use the Messages channel. According to backend-go/internal/handlers/messages/channels.go, this channel implements the Anthropic Messages API and is the only route that properly handles Claude's anthropic-version header requirements and message‑based conversation format.

Why does the Gemini channel require a different authentication header?

The Gemini channel communicates directly with Google's API infrastructure, which uses x-goog-api-key instead of the Bearer token scheme standardized by OpenAI. The handler in backend-go/internal/handlers/gemini/channels.go manages this translation, forwarding requests to Google's v1beta endpoints while optionally converting responses to OpenAI‑compatible formats for upstream model listings.

Can I use non‑OpenAI providers with the Images channel?

No. The Images channel explicitly requires serviceType: "openai" in the upstream configuration. As implemented in backend-go/internal/handlers/images/channels.go, this restriction ensures that only OpenAI‑compatible image endpoints (supporting generations, edits, and variations) are routed through this channel.

What is the difference between the Chat and Responses channels?

Chat uses the modern OpenAI Chat Completions protocol with structured messages arrays containing role and content fields, returning assistant messages in choices[0].message. Responses uses the legacy Completions API, accepting a raw prompt string and returning generated text in choices[0].text without role metadata. Choose Chat for conversational agents and Responses for single‑turn text completion tasks.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →