Skip to content

Рекламная статистика: Полное руководство

Подробная инструкция по получению всех данных рекламной статистики через SDK для фронт-энд и бэк-энд сервисов.

Содержание

Карта методов

Все методы для получения рекламных данных:

МетодЧто возвращаетRate LimitHTTP
getAdvFullstats()Полная статистика кампаний (клики, показы, заказы, по дням/платформам/SKU)3 req/min, интервал 20сGET
createAdvStat()Статистика медиа-кампаний (баннеры)600 req/minPOST
getAdvBalance()Баланс рекламного кабинета60 req/minGET
getAdvBudget()Бюджет кампании240 req/minGET
getAdvUpd()История расходов (УПД)60 req/minGET
getAdvPayments()История пополнений60 req/minGET
getCampaignCount()Список всех кампаний с ID300 req/minGET

Методы удалены в v4.0.0

Методы createAdvFullstat() (v2, POST), getStatsKeywords(), getStatWords(), getAutoStatWords(), getPromotionCount() и getAuctionAdverts() удалены в v4.0.0. Используйте getAdvFullstats() (v3, GET) для статистики и getCampaignCount() / getAdvertsV2() для списка кампаний.


Инициализация SDK

typescript
import { WildberriesSDK, RateLimitError } from 'daytona-wildberries-typescript-sdk';

const sdk = new WildberriesSDK({
  apiKey: process.env.WB_API_KEY!,
  retryConfig: {
    maxRetries: 3,
    retryDelay: 1000,
    exponentialBackoff: true,
  },
});

getAdvFullstats

Основной метод получения рекламной статистики. Возвращает полные данные по кампаниям: клики, показы, CTR, CPC, заказы, расходы — с разбивкой по дням, платформам и SKU.

Параметры

ПараметрТипОбязательныйОписание
idsstringДаID кампаний через запятую. Максимум 100
beginDatestringДаНачало периода, формат YYYY-MM-DD
endDatestringДаКонец периода, формат YYYY-MM-DD

Ограничения

  • Максимальный период: 31 день от beginDate
  • Работает только для кампаний в статусах: 7 (завершена), 9 (активна), 11 (на паузе)
  • Rate limit: 3 запроса в минуту, интервал 20 секунд

Базовый пример

typescript
const stats = await sdk.promotion.getAdvFullstats({
  ids: '24483511,23332267',     // ⚠️ Строка, НЕ число!
  beginDate: '2025-12-01',      // ⚠️ Именно beginDate, НЕ nDate, НЕ from
  endDate: '2025-12-31',        // ⚠️ Именно endDate, НЕ to
});

for (const campaign of stats) {
  console.log(`Кампания ${campaign.advertId}:`);
  console.log(`  Показы: ${campaign.views}`);
  console.log(`  Клики: ${campaign.clicks}`);
  console.log(`  CTR: ${campaign.ctr}%`);
  console.log(`  CPC: ${campaign.cpc}₽`);
  console.log(`  Заказы: ${campaign.orders}`);
  console.log(`  Расход: ${campaign.sum}₽`);
  console.log(`  В корзину: ${campaign.atbs}`);
  console.log(`  CR: ${campaign.cr}%`);
  console.log(`  Отмены: ${campaign.canceled}`);
}

Структура ответа

typescript
// Каждый элемент массива — одна кампания
interface FullStatsItem {
  advertId: number;    // ID кампании
  views: number;       // Общее количество показов
  clicks: number;      // Общее количество кликов
  ctr: number;         // Click-through rate, %
  cpc: number;         // Cost per click, ₽
  sum: number;         // Общий расход, ₽
  atbs: number;        // Добавлений в корзину
  orders: number;      // Заказы
  cr: number;          // Conversion rate, %
  shks: number;        // Количество товаров в заказах
  sum_price: number;   // Сумма заказов, ₽
  canceled: number;    // Отмены

