Batch запросы
Много запросов одним пакетом, результаты забираете позже. Удобно, когда ответ не нужен сразу: прогон датасета, ночная генерация, массовые эмбеддинги.
Окно выполнения — 24 часа. После завершения результаты приходят в том же GET, отдельный файл скачивать не нужно.
Какие модели
Обычное имя из каталога: claude-opus-4.8, gpt-5.4. Batch есть, если у модели в каталоге поле batch:
{
"batch": { "discount": 0.5, "window": "24h" }
}Прямые маршруты отдельных провайдеров в Batch не ходят — только модели с полем batch.
Эндпоинты
| Метод | Путь | Что делает |
|---|---|---|
POST | /v1/batches | Создать пакет, 202 Accepted |
GET | /v1/batches | Список ваших пакетов |
GET | /v1/batches/{id} | Статус и результаты |
Отмены нет: провайдер начинает работу сразу и выставляет нам счёт независимо от того, ждёте вы результат. «Отмена» означала бы вернуть вам деньги за уже оплаченную нами работу.
Bearer, что для чатаФорма запроса
endpointmodelrequestscustom_id и bodycustom_id уникален внутри пакета. body — то же, что вы бы отправили на выбранный endpoint. Модель в body можно не ставить: берётся верхний model. Если поставить — должно совпасть.
Один пакет — одна модель и один endpoint, не больше 10 000 запросов.
endpoint | API |
|---|---|
/v1/chat/completions | Chat Completions |
/v1/responses | Responses |
/v1/messages | Messages |
/v1/embeddings | Embeddings |
Отправка
curl https://api.daaj.ru/v1/batches \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-VTOP Ai-xxx" \
-d '{
"endpoint": "/v1/chat/completions",
"model": "claude-opus-4.8",
"requests": [
{
"custom_id": "req-0001",
"body": {
"messages": [
{ "role": "user", "content": "Суммируй VTOP Ai одним предложением." }
]
}
}
]
}'Успешный POST возвращает 202 и объект со статусом validating — пакет принят и встал в очередь, это ещё не готовые ответы.
{
"id": "batch_123",
"object": "batch",
"endpoint": "/v1/chat/completions",
"model": "claude-opus-4.8",
"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
}Единственное окно — 24h.
Опрос
curl https://api.daaj.ru/v1/batches/batch_123 \
-H "Authorization: Bearer sk-VTOP Ai-xxx"Цепочка статусов:
validating → in_progress → finalizing → completedЕщё бывают failed, expired, cancelling, cancelled. Терминальные: completed, failed, expired, cancelled. Опрашивайте, пока не дойдёте до одного из них.
Опрос нужен только чтобы узнать результат. Пакет мы досчитываем сами: раз в минуту планировщик проверяет незавершённые задачи, поэтому резерв освобождается без вашего участия — даже если процесс, отправивший пакет, давно завершился. Можно спокойно закрыть скрипт и вернуться за results позже.
Сразу после POST пакет может пару десятков секунд не находиться у провайдера — в это время GET вернёт статус из нашей записи (validating). Это нормально, повторите опрос.
request_counts — прогресс: total, completed, failed.
Пока пакет не completed, results равен null. После — массив в том же ответе. Каждый элемент склеивается со входом по custom_id. Заполнено ровно одно: response или error.
{
"id": "batch_req_123",
"custom_id": "req-0001",
"response": {
"status_code": 200,
"request_id": "request_123",
"body": {
"id": "gen-…",
"object": "chat.completion",
"model": "claude-opus-4.8",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "VTOP Ai — единый API к сотням моделей с оплатой в рублях."
},
"finish_reason": "stop"
}
]
}
},
"error": null
}Списание
При POST на балансе резервируется оценка (худший случай по составу пакета, уже со скидкой Batch). Резерв — это не списание: деньги удержаны, но ещё не потрачены, и в истории расходов их нет.
Когда пакет доходит до терминального статуса, списывается факт, а лишнее возвращается. При failed / expired / cancelled резерв возвращается целиком и списания не появляется вообще. Больше зарезервированного с вас не спишут: если провайдер выставил нам больше, разницу оплачиваем мы.
У пакета есть жёсткий срок (expires_at, чуть больше суток — окно выполнения плюс запас). Если к этому времени результата нет, пакет переводится в expired и резерв возвращается полностью. Зависнуть навсегда, удерживая деньги, пакет не может.
Итог в рублях — usage.cost_rub после completed.
Список пакетов и кабинет
# Ваши пакеты, новые сверху
curl "https://api.daaj.ru/v1/batches?limit=20" \
-H "Authorization: Bearer sk-VTOP Ai-xxx"
# Все асинхронные задачи (пакеты и видео), которые ещё держат резерв
curl "https://api.daaj.ru/v1/jobs?active=true" \
-H "Authorization: Bearer sk-VTOP Ai-xxx"Параметры списка: status, active=true, limit (до 100), after. GET /v1/jobs дополнительно возвращает active_count и active_reserved_rub — сколько задач выполняется и сколько рублей они держат; у каждой записи есть kind, reserved_rub, а после расчёта cost_rub и refunded_rub. Чужой id вернёт 404.
То же самое без кода — Статистика → Задачи в кабинете: сумма резерва, статусы, фактическое списание и возврат, фильтры по типу и статусу. Результаты завершённого пакета оттуда можно выгрузить в JSON. Во вкладке «Расходы» рядом — только фактически потраченное, резервы туда не попадают.
Другие формы API
Все элементы одного пакета — один endpoint. Смешать формы — несколько пакетов.
Пример Messages:
{
"endpoint": "/v1/messages",
"model": "claude-opus-4.8",
"requests": [
{
"custom_id": "req-1",
"body": {
"max_tokens": 32,
"messages": [
{ "role": "user", "content": "Скажи привет." }
]
}
}
]
}/v1/embeddings работает так же, если у модели в каталоге есть batch. В body обязательно input (строка или массив строк). Картинки и прочий мультимодальный вход в Batch не принимаются — для них синхронный /embeddings.
Ограничения
- Только текст. Картинки, аудио, видео, файлы в элементах пакета отклоняются. Для них — обычные синхронные эндпоинты.
- На части моделей все
bodyв пакете должны иметь одинаковыйresponse_format(или все без него). Иначе пакет не пройдёт проверку. - Имена пресетов в
modelне подходят — только каталожные id.