Documentation Index Fetch the complete documentation index at: https://docs.runblob.io/llms.txt
Use this file to discover all available pages before exploring further.
Webhooks доставляют мгновенные уведомления о завершении, ошибке или таймауте генерации видео. Без polling!
Руководство по настройке
Создайте webhook-эндпоинт
Поднимите HTTPS-эндпоинт, принимающий POST-запросы. from flask import Flask, request, jsonify
app = Flask( __name__ )
@app.route ( '/webhook' , methods = [ 'POST' ])
def handle_webhook ():
data = request.json
if data[ 'status' ] == 'completed' :
print ( f "Video ready: { data[ 'video_url' ] } " )
else :
error_msg = data.get( 'error' , {}).get( 'message' , 'Unknown error' )
print ( f "Generation failed: { error_msg } " )
return jsonify({ 'status' : 'received' }), 200
Передайте URL webhook
Укажите URL вашего webhook при создании задачи генерации. curl -X POST https://platform.runblob.io/v1/veo/generate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "A sunset over mountains",
"callback_url": "https://your-app.com/webhook"
}'
Обработайте уведомления
Ваш эндпоинт получит мгновенное уведомление по готовности задачи.
Структура payload
Отправляется при успешной генерации видео. {
"generation_id" : "ffd473d5-5bef-4e14-bf22-8d559be3c19f" ,
"status" : "completed" ,
"prompt" : "A cat playing with a ball in a sunny room" ,
"video_url" : "https://cdn.runblob.io/videos/your-video.mp4" ,
"created_at" : "2025-12-06T21:43:03.374000" ,
"completed_at" : "2025-12-06T21:44:06.143000" ,
"seed" : 319790131 ,
"error" : null
}
Всегда "completed" при успешной генерации
Исходный промпт для генерации
Прямая ссылка для скачивания готового видео
Временная метка создания задачи (ISO 8601)
Временная метка завершения задачи (ISO 8601)
Всегда null при успешной генерации
Отправляется при ошибке генерации с конкретным кодом. {
"generation_id" : "ffd473d5-5bef-4e14-bf22-8d559be3c19f" ,
"status" : "failed" ,
"prompt" : "A cat playing with a ball in a sunny room" ,
"video_url" : null ,
"created_at" : "2025-12-06T21:43:03.374000" ,
"completed_at" : "2025-12-06T21:44:06.143000" ,
"seed" : 319790131 ,
"error" : {
"message" : "UNSAFE_CONTENT" ,
"details" : {}
}
}
Всегда "failed" при ошибке
Описание ошибки: message (код) и details (см. Коды ошибок ) Всегда null при неудачной задаче
Отправляется при превышении лимита в 10 минут. {
"generation_id" : "ffd473d5-5bef-4e14-bf22-8d559be3c19f" ,
"status" : "failed" ,
"prompt" : "A cat playing with a ball in a sunny room" ,
"video_url" : null ,
"created_at" : "2025-12-06T21:43:03.374000" ,
"completed_at" : "2025-12-06T21:44:06.143000" ,
"seed" : 319790131 ,
"error" : {
"message" : "TIMEOUT" ,
"details" : {}
}
}
Кредиты автоматически возвращаются при таймауте.
Возможности надёжности
Политика повторов: до 5 попыток с интервалом 30 секундСтратегия задержки: линейная между повторамиОбработка отказа: после 5 неудачных попыток webhook помечается как failed
Тайм-аут запроса: 30 секунд на webhookТайм-аут соединения: 10 секунд для установления соединенияРекомендация: быстро отвечайте кодом 200
HTTPS обязателен: все URL webhook должны использовать HTTPSIP allowlist: рассмотрите ограничение доступа по IP RunBlobВалидация: всегда проверяйте generation_id в обработчике webhook
Примеры реализации
from flask import Flask, request, jsonify
import logging
app = Flask( __name__ )
logging.basicConfig( level = logging. INFO )
@app.route ( '/webhook' , methods = [ 'POST' ])
def runblob_webhook ():
try :
data = request.json
generation_id = data.get( 'generation_id' )
status = data.get( 'status' )
if status == 'completed' :
video_url = data.get( 'video_url' )
logging.info( f "Video ready for { generation_id } : { video_url } " )
# Process successful generation
process_video(generation_id, video_url)
else :
error = data.get( 'error' , {})
error_code = error.get( 'message' , 'Unknown error' )
logging.error( f "Generation failed for { generation_id } : { error_code } " )
# Handle failure
handle_failure(generation_id, error_code)
return jsonify({ 'status' : 'received' }), 200
except Exception as e:
logging.error( f "Webhook error: { str (e) } " )
return jsonify({ 'error' : 'Internal error' }), 500
def process_video ( generation_id , video_url ):
# Your video processing logic here
pass
def handle_failure ( generation_id , error_code ):
# Your error handling logic here
pass
Важно: всегда быстро возвращайте код 200, чтобы подтвердить получение. Тяжёлую обработку выполняйте асинхронно, чтобы избежать таймаутов.