YouTube Transcript API Rate Limit: What It Is and How to Handle 429s

Why APIs return 429 Too Many Requests, what RFC 6585 and the Retry-After header actually specify, how rate limits differ from daily quota, and how to implement correct retry and backoff logic.

00:08:00 · SEP 13, 2026

Краткий ответ

Код 429 означает, что вы отправляете запросы быстрее, чем позволяет лимит запросов в минуту вашего тарифа — это не связано с кредитами или суточной квотой. Если в ответе есть заголовок Retry-After, подождите ровно указанное время. Если его нет, используйте экспоненциальный откат со случайным разбросом (jitter) и отдельно ограничивайте, сколько запросов у вас в работе одновременно.

Лимит частоты запросов и квота

Это два разных ограничения, которые часто путают:

  • Квота — общее число разрешённых запросов за более длинный период (например, за день). Исчерпание означает ожидание сброса, иногда через много часов.
  • Лимит частоты запросов — число запросов, разрешённых за короткий период (например, за минуту). Достижение лимита означает замедление на секунды или минуту, а не часы.

Под капотом большинство API реализуют ограничение частоты запросов либо через token bucket (вы накапливаете «токены» запросов с постоянной скоростью и тратите по одному на запрос, что допускает короткие всплески), либо через счётчик с фиксированным/скользящим окном (жёсткий лимит на календарную минуту, сбрасываемый на границе). То, какой из вариантов использует конкретный API, влияет на то, насколько «взрывным» может безопасно быть ваш трафик — token bucket лучше переносит короткий всплеск, чем фиксированное окно.

Стандарт HTTP: RFC 6585 и Retry-After

429 Too Many Requests — это не частный фольклор конкретного провайдера: он был формально определён в RFC 6585 (апрель 2012) как стандартный код состояния HTTP. Согласно RFC 9110, соответствующий стандарту сервер может прикрепить заголовок Retry-After к ответу 429 (или 503) в одной из двух форм:

  • Форма задержки в секундах — целое число, например Retry-After: 120, что означает подождать 120 секунд.
  • Форма HTTP-даты — абсолютная метка времени, например Retry-After: Wed, 21 Oct 2026 07:28:00 GMT.

Если этот заголовок присутствует, он является авторитетным — сервер прямо говорит вам, когда он снова начнёт принимать запросы. Не накладывайте свой собственный экспоненциальный откат поверх него — это лишь дополнительно отсрочит восстановление. Прибегайте к откату только тогда, когда заголовок отсутствует.

Лимиты частоты запросов GetYouTubeTranscript

ТарифЛимит запросов
Бесплатный60 запросов/мин
Помесячный ($5/мес)200 запросов/мин
Годовой ($4.50/мес)300 запросов/мин

Как это реально применяется

Это фиксированное окно в 1 минуту на API-ключ, а не скользящее окно и не token bucket — счётчик сбрасывается на границе минуты по часам. Сейчас заголовок Retry-After не отправляется, поэтому любой 429 от этого API стоит трактовать как «подождите до ~60 секунд и повторите с откатом», используя приведённый ниже шаблон кода, а не разбирая заголовок, которого там не будет.

Правильная обработка 429

Правильный порядок действий: сначала проверьте Retry-After, и только если он отсутствует, переходите к экспоненциальному откату со случайным разбросом. Разброс (небольшая рандомизация задержки) важен, потому что когда много клиентов одновременно упираются в лимит и все повторяют попытку по одинаковому расписанию, они синхронизируются и создают «эффект грозовой толпы» (thundering herd), который мгновенно повторно провоцирует тот же лимит.

Node.js:

async function getTranscriptWithRetry(videoId, apiKey, maxRetries = 4) {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    const res = await fetch(
      `https://getyoutubetranscript.com/api/v1/transcript?v=${videoId}`,
      { headers: { Authorization: `Bearer ${apiKey}` } }
    );
    if (res.status !== 429) return res.json();

    const retryAfter = res.headers.get('retry-after');
    const waitMs = retryAfter
      ? Number(retryAfter) * 1000
      : 500 * 2 ** attempt + Math.random() * 250; // exponential backoff + jitter
    await new Promise((r) => setTimeout(r, waitMs));
  }
  throw new Error('Rate limited after retries');
}

Python:

import os, time, random, requests

