Skip to content

Batch API

Batch API позволяет отправить много inference-запросов одним пакетом и забрать результаты асинхронно. Это удобно, когда ответ не нужен сразу: overnight-прогоны, оценка датасетов, массовая генерация эмбеддингов и похожие задачи.

Окно выполнения — 24 часа. После завершения batch результаты приходят в том же ответе при опросе статуса (отдельный download URL не нужен).

Скидка на токены

Для поддерживаемых моделей токены ввода/вывода в Batch тарифицируются примерно на 50% дешевле стандартной цены. Точные batch-цены смотрите на странице модели (блок Batch API) и в поле batch публичного каталога.

Нетокеновые услуги

Не все компоненты тарифа одинаково скидываются. Например, вызовы web search обычно идут по стандартной цене; ставки prompt caching зависят от модели. Источник истины — карточка модели и фактический usage.cost_rub после completed.

Поддерживаемые модели

В Batch указывайте обычное имя модели из каталога (gpt-5.4, claude-sonnet-5, text-embedding-3-small, …). Модель поддерживает Batch, если в каталоге есть поле batch:

bash
curl https://api.aitunnel.ru/public/aitunnel/models/chat
curl https://api.aitunnel.ru/public/aitunnel/models/embeddings

Пример фрагмента:

json
{
  "prompt_cost": 500,
  "completion_cost": 3000,
  "batch": {
    "discount": 0.5,
    "window": "24h"
  }
}

Список моделей с Batch также отмечен на страницах моделей на сайте (блок возможностей и цены).

Эндпоинты

МетодПутьОписание
POST/v1/batchesСоздать batch (202 Accepted)
GET/v1/batches/{id}Статус и результаты

Базовый URL: https://api.aitunnel.ru/v1. Авторизация — как обычно: Authorization: Bearer sk-aitunnel-….

Форма запроса

ПолеОписание
endpointФорма API для всех элементов batch: /v1/chat/completions, /v1/responses, /v1/messages или /v1/embeddings
modelId модели AITUNNEL (без префикса провайдера)
requestsНепустой массив { custom_id, body }. custom_id уникален внутри batch; body — тело запроса выбранного endpoint

Порядок полей

В JSON сначала должны идти endpoint и model, затем requests. API stream-парсит тело и вернёт 400, если requests окажется раньше.

Batch-level model применяется ко всем запросам. В body поле model можно не указывать. Если указать — оно должно совпадать с batch-level значением.

Тарификация

  • При POST /v1/batches AITUNNEL резервирует на балансе оценочную стоимость (worst-case по составу batch).
  • Когда статус становится терминальным, списывается фактическая стоимость; разница возвращается на баланс.
  • При failed / expired / cancelled зарезервированная сумма возвращается целиком.
  • Итоговая сумма в рублях — в usage.cost_rub ответа GET /v1/batches/{id} после completed (и успешной сверки).

Отправка batch

python
import os
import time
import requests

API_KEY = os.environ["AITUNNEL_API_KEY"]
BASE = "https://api.aitunnel.ru/v1"

headers = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}

resp = requests.post(
    f"{BASE}/batches",
    headers=headers,
    json={
        "endpoint": "/v1/chat/completions",
        "model": "gpt-5.4",
        "requests": [
            {
                "custom_id": "req-0001",
                "body": {
                    "messages": [
                        {
                            "role": "user",
                            "content": "Суммируй AITUNNEL одним предложением.",
                        }
                    ]
                },
            }
        ],
    },
)
resp.raise_for_status()
batch = resp.json()
print("Batch ID:", batch["id"], "status:", batch["status"])

# Опрос до терминального статуса
while batch["status"] not in ("completed", "failed", "expired", "cancelled"):
    time.sleep(5)
    batch = requests.get(
        f"{BASE}/batches/{batch['id']}",
        headers=headers,
    ).json()
    print("Status:", batch["status"], batch.get("request_counts"))

if batch["status"] != "completed":
    raise RuntimeError(batch.get("error") or batch["status"])

for item in batch.get("results") or []:
    print(item["custom_id"], item.get("response") or item.get("error"))

print("cost_rub:", (batch.get("usage") or {}).get("cost_rub"))
typescript
const API_KEY = process.env.AITUNNEL_API_KEY!;
const BASE = 'https://api.aitunnel.ru/v1';

const headers = {
  Authorization: `Bearer ${API_KEY}`,
  'Content-Type': 'application/json',
};