  // Разбивка по дням
  days: Array<{
    date: string;          // "2025-12-17T00:00:00Z"
    views: number;
    clicks: number;
    ctr: number;
    cpc: number;
    sum: number;
    atbs: number;
    orders: number;
    cr: number;
    shks: number;
    sum_price: number;
    canceled: number;

    // Разбивка по платформам
    apps: Array<{
      appType: number;   // 1 = сайт, 32 = Android, 64 = iOS
      views: number;
      clicks: number;
      orders: number;
      sum: number;

      // Разбивка по SKU (товарам)
      nms: Array<{
        nmId: number;    // Артикул WB
        name: string;    // Название товара
        views: number;
        clicks: number;
        orders: number;
        sum: number;
      }>;
    }>;
  }>;

  // Средняя позиция (для кампаний с единой ставкой)
  boosterStats: Array<{
    date: string;
    nm: number;
    avg_position: number;
  }>;
}

Дневная статистика (adv_daily_stats)

Для получения ежедневной статистики используйте поле days из ответа:

typescript
const stats = await sdk.promotion.getAdvFullstats({
  ids: '24483511',
  beginDate: '2025-12-01',
  endDate: '2025-12-07',
});

// Ежедневная статистика
for (const campaign of stats) {
  console.log(`\n=== Кампания ${campaign.advertId} ===`);

  for (const day of campaign.days) {
    const date = day.date.split('T')[0]; // "2025-12-01"
    console.log(`${date}: показы=${day.views}, клики=${day.clicks}, ` +
      `CTR=${day.ctr}%, расход=${day.sum}₽, заказы=${day.orders}`);
  }
}

Статистика по платформам

typescript
const PLATFORMS: Record<number, string> = {
  1: 'Сайт',
  32: 'Android',
  64: 'iOS',
};

for (const campaign of stats) {
  for (const day of campaign.days) {
    const date = day.date.split('T')[0];
    console.log(`\n--- ${date} ---`);

    for (const app of day.apps) {
      const platform = PLATFORMS[app.appType] ?? `Unknown(${app.appType})`;
      console.log(`  ${platform}: показы=${app.views}, клики=${app.clicks}, ` +
        `заказы=${app.orders}, расход=${app.sum}₽`);
    }
  }
}

Статистика по SKU (товарам)

typescript
// Агрегация данных по товарам за весь период
interface SkuAggregated {
  nmId: number;
  name: string;
  views: number;
  clicks: number;
  orders: number;
  sum: number;
}

const skuMap = new Map<number, SkuAggregated>();

for (const campaign of stats) {
  for (const day of campaign.days) {
    for (const app of day.apps) {
      for (const nm of app.nms) {
        const existing = skuMap.get(nm.nmId) ?? {
          nmId: nm.nmId,
          name: nm.name,
          views: 0, clicks: 0, orders: 0, sum: 0,
        };

        existing.views += nm.views;
        existing.clicks += nm.clicks;
        existing.orders += nm.orders;
        existing.sum += nm.sum;

        skuMap.set(nm.nmId, existing);
      }
    }
  }
}

// Вывод по убыванию расходов
const sorted = [...skuMap.values()].sort((a, b) => b.sum - a.sum);
for (const sku of sorted) {
  console.log(`SKU ${sku.nmId} "${sku.name}": ` +
    `${sku.views} показов, ${sku.clicks} кликов, ` +
    `${sku.orders} заказов, ${sku.sum}₽`);
}

Обработка rate limit

typescript
import { RateLimitError } from 'daytona-wildberries-typescript-sdk';

const DELAY_BETWEEN_REQUESTS = 21_000; // 21 секунда
const MAX_IDS_PER_REQUEST = 100;

/**
 * Получает статистику для произвольного количества кампаний
 * с автоматической пагинацией и обработкой rate limit.
 */
async function getAllCampaignStats(
  campaignIds: number[],
  beginDate: string,
  endDate: string,
) {
  const results: FullStatsItem[] = [];

  // Разбиваем на батчи по 100 ID
  for (let i = 0; i < campaignIds.length; i += MAX_IDS_PER_REQUEST) {
    const batch = campaignIds.slice(i, i + MAX_IDS_PER_REQUEST);

    let attempt = 0;
    while (attempt < 3) {
      try {
        const stats = await sdk.promotion.getAdvFullstats({
          ids: batch.join(','),
          beginDate,
          endDate,
        });
        results.push(...stats);
        break; // Успешно, выходим из retry loop
      } catch (error) {
        if (error instanceof RateLimitError) {
          const waitMs = error.retryAfter ?? DELAY_BETWEEN_REQUESTS;
          console.warn(`Rate limit, ожидание ${waitMs}ms (попытка ${attempt + 1})`);
          await new Promise(r => setTimeout(r, waitMs));
          attempt++;
        } else {
          throw error; // Другие ошибки пробрасываем
        }
      }
    }

    // Пауза между батчами
    if (i + MAX_IDS_PER_REQUEST < campaignIds.length) {
      await new Promise(r => setTimeout(r, DELAY_BETWEEN_REQUESTS));
    }
  }

  return results;
}

