Техническое руководство
Correlation ID для video API и webhook: как связать задачу, статус и callback
Correlation ID для video API и webhook позволяет команде проследить одну асинхронную операцию от серверного создания задачи до проверенного callback, не записывая в логи ключи, исходный media-файл или полный ответ. Это особенно важно, когда пользователь нажал кнопку повторно, доставка события задержалась или результат нельзя считать готовым только по одному сообщению. RussiaAPI остаётся независимым gateway: названия полей, модели и статусы подтверждаются текущим каталогом и вашим контрактом.
RUSSIAAPI_API_KEY; не передавайте внешние ключи, cookie, пароли, коды подтверждения или лишние персональные данные.Не путайте три разных идентификатора
Внутренний operation ID создаёт ваше приложение до сети. Он связывается с пользователем, проектом, дедупликацией и правилами доступа. Task ID приходит после принятия асинхронной задачи внешним маршрутом. Event ID относится к конкретной доставке webhook. Эти значения решают разные задачи, поэтому нельзя подменять один другим или показывать task ID как доказательство готового видео.
Храните минимальную связку: operation ID, task ID, последнюю версию статуса, время обновления и безопасный request ID. Добавьте уникальное ограничение на operation ID и на пару task ID плюс event ID. Тогда повторный callback не создаст второй результат, а оператор сможет ответить на вопрос о состоянии без доступа к телу запроса. Детали создания асинхронной работы есть в руководстве по видео-задачам.
Создавайте задачу один раз
До вызова video API backend создаёт запись операции со статусом pending и idempotency key, если такой механизм поддержан вашим собственным контрактом. После успешного принятия он записывает task ID в той же логической операции. Если ответ потерялся после timeout, не запускайте новую генерацию автоматически: сначала найдите операцию по своему ключу и выполните разрешённую сверку статуса.
Эта схема защищает бюджет и пользовательский опыт. Таймаут ответа не означает, что задача не существует. Повторный клик пользователя тоже не является разрешением создать вторую платную операцию. Покажите понятное состояние «проверяем статус», а не обещание готовности. Практическая схема ключа и таблицы состояний разобрана в материале об idempotency key.
Webhook — сигнал, а не безусловная истина
Получив callback, сначала проверьте подпись по raw body согласно текущему контракту, затем дедуплицируйте event ID и только после этого обновляйте внутреннюю запись. Не доверяйте произвольному task ID в payload и не делайте дорогую работу прямо в HTTP обработчике. Быстро подтвердите приём, положите безопасное событие в очередь и обработайте его транзакционно.
Статус succeeded ещё не равен разрешению немедленно показать URL любому пользователю. Сверьте владельца operation ID, политику выдачи, срок хранения и факт наличия результата. Не раскрывайте временную ссылку в общих логах или сообщениях поддержки. Технические границы подписи описаны в проверке webhook, а повторная доставка — в подходе с DLQ.
Пример безопасной связки событий
Ниже Node.js 18+ пример показывает упрощённую серверную обработку уже проверенного события. В реальном сервисе проверка подписи должна работать с raw body до JSON.parse, а обновление базы — выполняться атомарно. Пример намеренно не содержит ключей, URL результата, имён моделей или предположения о наборе webhook полей.
export function applyVerifiedVideoEvent(store, event) {
if (!event?.eventId || !event.taskId || !event.state) return { ok: false, reason: 'invalid_event' };
if (store.seenEventIds.has(event.eventId)) return { ok: true, duplicate: true };
const operation = store.findByTaskId(event.taskId);
if (!operation) return { ok: false, reason: 'unknown_task' };
if (operation.state === 'completed') return { ok: true, stale: true };
store.transaction(() => {
store.seenEventIds.add(event.eventId);
store.update(operation.id, { state: event.state, updatedAt: new Date().toISOString() });
});
return { ok: true, operationId: operation.id };
}Проверьте синтаксис с node --check. В тестах передайте один event дважды, callback с неизвестным task ID и более старое событие после нового. Ожидаемый результат — одна запись операции и отсутствие повторной выдачи.
Сверяйте расхождения по расписанию
Webhook может не прийти, прийти поздно или быть обработан после кратковременного сбоя вашего сервиса. Поэтому полезен ограниченный reconciler: он выбирает только старые pending операции, сверяет статус разрешённым read-only способом и записывает результат с теми же правилами дедупликации. Частоту, лимит и доступность такого запроса определяет ваш текущий контракт, а не этот пример.
Отдельно измеряйте возраст pending задач, долю неизвестных callback, повторные event ID и время между созданием и подтверждением. Эти метрики помогают заметить инцидент, но не являются SLA и не дают права обходить ограничения. Если результат требует проверки прав на исходные материалы или способ публикации, остановите выдачу до решения владельца. Обязанности по контенту описаны в чек-листе прав.
Минимальный операционный контур
Для любого сценария заранее определите владельца операции, внутренний идентификатор, допустимый срок ожидания и событие, после которого результат считается подтверждённым. В журнале достаточно хранить время, статус, безопасный request ID, тип операции и версию вашего адаптера. Полный prompt, ответ пользователя, заголовок Authorization и временные ссылки не нужны для базовой диагностики и часто создают лишний риск.
Проверяйте изменения на обезличенном тестовом наборе и с отдельным собственным ключом, ограниченным бюджетом и правами. Нельзя по единичному удачному вызову делать вывод, что все модели, параметры, цены или возможности доступны постоянно. Перед расширением трафика сверяйте текущий каталог, права проекта, условия обработки данных и фактические сигналы своего приложения.
Ошибки 400, 401, 403, 429, timeout и 5xx требуют разных действий. Не скрывайте их бесконечным retry, не меняйте модель молча и не используйте интеграцию для обхода законов, санкций, региональных или платформенных ограничений. Если состояние операции после timeout неизвестно, сначала проверьте своё внутреннее хранилище, а затем выполняйте только явно разрешённый и ограниченный шаг.
Проверьте сценарий в RussiaAPI
Создайте собственный тестовый ключ в консоли, сверьте текущий каталог моделей и выполните обезличенный server-side smoke test. Расширяйте нагрузку и доступ только после измеримой проверки.
FAQ
Можно ли использовать task ID как correlation ID?
Лучше нет. Task ID обычно появляется после отправки задачи и относится к внешнему маршруту. Внутренний operation ID создаётся раньше, связывает владельца и дедупликацию, а event ID различает повторные доставки webhook.
Почему нельзя сразу выдавать результат после callback?
Сначала нужны проверка подписи, дедупликация, сверка владельца операции и правила доступа к результату. Callback сообщает о событии, но не отменяет ваши правила хранения, прав на контент или безопасной выдачи временной ссылки.
Нужен ли polling, если webhook уже есть?
Иногда нужен ограниченный reconciler для старых pending операций, потому что доставка может задержаться или ваш обработчик мог быть недоступен. Он должен быть лимитированным, безопасным и не создавать новые video-задачи при каждой проверке.