halfoff.devДокументация
Получить ключ
Models API

Anthropic Messages

Запускайте Claude за полцены с существующим кодом на Anthropic SDK. Замените базовый URL; потоковая передача, thinking, вызов инструментов, кеширование и подсчёт токенов работают без изменений.

Если ваш код уже обращается к Claude через Anthropic SDK, для перехода на Half Off Dev достаточно двух настроек: базовый URL https://halfoff.dev и ваш ключ Half Off Dev. POST /v1/messages и POST /v1/messages/count_tokens работают так, как описывает Anthropic, а тела запросов пересылаются без изменений, поэтому справочник API Anthropic остаётся вашим руководством по каждому полю. Каждый токен тарифицируется за половину прайсовой цены.

Направьте SDK на Half Off Dev#

Anthropic SDK передаёт ключ в x-api-key; передача в виде Authorization: Bearer тоже принимается.

curl https://halfoff.dev/v1/messages \
  -H "x-api-key: $HALFOFF_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-sonnet-5.5",
    "max_tokens": 1024,
    "messages": [{"role": "user", "content": "Give me three names for a code review bot."}]
  }'

Код, который создаёт клиент по умолчанию, вообще не нужно менять: SDK берут ANTHROPIC_BASE_URL и ANTHROPIC_API_KEY из окружения, так что export ANTHROPIC_BASE_URL=https://halfoff.dev и вашего ключа достаточно.

В актуальную линейку Claude входят claude-fable-5.1, claude-opus-5.5, claude-sonnet-5.5 и claude-haiku-5.5; более старые версии тоже доступны. Авторитетный список с ценами возвращает GET /v1/models.

Потоковая передача токенов по мере генерации#

Передайте stream: true или воспользуйтесь потоковым помощником SDK. События идут в порядке Anthropic: message_start, content_block_start, content_block_delta, content_block_stop, message_delta, message_stop.

with client.messages.stream(
    model="claude-sonnet-5.5",
    max_tokens=2048,
    messages=[{"role": "user", "content": "Draft a short release note for a bug-fix version."}],
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)
    final = stream.get_final_message()
print("\n", final.usage)

Пока не появился первый токен, шлюз держит поток у себя; если за это время канал выходит из строя, его заменяет другой, и вы сбоя не увидите. Подробности в разделе Потоковая передача.

Пусть Claude вызывает ваши функции#

Опишите каждую функцию через input_schema в формате JSON Schema. Ответ со stop_reason: "tool_use" просит вас выполнить функцию; ответьте блоком tool_result.

tools = [{
    "name": "convert_currency",
    "description": "Convert an amount between two currencies.",
    "input_schema": {
        "type": "object",
        "properties": {
            "amount": {"type": "number"},
            "from_currency": {"type": "string"},
            "to_currency": {"type": "string"},
        },
        "required": ["amount", "from_currency", "to_currency"],
    },
}]
messages = [{"role": "user", "content": "How much is 250 EUR in JPY?"}]

response = client.messages.create(
    model="claude-sonnet-5.5", max_tokens=1024, tools=tools, messages=messages,
)
if response.stop_reason == "tool_use":
    call = next(b for b in response.content if b.type == "tool_use")
    result = {"converted": 40125.0, "currency": call.input["to_currency"]}  # your code here
    messages += [
        {"role": "assistant", "content": response.content},
        {"role": "user", "content": [
            {"type": "tool_result", "tool_use_id": call.id, "content": str(result)},
        ]},
    ]
    response = client.messages.create(
        model="claude-sonnet-5.5", max_tokens=1024, tools=tools, messages=messages,
    )
print(response.content[0].text)

tool_choice, strict и остальные параметры Anthropic пересылаются как есть; они описаны в руководстве по tool use.

Включите extended thinking#

Передавайте thinking и output_config в том виде, который Anthropic определяет для нужной модели. Новые модели размышляют адаптивно и принимают уровень усилия; Claude 4.5 и старше ожидают фиксированный budget_tokens. Правила для каждой модели описаны в руководстве Anthropic по thinking.

reply = client.messages.create(
    model="claude-opus-5.5",
    max_tokens=16000,
    thinking={"type": "adaptive", "display": "summarized"},
    output_config={"effort": "high"},
    messages=[{"role": "user", "content": "A train leaves at 09:40 and arrives at 14:05. How long is the trip in minutes?"}],
)
for block in reply.content:
    if block.type == "thinking":
        print("Reasoning:", block.thinking)
    elif block.type == "text":
        print("Result:", block.text)

Размышления входят в usage.output_tokens, поэтому тарифицируются по (уменьшенной вдвое) цене выходных токенов. Если разговор продолжается после вызова инструмента, возвращайте блоки thinking ровно в том виде, в каком получили их.

Кешируйте префикс, который отправляете повторно#

Поставьте cache_control на последний блок той части, которая не меняется между вызовами. Первый вызов записывает кеш; любой следующий вызов, начинающийся с того же префикса, читает его по малой доле от цены входных токенов.

response = client.messages.create(
    model="claude-sonnet-5.5",
    max_tokens=1024,
    system=[{
        "type": "text",
        "text": STYLE_GUIDE,
        "cache_control": {"type": "ephemeral"},
    }],
    messages=[{"role": "user", "content": "Rewrite this headline to match the guide: 'Q3 numbers are in'"}],
)
u = response.usage
print(u.cache_creation_input_tokens, u.cache_read_input_tokens, u.input_tokens)

Цены для claude-sonnet-5.5 за миллион токенов: $1.00 за входные токены без кеша, $1.25 за запись кеша и $0.05 за чтение кеша. Префикс короче минимальной длины модели не кешируется, и оба поля кеша возвращаются нулевыми. Шлюз возвращает каждый разговор на канал, где лежит его кеш; полная картина в разделе Кеширование промптов.

Подсчёт токенов перед отправкой#

POST /v1/messages/count_tokens принимает тело сообщения без max_tokens и отвечает input_tokens. Это бесплатно и работает даже при нулевом балансе.

curl https://halfoff.dev/v1/messages/count_tokens \
  -H "x-api-key: $HALFOFF_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{"model": "claude-sonnet-5.5",
       "messages": [{"role": "user", "content": "How long is this prompt?"}]}'

Оценка, а не счёт

Подсчёт годится, чтобы сопоставить промпт с контекстным окном или спланировать бюджет. Списание всегда определяется блоком usage в фактическом ответе модели.

Claude Code#

Claude Code использует этот же API. Задайте ANTHROPIC_BASE_URL=https://halfoff.dev и положите ключ в ANTHROPIC_AUTH_TOKEN; каждая сессия остаётся на одном канале, чтобы её кеш не остывал. Пошаговая настройка, включая параметры моделей, описана в разделе Claude Code.

Заголовки запроса#

ЗаголовокПоведение
x-api-key или Authorization: BearerВаш ключ Half Off Dev. Обязателен.
anthropic-versionПересылается; если не указан, подставляется 2023-06-01.
anthropic-betaПересылается без изменений.
x-halfoff-groupНеобязателен. Выбирает группу каналов для этого запроса, если ключ ещё не привязан к группе.
x-session-idНеобязателен. Помечает запросы как один разговор для маршрутизации с учётом кеша. metadata.user_id в теле действует так же.

Все остальные заголовки запроса отбрасываются. Ошибки сохраняют формат Anthropic, {"type": "error", "error": {"type": "...", "message": "..."}}; коды перечислены в разделе Ошибки.