getStatsKeywords (удалён в v4.0.0)

Удалено в v4.0.0

Метод getStatsKeywords() удалён в v4.0.0 (WB отключил v0/v1 advert API). Для статистики по ключевым словам и SKU используйте getAdvFullstats() — он возвращает данные по дням, платформам и SKU, включая показы, клики, CTR и расход.

Ранее метод возвращал статистику по ключевым словам из поиска (параметры advert_id, from, to, макс. 7 дней, домен api.wildberries.ru). Замена:

typescript
const stats = await sdk.promotion.getAdvFullstats({
  ids: '24483511',
  beginDate: format(weekAgo),
  endDate: format(today),
});

for (const campaign of stats) {
  console.log(`Кампания ${campaign.advertId}: показы=${campaign.views}, клики=${campaign.clicks}, CTR=${campaign.ctr}%`);
}

getStatWords (удалён в v4.0.0)

Удалено в v4.0.0

Метод getStatWords() удалён в v4.0.0. Для статистики по ключевым словам/SKU используйте getAdvFullstats().

Ранее метод возвращал статистику по ключевым словам для кампаний с ручной ставкой (параметр id, обновление каждые 30 минут). Замена — getAdvFullstats(), который возвращает универсальную статистику по дням, платформам и SKU.


getAutoStatWords (удалён в v4.0.0)

Удалено в v4.0.0

Метод getAutoStatWords() удалён в v4.0.0. Используйте getAdvFullstats().

Ранее метод возвращал кластеры ключевых фраз для кампаний с единой ставкой (type 8). Замена — getAdvFullstats().


createAdvStat

Статистика для медиа-кампаний (баннерная реклама WB Media). Отдельный API домен: advert-media-api.wildberries.ru.

Параметры

Принимает три формата запроса:

Формат 1: По датам

typescript
const stats = await sdk.promotion.createAdvStat([
  { id: 12345, dates: ['2025-12-01', '2025-12-02', '2025-12-03'] }
]);

Формат 2: По интервалу

typescript
const stats = await sdk.promotion.createAdvStat([
  { id: 12345, interval: { begin: '2025-12-01', end: '2025-12-07' } }
]);

Формат 3: Только по ID кампании (вся история)

typescript
const stats = await sdk.promotion.createAdvStat([
  { id: 12345 }
]);

Структура ответа

typescript
Array<{
  stats?: Array<{
    item_id?: number;          // ID баннера
    item_name?: string;        // Название
    category_name?: string;    // Категория
    advert_type?: number;      // Тип рекламы
    place?: string;            // Место размещения
    views?: number;
    clicks?: number;
    cr?: number;               // Conversion rate
    ctr?: number;
    atbs?: number;
    orders?: number;
    price?: number;
    cpc?: number;
    status?: number;
    expenses?: number;         // Расходы

    // Ежедневная разбивка по платформам
    daily_stats?: Array<{
      date?: string;
      app_type_stats?: Array<{
        app_type?: number;     // 1=сайт, 32=Android, 64=iOS
        stats?: {
          views?: number;
          clicks?: number;
          atbs?: number;
          ctr?: number;
        };
      }>;
    }>;
  }>;
}>

createAdvFullstat (удалён в v4.0.0)

Удалено в v4.0.0

Метод createAdvFullstat() (v2, POST) удалён в v4.0.0. Используйте getAdvFullstats() (v3, GET).

typescript
// ✅ ИСПОЛЬЗУЙТЕ:
const stats = await sdk.promotion.getAdvFullstats({
  ids: '24483511',
  beginDate: '2025-12-01',
  endDate: '2025-12-07',
});

getAdvBalance

Баланс рекламного кабинета.

typescript
const balance = await sdk.promotion.getAdvBalance();

