Batch API (пакетная обработка запросов) позволяет отправить несколько запросов к модели одним файлом и получить результаты после завершения обработки. Запросы выполняются в фоновом режиме в течение 24 часов, обычно быстрее.
Пакетная обработка подходит для задач, в которых ответ не нужен сразу, например:
- перевода большого количества текстов;
- классификации отзывов и обращений;
- подготовки описаний товаров;
- создания векторных представлений текста (embeddings).
При использовании Batch API запросы к моделям становятся вдвое дешевле обычных запросов.
Для использования Batch API:
-
Подготовьте и загрузите JSONL-файл с запросами.
-
Создайте на его основе пакетную задачу — батч.
-
Проверяйте статус батча до завершения обработки.
-
Скачайте файлы с результатами и ошибками отдельных запросов.
Batch API совместим с OpenAI SDK.
Поддерживаемые модели и ограничения
Batch API доступен только в AI Gateway. Ключи AI-агентов для пакетной обработки не подходят.
Поддерживаются только модели OpenAI, для которых включена пакетная обработка:
-
чат-модели, например
openai/gpt-4.1-mini, — через эндпоинт/v1/chat/completions; -
модели для создания embeddings из семейства
openai/text-embedding-*— через эндпоинт/v1/embeddings.
Ограничения JSONL-файла:
|
Параметр |
Ограничение |
|
Формат |
JSONL: один JSON-объект на строку |
|
Количество запросов |
До 50 000 на файл |
|
Размер файла |
До 50 МБ |
|
Модель |
Одна на весь файл |
|
Эндпоинт |
Один на весь файл |
|
Срок обработки |
До 24 часов |
Внутри запросов не поддерживаются:
-
параметры
streamиstore; -
инструменты, кроме
function, напримерweb_searchиfile_search; -
аудио и изображения во входных данных;
-
ссылки на файлы через
file_id;
Запросы с неподдерживаемыми параметрами возвращаются с ошибкой.
Тарификация
Стоимость обработки рассчитывается по входящим и исходящим токенам с учетом множителя Batch API — 0,5 от обычной стоимости запросов к выбранной модели.
Резервирование средств
При создании батча на балансе аккаунта резервируются средства на обработку всего файла. Сумма складывается из стоимости входящих токенов и предполагаемой стоимости исходящих токенов по цене пакетной обработки.
Количество исходящих токенов определяется отдельно для каждой строки:
-
если указан
max_tokens, для расчета используется это значение; -
если
max_tokensне указан, резерв рассчитывается исходя из максимальной длины ответа выбранной модели —max_completion_tokens. Этот максимум учитывается для каждого запроса в файле, поскольку заранее определить фактическую длину ответов невозможно.
Поэтому без max_tokens сумма резерва может значительно превышать итоговую стоимость обработки. Чтобы ограничить резерв, указывайте значение с учетом ожидаемой длины ответа.
Зарезервированная сумма сразу вычитается из отображаемого баланса и становится недоступна для других платных действий. При этом окончательная стоимость батча определяется только после завершения обработки.
Средства на работу других сервисов
Для создания батча на аккаунте должно хватать средств не только на резерв, но и на 30 часов работы остальных сервисов. Это необходимо, чтобы резервирование средств для батча не приводило к их блокировке.
Например, если на балансе 5 000 ₽, а остальные сервисы расходуют 500 ₽ в сутки, на 30 часов их работы потребуется:
500 × 30 / 24 = 625 ₽.
Для резервирования под батч останется 4 375 ₽, если на аккаунте нет других зарезервированных сумм.
Если доступных средств недостаточно, API вернет ошибку 402 Insufficient funds. В этом случае можно пополнить баланс, уменьшить количество запросов в файле или сократить максимальную длину ответа.
Списание после обработки
После завершения батча рассчитывается стоимость фактически использованных токенов. Оплачиваются только успешные запросы с кодом 200. Запросы с ошибками не оплачиваются.
Неиспользованная часть резерва сразу возвращается в доступный баланс. Например, если для батча было зарезервировано 1 000 ₽, а фактическая стоимость обработки составила 200 ₽, на балансе снова станут доступны 800 ₽.
Фактический расход отображается в истории расходов как расход по модели.
Если батч завершился со статусом:
-
expiredилиcancelled— оплачиваются успешные запросы, которые успели выполниться; остаток резерва возвращается в доступный баланс; -
failed— списания нет, весь резерв возвращается в доступный баланс.
Дневные лимиты ключа
Batch API учитывает дневные лимиты API-ключа. При создании батча проверяется, укладывается ли оценка расхода в оставшийся лимит в рублях или токенах. Фактический расход записывается в лимит после завершения обработки.
Например, если оставшийся дневной лимит составляет 5 000 ₽, а батч без max_tokens требует резерва в 7 000 ₽, его создание будет отклонено. Батч не запустится и придет уведомление о достижении лимита. Это произойдет, даже если фактическая стоимость обработки была бы сильно ниже лимита (например, 500 ₽): при создании проверяется сумма резерва.
При отказе дневной лимит не расходуется.
Пример пакетной обработки запросов
Рассмотрим пример пакетного перевода двух текстов с помощью модели openai/gpt-4.1-mini.
Подготовка файла с запросами
Создайте файл batch.jsonl со следующим содержимым:
{"custom_id":"1","method":"POST","url":"/v1/chat/completions","body":{"model":"openai/gpt-4.1-mini","messages":[{"role":"user","content":"Переведи на русский: Hello!"}],"max_tokens":500}}
{"custom_id":"2","method":"POST","url":"/v1/chat/completions","body":{"model":"openai/gpt-4.1-mini","messages":[{"role":"user","content":"Переведи на русский: Thank you for your order."}],"max_tokens":500}}
Каждый JSON-объект должен занимать одну строку. Объединять запросы в массив и ставить запятые между строками не нужно.
Параметры:
-
custom_id— идентификатор запроса, уникальный в пределах файла. По нему вы сможете сопоставить ответ с исходным запросом. -
method— HTTP-метод. -
url— эндпоинт для обработки запроса:/v1/chat/completionsдля чат-моделей или/v1/embeddingsдля создания эмбеддингов. Значение должно быть одинаковым во всех строках файла. -
body— тело запроса к модели. В примере оно содержит имя моделиmodel, массив сообщенийmessagesи ограничение длины ответаmax_tokens.
Для чат-запросов рекомендуем задавать max_tokens с учетом ожидаемой длины ответа. Этот параметр влияет на сумму, которая резервируется при создании батча. Без него резерв будет больше.
Загрузка файла
Отправьте файл через Files API с назначением purpose=batch:
curl --request POST \ --url https://api.timeweb.ai/v1/files \ --header "Authorization: Bearer $TIMEWEB_AI_TOKEN" \ --form "purpose=batch" \ --form "file=@batch.jsonl"
Параметры:
-
purpose— назначение файла. Для пакетной обработки укажитеbatch. -
file— путь к файлу на локальном компьютере. Перед путем указывается символ@.
Для файлов с purpose=batch модель определяется из содержимого файла. Параметр target_model_names передавать не нужно.
Сохраните значение id из ответа — оно понадобится для создания батча.
Создание батча
Отправьте POST-запрос на эндпоинт /v1/batches:
curl --request POST \ --url https://api.timeweb.ai/v1/batches \ --header "Authorization: Bearer $TIMEWEB_AI_TOKEN" \ --header "Content-Type: application/json" \ --data '{ "input_file_id": "FILE_ID", "endpoint": "/v1/chat/completions", "completion_window": "24h" }'
Параметры:
-
input_file_id— идентификатор загруженного файла. ЗаменитеFILE_IDна значениеidиз предыдущего шага. -
endpoint— эндпоинт обработки. Он должен совпадать со значениемurlв строках файла. -
completion_window— срок обработки батча. Укажите24h.
В ответе API вернет объект батча со статусом validating. Сохраните его id для проверки статуса и отмены задачи.
При создании батча на балансе резервируются средства на обработку всего файла. Если доступных средств недостаточно, API вернет ошибку 402 Insufficient funds.
Проверка статуса
Чтобы узнать состояние батча, отправьте GET-запрос, заменив BATCH_ID на его идентификатор:
curl --request GET \ --url "https://api.timeweb.ai/v1/batches/BATCH_ID" \ --header "Authorization: Bearer $TIMEWEB_AI_TOKEN"
Текущее состояние отображается в поле status:
|
Статус |
Описание |
|
|
Выполняется проверка входных данных |
|
|
Запросы обрабатываются |
|
|
Подготавливаются результаты |
|
|
Обработка завершена. В отдельных запросах могут быть ошибки |
|
|
Батч завершился с ошибкой |
|
|
Истек срок обработки |
|
|
Батч отменен |
Повторяйте запрос для проверки состояния, пока обработка не завершится. Успешный батч проходит статусы validating → in_progress → finalizing → completed. Статусы failed, expired и cancelled также означают завершение задачи — ждать перехода в completed в этих случаях не нужно.
Получить список батчей, доступных текущему ключу, можно отдельным запросом:
curl --request GET \ --url https://api.timeweb.ai/v1/batches \ --header "Authorization: Bearer $TIMEWEB_AI_TOKEN"
Получение результатов
После завершения обработки получите актуальную информацию о батче. Для скачивания файлов используются поля:
-
output_file_id— идентификатор файла с результатами; -
error_file_id— идентификатор файла с ошибками отдельных запросов.
Если в поле output_file_id есть идентификатор, подставьте его вместо OUTPUT_FILE_ID и скачайте результаты:
curl --request GET \ --url "https://api.timeweb.ai/v1/files/OUTPUT_FILE_ID/content" \ --header "Authorization: Bearer $TIMEWEB_AI_TOKEN" \ --output results.jsonl
Результаты сохранятся в файл results.jsonl в текущей директории. Каждая строка содержит JSON-объект с полями:
-
custom_id— идентификатор исходного запроса; -
response.status_code— HTTP-код ответа; -
response.body— тело ответа модели; -
error— информация об ошибке, если она есть.
Порядок строк в результатах может отличаться от порядка во входном файле. Сопоставляйте запросы и ответы по custom_id.
Пример строки из файла результатов для первого запроса:
{"id":"batch_req_b83d7a9e420f4c6198a56e2d03f7c145","custom_id":"req-a7f3","response":{"status_code":200,"request_id":"e7294b18-6c3a-4f85-9d02-a147c8e65b30","body":{"id":"chatcmpl-K7m2R9v4N6p8T1x3B5q0C2d4F6h8J","object":"chat.completion","created":1791804147,"model":"gpt-4.1-mini-2025-04-14","choices":[{"index":0,"message":{"role":"assistant","content":"\u041f\u0440\u0438\u0432\u0435\u0442!","refusal":null,"annotations":[]},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":15,"completion_tokens":3,"total_tokens":18,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"service_tier":"default","system_fingerprint":"fp_a83b72d901"}},"error":null}
Значение content в этом примере — «Привет!». Кириллица записывается в виде Unicode escape-последовательностей \uXXXX: это экранирование символов в JSON.
Если у вас установлен jq, вывести идентификатор и текст ответа для каждой строки можно командой:
jq -r '[.custom_id, .response.body.choices[0].message.content] | @tsv' results.jsonl
Для двух запросов из примера вывод может выглядеть так:
1 Привет! 2 Спасибо за ваш заказ.
Если в поле error_file_id есть идентификатор, скачайте файл ошибок, заменив ERROR_FILE_ID на его значение:
curl --request GET \ --url "https://api.timeweb.ai/v1/files/ERROR_FILE_ID/content" \ --header "Authorization: Bearer $TIMEWEB_AI_TOKEN" \ --output errors.jsonl
Статус completed не гарантирует, что все запросы выполнены успешно. Проверьте файл ошибок: он содержит код и описание ошибки для каждого неуспешного запроса. Исправленные запросы можно отправить новым батчем.
При отмене батча или истечении срока обработки запросы, которые успели выполниться, доступны в результатах.
Файл результатов хранится 30 дней. Скачайте его до окончания этого срока.
Пример пакетного создания эмбеддингов
Для пакетного создания embeddings подготовьте отдельный JSONL-файл. Используйте модель, для которой включена пакетная обработка, и эндпоинт /v1/embeddings.
Например, строка запроса для модели openai/text-embedding-3-large выглядит так:
{"custom_id":"embedding-1","method":"POST","url":"/v1/embeddings","body":{"model":"openai/text-embedding-3-large","input":"Текст для векторизации"}}
Загрузите файл с purpose=batch, затем создайте батч со значением endpoint равным /v1/embeddings. Проверка статуса и получение результатов выполняются так же, как для чат-запросов.
Отмена батча
Чтобы отменить обработку, отправьте POST-запрос, заменив BATCH_ID на идентификатор батча:
curl --request POST \ --url "https://api.timeweb.ai/v1/batches/BATCH_ID/cancel" \ --header "Authorization: Bearer $TIMEWEB_AI_TOKEN"
Успешные запросы, выполненные до отмены, попадут в результаты и будут оплачены. Остальные запросы не выполняются и не оплачиваются. Неиспользованный резерв возвращается в доступный баланс.