def get_transcript_with_retry(video_id, api_key, max_retries=4):
    url = "https://getyoutubetranscript.com/api/v1/transcript"
    for attempt in range(max_retries + 1):
        res = requests.get(url, params={"v": video_id}, headers={"Authorization": f"Bearer {api_key}"})
        if res.status_code != 429:
            return res.json()

        retry_after = res.headers.get("Retry-After")
        wait = float(retry_after) if retry_after else (0.5 * 2 ** attempt + random.uniform(0, 0.25))
        time.sleep(wait)
    raise RuntimeError("Rate limited after retries")

Частота и одновременность — разные проблемы

Потолок запросов в минуту и потолок одновременных соединений — это не одно и то же. Одновременный запуск 50 запросов через Promise.all может спровоцировать 429, даже если ваш итог за минуту хорошо укладывается в бюджет, потому что сервер (или прокси перед ним) может также ограничивать число одновременных соединений. При пакетной обработке множества видео ограничивайте параллелизм отдельно от отката по лимиту частоты запросов:

import pLimit from 'p-limit';

const limit = pLimit(5); // at most 5 requests in flight at once
const results = await Promise.all(
  videoIds.map((id) => limit(() => getTranscriptWithRetry(id, apiKey)))
);

Для устойчивых высокообъёмных пакетов повышение тарифа напрямую увеличивает потолок запросов в минуту — см. тарифы в документации API или начните с 100 бесплатных кредитов в панели управления.

Часто задаваемые вопросы о лимите частоты запросов

Q01

В чём разница между лимитом частоты запросов и квотой?

Квота ограничивает общее использование за период (например, за день). Лимит частоты запросов ограничивает, сколько запросов вы можете сделать за единицу времени (например, за минуту), независимо от вашего общего суточного использования — вы можете упереться в лимит частоты запросов, оставаясь при этом далеко от суточной квоты. Сторону квоты см. в нашем руководстве по квоте YouTube API.

Q02

Что означает ответ 429?

429 Too Many Requests был формально определён в RFC 6585 в 2012 году. Это означает, что вы превысили лимит запросов на окно для вашего тарифа — это сигнал замедлиться и повторить попытку, а не то, что ваш запрос был некорректным или у вас закончились кредиты.

Q03

Что такое заголовок Retry-After, и всегда ли ему стоит доверять?

Согласно RFC 9110, сервер может включить заголовок Retry-After в ответ 429 или 503, в одной из двух форм: целое число секунд (Retry-After: 120) или абсолютная HTTP-дата. Если он присутствует, соблюдайте его точно, а не накладывайте поверх свой собственный откат — сервер дал вам авторитетный ответ о том, когда повторить попытку.

Q04

Какой лимит частоты запросов у GetYouTubeTranscript, и отправляет ли он заголовок Retry-After?

60 запросов в минуту на бесплатном тарифе, 200 запросов/мин на помесячном и 300 запросов/мин на годовом, применяется как фиксированное окно в 1 минуту на API-ключ (не скользящее окно). Сейчас заголовок Retry-After на 429 не отправляется, поэтому реализуйте собственный откат (см. код ниже), а не рассчитывайте на него — поскольку окно фиксированное, а не скользящее, ожидание составит максимум остаток текущей минуты.

Q05

Списывается ли кредит за 429?

Нет — запрос, ограниченный по частоте, никогда не тарифицируется. Кредиты списываются только за успешные запросы.

Q06

Стоит ли открывать несколько API-ключей ради большей пропускной способности?

Нет — это обычно нарушает условия добросовестного использования провайдера, а в GetYouTubeTranscript лимит частоты запросов и так применяется отдельно на каждый API-ключ, но кредиты и статус аккаунта отслеживаются на уровне аккаунта независимо от того, сколько ключей вы создали. Если вам нужна большая пропускная способность, повысьте тариф — это напрямую увеличивает потолок запросов в минуту.

Q07

Почему мои запросы не проходят, хотя я не превышаю лимит запросов в минуту?

Обычно это проблема параллелизма, а не частоты — одновременный запуск 50 запросов может перегрузить сервер, даже если ваш итог за минуту укладывается в бюджет. Используйте ограничитель параллелизма (например, p-limit в Node или семафор в Python), чтобы ограничить число одновременных запросов, отдельно от того, сколько вы отправляете в минуту.

Похожие материалы