console.log(`Баланс: ${balance.balance}₽`);     // Средства продавца
console.log(`Взаимозачет: ${balance.net}₽`);     // Из будущих продаж
console.log(`Бонусы: ${balance.bonus}₽`);        // Бонусы от WB

// Детали бонусов
if (balance.cashbacks) {
  for (const cb of balance.cashbacks) {
    console.log(`  Бонус: ${cb.sum}₽ (${cb.percent}%), до ${cb.expiration_date}`);
  }
}

getAdvBudget

Бюджет конкретной кампании.

typescript
const budget = await sdk.promotion.getAdvBudget({ id: 24483511 });

console.log(`Баланс (наличные): ${budget.cash}₽`);
console.log(`Баланс (взаимозачет): ${budget.netting}₽`);
console.log(`Итого: ${budget.total}₽`);

getAdvUpd

История расходов (акты УПД) за период.

typescript
const expenses = await sdk.promotion.getAdvUpd({
  from: '2025-12-01',
  to: '2025-12-31',
});

let totalExpenses = 0;
for (const record of expenses) {
  totalExpenses += record.updSum ?? 0;
  console.log(`${record.updTime}: кампания "${record.campName}" (${record.advertId}) — ${record.updSum}₽`);
}
console.log(`\nИтого расходов: ${totalExpenses}₽`);

Структура ответа

typescript
Array<{
  updNum?: number;        // Номер УПД
  updTime?: string;       // Дата/время
  updSum?: number;        // Сумма, ₽
  advertId?: number;      // ID кампании
  campName?: string;      // Название кампании
  advertType?: number;    // Тип кампании
  paymentType?: string;   // Тип оплаты
  advertStatus?: number;  // Статус кампании
}>

getAdvPayments

История пополнений рекламного кабинета.

typescript
const payments = await sdk.promotion.getAdvPayments({
  from: '2025-01-01',
  to: '2025-12-31',
});

for (const p of payments) {
  console.log(`${p.date}: пополнение ${p.sum}₽, тип=${p.type}, статус=${p.statusId}`);
}

getCampaignCount

Список всех кампаний с ID, типами и статусами. Используйте для получения ID кампаний перед запросом статистики. (Переименован из getPromotionCount() в v4.0.0 — тот же endpoint.)

typescript
const campaigns = await sdk.promotion.getCampaignCount();

console.log(`Всего кампаний: ${campaigns.all}`);

// Собираем все ID кампаний
const allIds: number[] = [];

for (const group of campaigns.adverts ?? []) {
  console.log(`Тип ${group.type}, статус ${group.status}: ${group.count} шт.`);

  for (const ad of group.advert_list ?? []) {
    allIds.push(ad.advertId!);
  }
}

console.log(`\nСобрано ID: ${allIds.length}`);
console.log(`ID кампаний: ${allIds.join(', ')}`);

getAuctionAdverts (удалён в v4.0.0)

Удалено в v4.0.0

Метод getAuctionAdverts() удалён в v4.0.0. Используйте getAdvertsV2() для получения деталей кампаний любого типа.

typescript
// ✅ ИСПОЛЬЗУЙТЕ getAdvertsV2:
const active = await sdk.promotion.getAdvertsV2({ statuses: '9' });
const specific = await sdk.promotion.getAdvertsV2({ ids: '24483511,23332267' });
const cpmCampaigns = await sdk.promotion.getAdvertsV2({ payment_type: 'cpm' });

Полные рабочие примеры

Пример 1: Ежедневный отчет по рекламе (бэк-энд сервис)

typescript
import { WildberriesSDK, RateLimitError } from 'daytona-wildberries-typescript-sdk';

const sdk = new WildberriesSDK({ apiKey: process.env.WB_API_KEY! });

