---
title: Channel groups
description: Claude · Value, GPT · Value and Gemini · Value pool capacity for each model family at half the list price. How to pick one per key or per request.
---

Three channel groups serve every call on Half Off Dev, one per model family. Each is a pool of capacity from several **channels** (individual sources of capacity) that serve the same models at one price. All three bill at half the official list price, so the group you land on never changes what you pay.

Most developers never touch this setting. A new key starts on **Auto**, which sends each request to the group that serves its model. Read on if you want to pin a key or a request to a group explicitly, or to see which group answered.

## The three groups {#groups}

| Group id | Name | Serves | Multiplier |
| --- | --- | --- | --- |
| `claude-value` | Claude · Value | Claude models | ×0.50 |
| `gpt-value` | GPT · Value | GPT models | ×0.50 |
| `gemini-value` | Gemini · Value | Gemini models | ×0.50 |

Each group pools several channels for throughput and keeps every conversation on one channel, so its prompt cache stays warm between turns (see [Prompt caching](/docs/models/caching)). The `groups` field of [`GET /v1/models`](/docs/models/pricing#list-models) names the group behind each model, and the [marketplace](/models) shows every group with its current multiplier.

## Choosing a group {#choosing}

There are three ways a request ends up in a group:

| Setup | Which group serves the call |
| --- | --- |
| Key on **Auto**, no header | The group that serves the requested model. |
| Key on **Auto**, `x-halfoff-group` header | The group named in the header. |
| Key bound to a group | Always the key's group; any header is ignored. |

Since each family has exactly one group, Auto already picks the right one. Binding is useful when you want a key to be limited to one family, for example a key you give to a coding assistant that should only ever call Claude: requests for other models then fail with `404` instead of being served.

## Bind a key {#bind-key}

When you create a key in [API keys](/app/keys), set **Channel group** to one of the three groups. From then on, every request made with that key goes to that group, whatever the request asks for. The binding cannot be edited later; create a new key if you need a different one. More about key settings in [API keys](/docs/account/api-keys).

## Pick a group per request {#per-request}

With a key on Auto, add the `x-halfoff-group` header with a group id. It is honored on every model endpoint, in all three API formats.

```bash title="cURL"
curl https://halfoff.dev/v1/messages \
  -H "x-api-key: $HALFOFF_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "x-halfoff-group: claude-value" \
  -H "content-type: application/json" \
  -d '{"model": "claude-haiku-5.5", "max_tokens": 256,
       "messages": [{"role": "user", "content": "Say hello in Portuguese."}]}'
```

```python title="Python"
import os
import anthropic

client = anthropic.Anthropic(
    base_url="https://halfoff.dev",
    api_key=os.environ["HALFOFF_API_KEY"],
    default_headers={"x-halfoff-group": "claude-value"},
)
```

```js title="Node.js"
import Anthropic from '@anthropic-ai/sdk';

const client = new Anthropic({
  baseURL: 'https://halfoff.dev',
  apiKey: process.env.HALFOFF_API_KEY,
  defaultHeaders: { 'x-halfoff-group': 'claude-value' },
});
```

The OpenAI SDKs accept the same `default_headers` / `defaultHeaders` option.

| If… | You get |
| --- | --- |
| The key is bound to a group | The header is ignored and the key's group serves the call. |
| The group id doesn't exist | `400` with `Unknown group '<id>'`. |
| The group doesn't serve that model in your API format (for example `gpt-value` with a Claude model) | `404` with `Model '<id>' is not served in <format> format in group '<group>'.` |

## Which group answered {#which-group}

Successful responses carry two headers that tell you:

| Header | Example |
| --- | --- |
| `x-halfoff-group` | `claude-value` |
| `x-halfoff-channel` | `Pooled%20capacity` (the group's channel label, URL-encoded) |

The group is also recorded for every call in [Logs](/app/logs), where you can filter by it.

## Failover inside the group {#failover}

If a channel errors or is full, the gateway retries on another channel. With a bound key or an `x-halfoff-group` header, every retry stays in that group, so neither the group nor the price can change underneath you. On Auto, the retry goes to a group that serves the model, and `x-halfoff-group` always names the one that finally answered. [Rate limits & failover](/docs/models/rate-limits#failover) explains when retries happen.

## What each group costs {#price}

A call costs the model's list price times the multiplier of the group that served it. All three groups are at ×0.50, so every call is billed at half the list price whichever group serves it. The full calculation is on [Models & pricing](/docs/models/pricing#charge-formula).