let res = await fetch(`${BASE}/batches`, {
  method: 'POST',
  headers,
  body: JSON.stringify({
    endpoint: '/v1/chat/completions',
    model: 'gpt-5.4',
    requests: [
      {
        custom_id: 'req-0001',
        body: {
          messages: [
            { role: 'user', content: 'Суммируй AITUNNEL одним предложением.' },
          ],
        },
      },
    ],
  }),
});

let batch = await res.json();
console.log('Batch ID:', batch.id, batch.status);

while (!['completed', 'failed', 'expired', 'cancelled'].includes(batch.status)) {
  await new Promise((r) => setTimeout(r, 5000));
  res = await fetch(`${BASE}/batches/${batch.id}`, { headers });
  batch = await res.json();
  console.log('Status:', batch.status, batch.request_counts);
}

if (batch.status !== 'completed') {
  throw new Error(batch.error || batch.status);
}

for (const item of batch.results ?? []) {
  console.log(item.custom_id, item.response ?? item.error);
}

console.log('cost_rub:', batch.usage?.cost_rub);
shell
curl https://api.aitunnel.ru/v1/batches \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AITUNNEL_API_KEY" \
  -d '{
  "endpoint": "/v1/chat/completions",
  "model": "gpt-5.4",
  "requests": [
    {
      "custom_id": "req-0001",
      "body": {
        "messages": [
          {
            "role": "user",
            "content": "Суммируй AITUNNEL одним предложением."
          }
        ]
      }
    }
  ]
}'

Успешный submit возвращает 202 и объект batch со статусом validating:

json
{
  "id": "batch_123",
  "object": "batch",
  "endpoint": "/v1/chat/completions",
  "model": "gpt-5.4",
  "completion_window": "24h",
  "status": "validating",
  "created_at": 1782097200,
  "finalized_at": null,
  "request_counts": {
    "total": 1,
    "completed": 0,
    "failed": 0
  },
  "usage": null,
  "results": null,
  "error": null
}

Опрос статуса

shell
curl https://api.aitunnel.ru/v1/batches/batch_123 \
  -H "Authorization: Bearer $AITUNNEL_API_KEY"

Типичная цепочка статусов:

text
validating → in_progress → finalizing → completed

Также возможны failed, expired, cancelling, cancelled. Терминальные: completed, failed, expired, cancelled.

request_counts показывает прогресс:

json
{
  "total": 100,
  "completed": 98,
  "failed": 2
}

Пока batch не завершён (или завершён с ошибкой без результатов), results равен null. После completed результаты приходят inline в массиве results.

Каждый элемент сопоставляется с входом по custom_id. Заполняется ровно одно из полей — response или error:

json
{
  "id": "batch_req_123",
  "custom_id": "req-0001",
  "response": {
    "status_code": 200,
    "request_id": "request_123",
    "body": {
      "id": "gen-…",
      "object": "chat.completion",
      "model": "gpt-5.4",
      "choices": [
        {
          "index": 0,
          "message": {
            "role": "assistant",
            "content": "AITUNNEL — единый API к сотням моделей ИИ с оплатой в рублях."
          },
          "finish_reason": "stop"
        }
      ]
    }
  },
  "error": null
}

Другие формы API

Все элементы одного batch используют один и тот же endpoint. Чтобы смешать формы — отправьте несколько batch.

Anthropic Messages

json
{
  "endpoint": "/v1/messages",
  "model": "claude-sonnet-5",
  "requests": [
    {
      "custom_id": "req-1",
      "body": {
        "max_tokens": 32,
        "messages": [
          { "role": "user", "content": "Скажи привет." }
        ]
      }
    }
  ]
}

Embeddings

json
{
  "endpoint": "/v1/embeddings",
  "model": "text-embedding-3-small",
  "requests": [
    {
      "custom_id": "emb-0001",
      "body": {
        "input": [
          "The quick brown fox jumped over the lazy dog.",
          "Pack my box with five dozen liquor jugs."
        ]
      }
    }
  ]
}

Поддержка Batch у конкретной embeddings-модели — поле batch в каталоге:

bash
curl https://api.aitunnel.ru/public/aitunnel/models/embeddings

Мультимодальный input и часть дополнительных параметров могут быть недоступны в Batch — для них используйте синхронный /v1/embeddings.

Хранение результатов

Входные данные и результаты batch хранятся ограниченное время (порядка 30 дней). Скачайте и сохраните нужные результаты до истечения окна хранения.

FAQ

Когда списываются деньги?
Сначала резерв при создании, затем сверка по факту на первом терминальном опросе. Смотрите usage.cost_rub.

Можно ли смешивать модели в одном batch?
Нет. Один batch — одна модель и один endpoint.

AITUNNEL