async function generateDailyReport(date: string) {
  const report: Record<string, unknown>[] = [];

  // 1. Получаем список всех кампаний
  const campaigns = await sdk.promotion.getCampaignCount();
  const activeIds = (campaigns.adverts ?? [])
    .filter(g => g.status === 9 || g.status === 11) // Активные и на паузе
    .flatMap(g => g.advert_list?.map(a => a.advertId!) ?? []);

  if (activeIds.length === 0) {
    console.log('Нет активных кампаний');
    return [];
  }

  // 2. Получаем статистику (батчами по 100)
  for (let i = 0; i < activeIds.length; i += 100) {
    const batch = activeIds.slice(i, i + 100);

    try {
      const stats = await sdk.promotion.getAdvFullstats({
        ids: batch.join(','),
        beginDate: date,
        endDate: date,
      });

      for (const campaign of stats) {
        const dayData = campaign.days?.[0]; // Один день

        report.push({
          campaign_id: campaign.advertId,
          date,
          views: campaign.views,
          clicks: campaign.clicks,
          ctr: campaign.ctr,
          cpc: campaign.cpc,
          orders: campaign.orders,
          spent: campaign.sum,
          revenue: campaign.sum_price,
          roi: campaign.sum > 0
            ? ((campaign.sum_price - campaign.sum) / campaign.sum * 100).toFixed(2)
            : 0,

          // По платформам
          platforms: dayData?.apps?.map(app => ({
            type: app.appType === 1 ? 'web' : app.appType === 32 ? 'android' : 'ios',
            views: app.views,
            clicks: app.clicks,
            orders: app.orders,
          })) ?? [],

          // Топ товаров
          top_skus: dayData?.apps?.flatMap(app =>
            app.nms.map(nm => ({
              nmId: nm.nmId,
              name: nm.name,
              clicks: nm.clicks,
              orders: nm.orders,
              spent: nm.sum,
            }))
          )?.sort((a, b) => b.spent - a.spent)
            .slice(0, 5) ?? [],
        });
      }
    } catch (error) {
      if (error instanceof RateLimitError) {
        await new Promise(r => setTimeout(r, error.retryAfter ?? 21000));
        i -= 100; // Повторяем этот батч
        continue;
      }
      throw error;
    }

    // Пауза 21с между батчами
    if (i + 100 < activeIds.length) {
      await new Promise(r => setTimeout(r, 21000));
    }
  }

  // 3. Баланс
  const balance = await sdk.promotion.getAdvBalance();

  return { report, balance: { cash: balance.balance, net: balance.net, bonus: balance.bonus } };
}

// Использование
const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
const dateStr = yesterday.toISOString().split('T')[0];

const result = await generateDailyReport(dateStr);
console.log(JSON.stringify(result, null, 2));

Пример 2: Мониторинг ключевых слов (фронт-энд)

typescript
import { WildberriesSDK } from 'daytona-wildberries-typescript-sdk';

const sdk = new WildberriesSDK({ apiKey: process.env.WB_API_KEY! });

interface SkuReport {
  nmId: number;
  name: string;
  totalViews: number;
  totalClicks: number;
  totalSpent: number;
  totalOrders: number;
  avgCtr: number;
}

async function getSkuAnalytics(campaignId: number, days: number = 7) {
  const to = new Date();
  const from = new Date();
  from.setDate(to.getDate() - days);

  const format = (d: Date) => d.toISOString().split('T')[0];

  // getAdvFullstats заменил getStatsKeywords (удалён в v4.0.0)
  const stats = await sdk.promotion.getAdvFullstats({
    ids: String(campaignId),
    beginDate: format(from),
    endDate: format(to),
  });

  // Агрегация по SKU (nmId) — days[] -> apps[] -> nms[]
  const skuMap = new Map<number, SkuReport>();

  for (const campaign of stats) {
    for (const day of campaign.days ?? []) {
      for (const app of day.apps ?? []) {
        for (const nm of app.nms ?? []) {
          const existing = skuMap.get(nm.nmId) ?? {
            nmId: nm.nmId,
            name: nm.name,
            totalViews: 0,
            totalClicks: 0,
            totalSpent: 0,
            totalOrders: 0,
            avgCtr: 0,
          };

          existing.totalViews += nm.views ?? 0;
          existing.totalClicks += nm.clicks ?? 0;
          existing.totalSpent += nm.sum ?? 0;
          existing.totalOrders += nm.orders ?? 0;

          skuMap.set(nm.nmId, existing);
        }
      }
    }
  }

  // Расчет среднего CTR
  for (const sku of skuMap.values()) {
    sku.avgCtr = sku.totalViews > 0
      ? (sku.totalClicks / sku.totalViews) * 100
      : 0;
  }

  return [...skuMap.values()].sort((a, b) => b.totalSpent - a.totalSpent);
}

// Использование
const skus = await getSkuAnalytics(24483511, 7);
for (const sku of skus.slice(0, 20)) {
  console.log(`SKU ${sku.nmId} "${sku.name}": ${sku.totalViews} показов, ` +
    `${sku.totalClicks} кликов, CTR=${sku.avgCtr.toFixed(2)}%, ${sku.totalSpent}₽`);
}

Пример 3: Финансовый дашборд

typescript
async function getFinancialDashboard(fromDate: string, toDate: string) {
  const [balance, expenses, payments] = await Promise.all([
    sdk.promotion.getAdvBalance(),
    sdk.promotion.getAdvUpd({ from: fromDate, to: toDate }),
    sdk.promotion.getAdvPayments({ from: fromDate, to: toDate }),
  ]);

  // Итоги
  const totalExpenses = expenses.reduce((sum, e) => sum + (e.updSum ?? 0), 0);
  const totalDeposits = payments.reduce((sum, p) => sum + (p.sum ?? 0), 0);

  // Расходы по кампаниям
  const byCampaign = new Map<number, { name: string; total: number }>();
  for (const e of expenses) {
    const existing = byCampaign.get(e.advertId!) ?? { name: e.campName ?? '', total: 0 };
    existing.total += e.updSum ?? 0;
    byCampaign.set(e.advertId!, existing);
  }

  return {
    balance: {
      cash: balance.balance,
      netting: balance.net,
      bonus: balance.bonus,
      total: (balance.balance ?? 0) + (balance.net ?? 0) + (balance.bonus ?? 0),
    },
    period: { from: fromDate, to: toDate },
    totalExpenses,
    totalDeposits,
    netCashflow: totalDeposits - totalExpenses,
    topCampaignsBySpend: [...byCampaign.entries()]
      .sort(([, a], [, b]) => b.total - a.total)
      .slice(0, 10)
      .map(([id, data]) => ({ id, name: data.name, spent: data.total })),
  };
}

Типичные ошибки и решения

Ошибка: HTTP 400 на getAdvFullstats

Причина #1: Неправильные имена параметров

typescript
// ❌ НЕПРАВИЛЬНО — частая ошибка
await sdk.promotion.getAdvFullstats({
  ids: '123',
  nDate: '2025-12-01',     // ❌ Нет такого параметра!
  endDate: '2025-12-31',
});

// ❌ НЕПРАВИЛЬНО — другие варианты ошибок
await sdk.promotion.getAdvFullstats({
  ids: '123',
  from: '2025-12-01',      // ❌ Это не getStatsKeywords!
  to: '2025-12-31',
});

// ✅ ПРАВИЛЬНО
await sdk.promotion.getAdvFullstats({
  ids: '123',
  beginDate: '2025-12-01', // ✅ beginDate
  endDate: '2025-12-31',   // ✅ endDate
});

Причина #2: ids как число, не строка

typescript
// ❌ НЕПРАВИЛЬНО
await sdk.promotion.getAdvFullstats({
  ids: 24483511,            // ❌ Число, а нужна строка
  beginDate: '2025-12-01',
  endDate: '2025-12-31',
});

// ✅ ПРАВИЛЬНО
await sdk.promotion.getAdvFullstats({
  ids: '24483511',          // ✅ Строка
  beginDate: '2025-12-01',
  endDate: '2025-12-31',
});

// ✅ Несколько кампаний
await sdk.promotion.getAdvFullstats({
  ids: '24483511,23332267', // ✅ Через запятую
  beginDate: '2025-12-01',
  endDate: '2025-12-31',
});

Причина #3: Период больше 31 дня

typescript
// ❌ Период 60 дней — вернет 400
await sdk.promotion.getAdvFullstats({
  ids: '24483511',
  beginDate: '2025-10-01',  // ❌ >31 дня
  endDate: '2025-12-01',
});

// ✅ Разбейте на несколько запросов
for (const [begin, end] of [
  ['2025-10-01', '2025-10-31'],
  ['2025-11-01', '2025-12-01'],
]) {
  const stats = await sdk.promotion.getAdvFullstats({
    ids: '24483511',
    beginDate: begin,
    endDate: end,
  });
  // ... обработка
  await new Promise(r => setTimeout(r, 21000)); // Rate limit
}

Ошибка: HTTP 429 (Rate Limit)

Проблема: Слишком частые запросы.

typescript
import { RateLimitError } from 'daytona-wildberries-typescript-sdk';

// ✅ Правильная обработка
try {
  const stats = await sdk.promotion.getAdvFullstats({
    ids: '24483511',
    beginDate: '2025-12-01',
    endDate: '2025-12-07',
  });
} catch (error) {
  if (error instanceof RateLimitError) {
    // SDK автоматически ретраит, но если лимит исчерпан:
    console.warn(`Rate limit! Ждать: ${error.retryAfter}ms`);
    await new Promise(r => setTimeout(r, error.retryAfter));
    // Повторить запрос
  }
}

Рекомендуемые интервалы между запросами:

МетодМинимальный интервал
getAdvFullstats()21 секунда
getAdvBalance()1 секунда
getAdvUpd()1 секунда
getAdvPayments()1 секунда
createAdvStat()100 мс

Ошибка: Пустой массив в ответе

Причины:

  1. Кампания не в статусе 7, 9 или 11
  2. За указанный период не было активности
  3. ID кампании не существует или принадлежит другому продавцу
typescript
const stats = await sdk.promotion.getAdvFullstats({
  ids: '24483511',
  beginDate: '2025-12-01',
  endDate: '2025-12-07',
});

if (stats.length === 0) {
  // Проверяем: существует ли кампания?
  const campaigns = await sdk.promotion.getCampaignCount();
  const allIds = campaigns.adverts?.flatMap(g =>
    g.advert_list?.map(a => a.advertId) ?? []
  ) ?? [];

  if (!allIds.includes(24483511)) {
    console.error('Кампания 24483511 не найдена в аккаунте');
  } else {
    console.log('Кампания существует, но за период нет данных');
  }
}

Ошибка: getAdvFullstats — неправильные параметры

getStatsKeywords() удалён в v4.0.0. Ниже — типичные ошибки параметров getAdvFullstats().

typescript
// ❌ НЕПРАВИЛЬНО — путаница с типами параметров
await sdk.promotion.getAdvFullstats({
  ids: 24483511,            // ❌ ids — строка, не число
  from: '2025-12-01',       // ❌ Параметр называется beginDate
  to: '2025-12-07',         // ❌ Параметр называется endDate
});

// ✅ ПРАВИЛЬНО
await sdk.promotion.getAdvFullstats({
  ids: '24483511',          // ✅ строка
  beginDate: '2025-12-01',  // ✅ beginDate
  endDate: '2025-12-07',    // ✅ endDate (макс 31 день)
});

Сводная таблица параметров

МетодПараметр даты началаПараметр даты концаПараметр IDМакс. период
getAdvFullstats()beginDateendDateids (строка)31 день
getAdvUpd()fromtoбез лимита
getAdvPayments()fromtoбез лимита

ЗАПОМНИТЕ

У каждого метода свои имена параметров! Это самая частая причина ошибок HTTP 400. Не путайте beginDate с from, ids с id, advert_id с id.


Статусы кампаний

КодСтатусСтатистика доступна
4Готова к запускуНет
7ЗавершенаДа
8ОтмененаНет
9АктивнаДа
11На паузеДа
-1УдаляетсяНет

Типы кампаний

ТипОписаниеСтатус
4В каталогеDeprecated
5В карточке товараDeprecated
6В поискеDeprecated
7В рекомендацияхDeprecated
8Единая ставкаDeprecated (02.02.2026)
9Единая или ручная ставкаТекущий

API домены

Разные методы используют разные домены API:

ДоменМетоды
advert-api.wildberries.rugetAdvFullstats, getAdvBalance, getAdvBudget, getAdvUpd, getAdvPayments, getCampaignCount, getAdvertsV2
advert-media-api.wildberries.rucreateAdvStat, getAdvCount, getAdvAdverts, getAdvAdvert

INFO

SDK автоматически направляет запросы на нужный домен. Знать домены нужно только для отладки сетевых проблем.


Связанные ресурсы

Made with ❤️ for the Wildberries developer community